I have a debug context manager where I would like to access the locals() at the time the context manager was initiated, without giving the locals as an argument. Is this possible?
I would like to do this in the general case, so that my Debug context manager can be used from any file importing Debug
, not just in the tinkertoy example below.
Here is my minimal example:
import inspect
class Debug:
def __init__(self):
frames = inspect.stack()
for frame in frames:
line = frame.code_context[0]
if "Debug" in line:
break
# I want to get the locals() at the time debug was called here!
# give me i_will_be_in_the_locals
raise Exception()
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
pass
if __name__ == "__main__":
i_will_be_in_the_locals = 42
with Debug():
"hi"
The frame object is inside the "frame" variable you defined. To get the local variables for a frame object, you can call its f_locals attribute like this:
import inspect
class Debug:
def __init__(self):
frames = inspect.stack()
for frame in frames:
line = frame.code_context[0]
if "Debug" in line:
break
# I want to get the locals() at the time debug was called here!
# give me i_will_be_in_the_locals
from pprint import pprint
pprint(frame.frame.f_locals)
def __enter__(self):
pass
def __exit__(self, exc_type, exc_val, exc_tb):
pass
if __name__ == "__main__":
i_will_be_in_the_locals = 42
with Debug():
"hi"
The returned value is:
{'Debug': <class '__main__.Debug'>,
'__builtins__': <module 'builtins' (built-in)>,
'__cached__': None,
'__doc__': None,
'__file__': '/home/user1/main-projects/overflow/file.py',
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f7bbb44f7f0>,
'__name__': '__main__',
'__package__': None,
'__spec__': None,
'i_will_be_in_the_locals': 42,
'inspect': <module 'inspect' from '/usr/lib/python3.5/inspect.py'>}