Comment

Marius Gedminas

There are many `__special__` names that cause problems of this kind when you accidentally provide them by overriding `__getattr__`. I've found it best to always do

    def __getattr__(self, name):
        if name.startswith('__'):
            raise AttributeError(name)
        ...

Actually, your custom getattr raises KeyError for missing attributes, which is a strange thing to get from an expression that looks like `obj.attrname`. I would suggest catching KeyError and raising AttributeError. This would actually have avoided your original `__deepcopy__` error too.

(Note: I've replaced initial spaces with non-breaking spaces so this blog won't mangle the indentation. If you actually copy & paste this code, expect interesting SyntaxErrors ;)

Replies

Peter Bengtsson

Excellent! Thanks!