Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Where does a compiled function get its globals()?

I’ve discovered that if I write something like:

code = f"lambda a, b: add(a, b)"
my_globals = globals().copy()
my_globals['add'] = operator.__add__
result = eval(code, my_globals, {})

Then result(3, 5) has the value 8, just like I want.

When I look at the disassembly of result, I see:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 0 LOAD_GLOBAL              0 (add)
 2 LOAD_FAST                0 (a)
 4 LOAD_FAST                1 (b)
 6 CALL_FUNCTION            2
 8 RETURN_VALUE

How does LOAD_GLOBAL convert add into operator.__add__? It clearly must save a reference to my_globals somewhere inside itself or its __code__ object.. But I’ve been unable to find it.

>Solution :

The reference you seek is the __globals__ attribute of the function object:

>>> result.__globals__
{'__name__': '__main__',
 # Many lines omitted
 'operator': <module 'operator' from '/usr/lib/python3.8/operator.py'>,
 'code': 'lambda a, b: add(a, b)',
 'add': <function _operator.add(a, b, /)>}

This attribute is documented in the Python Data model docs, under special attributes for user-defined functions:

__globals__:
A reference to the dictionary that holds the function’s global variables — the global namespace of the module in which the function was defined.
Read-only

As you found, the code object itself (__code__) does not contain a reference to the applicable globals dictionary. This is explicitly mentioned in the data model docs under "code objects":

Code objects represent byte-compiled executable Python code, or bytecode. The difference between a code object and a function object is that the function object contains an explicit reference to the function’s globals (the module in which it was defined), while a code object contains no context; also the default argument values are stored in the function object, not in the code object (because they represent values calculated at run-time). Unlike function objects, code objects are immutable and contain no references (directly or indirectly) to mutable objects.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading