Guido van Rossum <guido@python.org> writes:
I am generating extension types derived from a type which is derived from int 'int' by calling the metaclass; in order to prevent instances of the most-derived type from getting an instance __dict__ I am putting an empty tuple in the class __dict__ as '__slots__'. The problem with this hack is that it disables pickling of these babies:
"a class that defines __slots__ without defining __getstate__ cannot be pickled"
Yes, I can define __getstate__, __setstate__, and __getinitargs__ (the only one that can actually do any work, since ints are immutable), but I was wondering if there's a more straightforward way to suppress the instance __dict__ in the derived classes.
Actually, even __getinitargs__ won't work, because __init__ is called after the object is created.
...and ints are immutable. Right.
In Python 2.3, you'd use __getnewargs__,
Cute. It's almost too bad that the distinction between __new__ and __init__ is there -- as we find we need to legitimize the use of __new__ with things like __getnewargs__ it be comes a little less clear which one should be used, and when. TIMTOWDI and all that. In the absence of clear guidelines I'm tempted to suggest that C++ got this part right. Occasionally we get people who think they want to call overridden virtual functions from constructors (I presume the analogous thing could be done safely from __init__ but not from __new__) but that's pretty rare. I'm interested in gaining insight into the Pythonic thinking behind __new__/__init__; I'm sure I don't have the complete picture.
but I expect you're still bound to supporting Python 2.2
Yup, I think it would be bad to force my users to move to an unreleased Python version at this point ;-)
(Python 2.3 also doesn't have the error message above when pickling).
Nice. Too bad about 2.2.
I think you could subclass the metaclass, override __new__, and delete the bogus __getstate__ from the type's __dict__. Then you'll get the default pickling behavior which ignores slots; that should work just fine in your case. :-)
Ooh, that's sneaky! But I can't quite see how it works. The error message I quoted at the top about __getstate__ happens when you try to pickle an instance of the class. If I delete __getstate__ during __new__, it won't be there for pickle to find when I try to do the pickling. What will keep it from inducing the same error? Thanks, -- Dave Abrahams Boost Consulting www.boost-consulting.com