__qualname__ in python 3.3

ISE Development isenntp at gmail.com
Mon Sep 8 00:25:18 CEST 2014

Antoine Pitrou wrote:
> Hi,
> ISE Development <isenntp <at> gmail.com> writes:
>> 'code' object     'function' object
>> ----------------  ------------------------------------
>> co_name: test     __qualname__: test
>> co_name: T        __qualname__: T
>> co_name: method   __qualname__: test.<locals>.T.method
>> The second call corresponds to the class definition and not the call to
>> the constructor (which is in fact a call to 'object.__init__', a C
>> function hence not traced as a 'call' event - I checked this by
>> disassembling the code object).
> There's nothing wrong here. That's just the way things are implemented
> internally. This may change in the future without prior notice, so
> you shouldn't rely on it.
> If you want to dig more, you have to look at how the hidden function ("T")
> works:
>>>> def f():
> ...   class T: pass
> ...
>>>> f.__code__.co_consts
> (None, <code object T at 0x7f4d9d0f4a00, file "<stdin>", line 2>, 'T')
>>>> dis.dis(f.__code__.co_consts[1])
>   2           0 LOAD_NAME                0 (__name__)
>               3 STORE_NAME               1 (__module__)
>               6 LOAD_CONST               0 ('f.<locals>.T')
>               9 STORE_NAME               2 (__qualname__)
>              12 LOAD_CONST               1 (None)
>              15 RETURN_VALUE
> Regards
> Antoine.

Ok, I accept it's implementation specific. That's fair enough.

Yet wouldn't it make more sense to have the 'T' function '__qualname__' 
attribute refer to the defining context, i.e. in the present case, 
'test.<locals>.T' (much along the lines of the actual method qualified 
names, e.g. 'test.<locals>.T.__init__', and identical to the qualified name 
of the actual object if returned by the defining function - see Peter Otten 

The rationale is that a properly qualified name is easier to interpret than 
the current unqualified one. To properly identify the 'T' function if a 
'class T' is defined in more than enclosing function requires some 
additional complex (and hence error prone) logic as things stand: one has to 
examine the previous stack frame.

Effectively, I am not saying the current behaviour is wrong, simply that it 
is inconsistent and could be improved. In that context, is it worth an 
enhancement request?

-- isedev

More information about the Python-list mailing list