__qualname__ in python 3.3

Peter Otten __peter__ at web.de
Sat Sep 6 20:11:01 CEST 2014


ISE Development wrote:

> Peter Otten wrote:
> 
>> ISE Development wrote:
>> 
>>> Hi,
>>> 
>>> When a class is defined within a function, the class generation
>>> function's '__qualname__' attrbute is not qualified a name.
>>> 
>>> For instance:
>>> 
>>>     def test():
>>>         class T:
>>>             def method(self):
>>>                 pass
>>>         t = T()
>>>         t.method()
>>> 
>>> When tracing a call to 'test()' using 'sys.settrace()', extracting the
>>> 'code' object from the frames of 'call' events and matching it to a
>>> 'function' object (using 'gc.get_referrers()') results in the following:
>>> 
>>> '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).
>>> 
>>> I would expect the second call's '__qualname__' to be 'test.<locals>.T'.
>>> Can this be considered a bug? If so, I'll open one.
>> 
>> I don't understand what you are doing, so I tried to reproduce the
>> unqualified class name in 3.4 with the simpler approach of returning T:
>> 
>> Python 3.4.0 (default, Apr 11 2014, 13:05:11)
>> [GCC 4.8.2] on linux
>> Type "help", "copyright", "credits" or "license" for more information.
>>>>> def test():
>> ...     class T:
>> ...         def method(self): pass
>> ...     return T
>> ...
>>>>> T = test()
>>>>> T.__qualname__
>> 'test.<locals>.T'
>>>>> T.method.__qualname__
>> 'test.<locals>.T.method'
>> 
>> If you do it that way with 3.3 (I don't have it handy) do you still see
>> T instead of test.<locals>.T?
> 
> Python 3.3 behaves in the same way in that case.
> 
> This following shows the behaviour I am referring to:
> 
>     import gc
>     import sys
>     import inspect
> 
>     def global_trace(frame,event,arg):
>         if event == 'call':
>             code = frame.f_code
>             funcs = [obj for obj in gc.get_referrers(code)
>                      if inspect.isfunction(obj)]
>             if len(funcs) == 1:
>                 f = funcs[0]
>                 print(f.__qualname__)
> 
>     def test():
>         class C:
>             def method(self):
>                 self
>         c = C()
>         c.method()
> 
>     sys.settrace(global_trace)
>     try:
>         test()
>     finally:
>         sys.settrace(None)
> 
> which produces:
> 
>     test
>     C
>     test.<locals>.C.method

OK, I get the same output in Python 3.4. That C seems to be an internal 
function that helps build the class test.<locals>.C, and I have no 
expectations as to its name. If anything I'd use something completely 
different, _init_namespace_C, say.

I'm sorry I am not familiar enough with Python's internals to answer your 
question -- but if in doubt, file a report.





More information about the Python-list mailing list