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
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.