__qualname__ in python 3.3
ISE Development
isenntp at gmail.com
Sat Sep 6 13:09:56 EDT 2014
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
More information about the Python-list
mailing list