Search code examples
pythoncythonopcodes

Cython: use globals().update(...)?


I am writing a Python bytecode optimizer for a module that previously had a Cython tool-chain. While that may be deprecated by now, I encountered something strange while fiddling with it. Consider this simple piece of code:

from opcode import opmap

globals().update(opmap)

print(STORE_GLOBAL)

This should print 97, as STORE_GLOBAL is defined in opmap with its opcode(which is 97). Cython will tell me that STORE_GLOBAL is not defined, though:

Error compiling Cython file:
------------------------------------------------------------
...
from opcode import opmap

globals().update(opmap)

print(STORE_GLOBAL)
                 ^
------------------------------------------------------------

test.py:5:18: undeclared name not builtin: STORE_GLOBAL

The reason for that is pretty easy, I guess. I assume that it doesn't update the globals, so it does not know about STORE_GLOBAL now being a variable.

Is there a unhacky way to overcome this problem?

Cheers


Solution

  • The reason is that while cython modules have a global namespace that is exposed in python, this is namespace is only used to export python visible variables.

    However, most variables are not visible to python. These variables are declared at compile time and are statically typed. It is assumed that any variable referenced that is not declared in the module is an error, rather hoping the variable will be added later to the module globals.

    The only way to circumvent this is to refer to such variables via the modules globals. Not very elegant.

    print(globals()["STORE_GLOBAL"])
    

    The best alternatives are to import opmap and refer to the relevant values through that. Or to write out the values in opmap verbatim in your module.