frame.f_locals['__class__'] -- When does it (not) exist and why?
kevinarpe at gmail.com
kevinarpe at gmail.com
Sun Nov 16 00:25:42 EST 2014
Hello,
I am CPython 3.4+ user on Linux.
I am writing a little library for myself to improve the traceback module -- print_exc() and friends. I want to include the module name, class name (if possible), and function name.
Some background: traceback.print_exc() iterates through traceback objects returned by sys.exc_info()[2]. traceback.tb_frame holds each stack frame. (I call this 'frame' below.)
My improved library nearly works, but I noticed a strange corner case around frame.f_locals['__class__'].
When super().__init__() is called, a 'magic' local appears in frame.f_locals called '__class__'. Helpfully, it has the correct class for the context, which will differ from type(self). (I discovered this magic local by poking around in the debugger. I am unable to find any official documentation on it.)
Here is the quirk: In the last class in a chain of super.__init__() calls, this magic local disappears. So I have no idea the correct class for the context. I am stuck with frame.f_locals['self'].
How can I recover the correct class for the context in the last __init__() method?
I noticed if I chance the last class to inherit from object, the magic local '__class__' appears again.
A little code to demonstrate:
# do not subclass object here
def class X:
def __init__(self):
# frame.f_locals['__class__'] does not exist
pass
def class Y(X):
def __init__(self):
# frame.f_locals['__class__'] == Y
super().__init__()
def class Z(Y):
def __init__(self):
super().__init__()
# subclass object here
def class X2(object):
def __init__(self):
# frame.f_locals['__class__'] == X2
pass
def class Y2(X2):
def __init__(self):
# frame.f_locals['__class__'] == Y2
super().__init__()
def class Z2(Y2):
def __init__(self):
super().__init__()
Thanks,
Arpe
More information about the Python-list
mailing list