Robin Becker wrote:
I found that this error

Exception RuntimeError: 'maximum recursion depth exceeded in __subclasscheck__' in <type 'exceptions.AttributeError'> ignored

occurs when attempting to copy (copy.copy(inst)) an instance of a class that looks like this

class LazyParagraph(_LazyMixin,TTParagraph):
    SUPER=TTParagraph
    _CLEAN_SPACE=1
........

I have attempted to abstract the problem, but so far I haven't found the vital bits.

OK this turns out to be one of those useful exercises after all. After instrumenting the copy instance copy func my colleague and I found the problem occurs in this innocuous looking example

###################
import copy
class _LazyMixin:
        """don't do any initialization until later"""
        def __init__(self,*args):
                self._args = args
                self._initialized = 0

        def __getattr__(self,a):
                if not self._initialized:
                        self._Initialize()
                        return getattr(self,a)
                raise AttributeError("No attribute '%s'" % a)

        def _Initialize(self):
                if not self._initialized:
                        self._initialized = 1
                        del self._args

l=_LazyMixin()
print l._initialized
copy.debug=1
copy.copy(l)
###################


it turns out that in the absence of other info _copy_inst creates a dummy instance and changes its class to the incoming class. It then asks the new unpopulated instance if it has an attribute __setstate__, that triggers the _LazyMixin __getattr__ which fails because there's no _initialize member so __getattr__ gets recalled etc etc. Presumably in earlier pythons this bad behaviour is just hidden. The fix for us is to provide a __setstate__ which does what the no __setstate__ code does ie update __dict__.

However, since the _copy_inst code knows there can be no members on the new instance should it not be asking the __class__ for __setstate__?
--
Robin Becker

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to