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 -- https://mail.python.org/mailman/listinfo/python-list