Why deepcopy with class with __getattr__ makes the tracing go nuts?

Peter Otten __peter__ at web.de
Thu Feb 19 10:39:42 EST 2009


Fabio Zadrozny wrote:

> Anyone has any idea why the code attached does not work?
> 
> Basically, after doing the deepcopy of the class that has __getattr__
> overridden, the python tracing facilities don't seem to work anymore.
> 
> In the code-attached, if the deepcopy is removed, all works as
> expected (or if __deepcopy__ is overridden too).
> 
> Thanks,
> 
> Fabio
> 
> p.s. I've discovered this while trying to debug a real-world
> application and the debugger stopped working after making that
> deepcopy.

The problem seems to be a recursion error that implicitly switches off
tracing:

$ cat trace_test.py
import sys

def blowup():
    blowup()

def f():
    print "f called"

def trace(frame, event, arg):
    try:
        if frame.f_code.co_name == 'f':
            print "f seen", event
    finally:
        return trace

sys.settrace(trace)

if "-b" in sys.argv:
    try:
        blowup()
    except:
        pass

f()

$ python trace_test.py
f seen call
f seen line
f called
f seen return

$ python trace_test.py -b
f called

deepcopy() probably triggers such a recursion by accessing the type_name
attribute on a CppType instance with an empty __dict__. You can fix that
with

    def __getattr__(self, attr):
        if attr == 'type_name':
            return super(CppType, self).__getattr__(attr)
        # ...

I don't know why the exception is caught silently, nor how to make tracing
survive the stack overflow.

Peter



More information about the Python-list mailing list