frame.f_locals['__class__'] -- When does it (not) exist and why?
kevinarpe at gmail.com
kevinarpe at gmail.com
Sun Nov 16 01:28:13 EST 2014
Apologies for previous code example. Yes, the 'def class' should read: 'class'.
Writing a sample to better demonstrate the issue made me realize that super() is doing something special. It is injecting the magic '__class__' local.
I should rephrase my question: How do I get the declaring class from from a traceback object? Currently, I cannot see how to do it. Magic local '__class__' is not always available. And locals 'cls' and 'self' may come from subclasses.
Code sample:
import inspect
import sys
class X:
def __init__(self):
# Magic local '__class__' is missing
raise ValueError()
class Y(X):
def __init__(self):
super().__init__()
class X2:
def __init__(self):
# Calling super() here will 'inject' magic local '__class__'
super().__init__()
raise ValueError()
class Y2(X2):
def __init__(self):
super().__init__()
def main():
_main(lambda: Y())
_main(lambda: Y2())
def _main(func):
try:
func()
except:
(exc_type, exc_value, traceback) = sys.exc_info()
tb = traceback
while tb:
frame = tb.tb_frame
# See: code.co_freevars. Sometimes magic '__class__' appears.
code = frame.f_code
lineno = frame.f_lineno
func_name = code.co_name
file_path = code.co_filename
module = inspect.getmodule(frame, file_path)
module_name = module.__name__
print("File: {}, Line: {}, Func: {}, Module: {}".format(file_path, lineno, func_name, module_name))
for name in ('__class__', 'self', 'cls'):
if name in frame.f_locals:
print(" {}: '{}'".format(name, frame.f_locals[name]))
tb = tb.tb_next
print()
if __name__ == '__main__':
main()
More information about the Python-list
mailing list