[Python-Dev] copy confusion
Phillip J. Eby
pje at telecommunity.com
Wed Jan 12 00:40:18 CET 2005
At 02:58 PM 1/11/05 -0800, Guido van Rossum wrote:
>[Phillip]
> > Looks like a bug to me; it breaks the behavior of classic classes, since
> > type(classicInstance) returns InstanceType.
>
>I'm not so sure. I can't seem to break this for classic classes.
Sorry; I was extrapolating from what I thought was Fredrik's description of
this behavior as a bug, and examining of the history of the code that he
referenced. I saw that the current version of that code had evolved
directly from a version that was retrieving instance.__copy__; I therefore
assumed that the loss-of-feature Fredrik was reporting was that.
That is, I thought that the problem he was experiencing was that classic
classes no longer supported __copy__ because this code had changed. I
guess I should have looked at other lines of code besides the ones he
pointed out; sorry about that. :(
>The only thing this intends to break, and then only for new-style
>classes, is the ability to have __copy__ be an instance variable
>(whose value should be a callable without arguments) -- it must be a
>method on the class. This is the same thing that I've done for all
>built-in operations (__add__, __getitem__ etc.).
Presumably, this is the actual feature loss that Fredrik's describing; i.e.
lack of per-instance __copy__ on new-style classes. That would make more
sense.
> > However, it also looks like it might have been introduced to fix the
> > possibility that calling '__copy__' on a new-style class with a custom
> > metaclass would result in ending up with an unbound method. (Similar to
> > the "metaconfusion" issue being recently discussed for PEP 246.)
>
>Sorry, my head just exploded. :-(
The issue is that for special attributes (like __copy__, __conform__, etc.)
that do not have a corresponding type slot, using getattr() is not
sufficient to obtain slot-like behavior. This is because
'aType.__special__' may refer to a __special__ intended for *instances* of
'aType', instead of the __special__ for aType.
As Armin points out, the only way to fully emulate type slot behavior for
unslotted special attributes is to perform a search of the __dict__ of each
type in the MRO of the type of the object for which you wish to obtain the
special attribute.
So, in this specific case, __copy__ does not have a type slot, so it is
impossible using getattr (or simple attribute access) to guarantee that you
are retrieving the correct version of __copy__ in the presence of metaclasses.
This is what Alex and I dubbed "metaconfusion" in discussion of the same
issue for PEP 246's __adapt__ and __conform__ methods; until they have
tp_adapt and tp_conform slots, they can have this same problem.
Alex and I also just speculated that perhaps the stdlib should include a
function that can do this, so that stdlib modules that define unslotted
special attributes (such as __copy__) can ensure they work correctly in the
presence of metaclasses.
More information about the Python-Dev
mailing list