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