[Python-Dev] copy confusion (original) (raw)
Alex Martelli aleax at aleax.it
Tue Jan 11 23:50:55 CET 2005
- Previous message: [Python-Dev] copy confusion
- Next message: [Python-Dev] PEP 246, redux
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 2005 Jan 11, at 23:20, Fredrik Lundh wrote:
back in Python 2.1 (and before), an object could define how copy.copy should work simply by definining a copy method. here's the relevant portion:
... try: copierfunction = copydispatch[type(x)] except KeyError: try: copier = x.copy except AttributeError: _raise error, _ "un(shallow)copyable object of type %s" % type(x) y = copier() ... I recently discovered that this feature has disappeared in 2.3 and 2.4. in- stead of looking for an instance method, the code now looks at the object's type:
Hmmm, yes, we were discussing this general issue as part of the huge recent thread about pep 246. In the new-style object model, special methods are supposed to be looked up on the type, not on the object; otherwise, having a class with special methods would be a problem -- are the methods meant to apply to the class object itself, or to its instances?
However, apparently, the code you quote is doing it wrong:
cls = type(x)
copier = copydispatch.get(cls) if copier: return copier(x) copier = getattr(cls, "copy", None) if copier: return copier(x)
...because getattr is apparently the wrong way to go about it (e.g., it
could get the 'copy' from type(cls), which would be mistaken).
Please see Armin Rigo's only recent post to Python-Dev for the way it
should apparently be done instead -- assuming Armin is right (he
generally is), there should be plenty of bugs in copy.py (ones that
emerge when you're using custom metaclasses &c -- are you doing that?).
Still, if you're using an instance of an old-style class, the lookup in _copy_dispatch should be on types.InstanceType -- is that what you're trying to copy, an instance of an old-style class?
(copy.deepcopy still seems to be able to use deepcopy hooks, though)
It starts with a peek into a dispatch dictionary for the type of the object, too, just like shallow copy does. What's the type of what you're trying to copy?
is this a bug, or a feature of the revised copy/pickle design? (the code in copyreg/copy/pickle might be among the more convoluted pieces of python coding that I ever seen... and what's that smiley doing in copy.py?)
and if it's a bug, does the fact that nobody reported this for 2.3 indicate that I'm the only one using this feature? is there a better way to control copying that I should use instead?
When I can, I use getstate and setstate, simply because they seem clear and flexible to be (usable for copying, deep copying, pickling). But that doesn't mean copy or deepcopy should be left broken, of course.
Although there are features of design intent here, it does appear to me there may be bugs too (if the getattr on the type is wrong); in this case it's worrisome, not just that nobody else reported problems, but also that the unit tests didn't catch them...:-(
Alex
- Previous message: [Python-Dev] copy confusion
- Next message: [Python-Dev] PEP 246, redux
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]