getting special from type, not instance (was Re: [Python-Dev] copy confusion)

Alex Martelli aleax at aleax.it
Thu Jan 13 11:47:59 CET 2005


On 2005 Jan 12, at 18:59, Guido van Rossum wrote:
    ...
> [Alex]
>> Armin's fix was to change:
    ...
> [And then proceeds to propose a new API to improve the situation]
>
> I wonder if the following solution wouldn't be more useful (since less
> code will have to be changed).
>
> The descriptor for __getattr__ and other special attributes could
> claim to be a "data descriptor" which means that it gets first pick
> *even if there's also a matching entry in the instance __dict__*.
    ...
> Normal methods are not data descriptors, so they can be overridden by
> something in __dict__; but it makes some sense that for methods
> implementing special operations like __getitem__ or __copy__, where
> the instance __dict__ is already skipped when the operation is invoked
> using its special syntax, it should also be skipped by explicit
> attribute access (whether getattr(x, "__getitem__") or x.__getitem__
> -- these are entirely equivalent).

A very nice idea for how to proceed in the future, and I think 
definitely the right solution for Python 2.5.  But maybe we need to 
think about a bugfix for 2.3/2.4, too.

> We would need to introduce a new decorator so that classes overriding
> these methods can also make those methods "data descriptors", and so
> that users can define their own methods with this special behavior
> (this would be needed for __copy__, probably).
>
> I don't think this will cause any backwards compatibility problems --
> since putting a __getitem__ in an instance __dict__ doesn't override
> the x[y] syntax, it's unlikely that anybody would be using this.

...in new-style classes, yes.  And classic types and old-style classes 
would keep behaving the old-way (with per-instance override) so the bug 
that bit the effbot would disappear... in Python 2.5.  But the bug is 
there in 2.3 and 2.4, and it seems to me we should still find a fix 
that is applicable there, even though the fix won't need to get into 
the 2.5 head, just the 2.3 and 2.4 bugfix branches.

> "Ordinary" methods will still be overridable.
>
> PS. The term "data descriptor" now feels odd, perhaps we can say "hard
> descriptors" instead. Hard descriptors have a __set__ method in
> addition to a __get__ method (though the __set__ method may always
> raise an exception, to implement a read-only attribute).

Good terminology point, and indeed explaining the ``data'' in "data 
descriptor" has always been a problem.  "Hard" or "Get-Set" descriptors 
or other terminology yet will make explanation easier; to pick the best 
terminology we should also think of the antonym, since ``non-data'' 
won't apply any more ("soft descriptors", "get-only descriptors", ...). 
  ``strong'' descriptors having a __set__, and ``weak'' ones not having 
it, is another possibility.


But back to the bugfix for copy.py (and I believe at least pprint.py 
too, though of course that's more marginal than copy.py!) in 2.3 and 
2.4: am I correct that this new descriptor idea is too big/invasive for 
ths bugfix, and thus we should still be considering localized changes 
(to copy.py and pprint.py) via a function copy._get_special (or 
whatever) in 2.3.5 and 2.4.1?

This small, local, minimally invasive change to copy.py would go well 
with the other one we need (as per my latest post with
Subject: 	Re: [Python-Dev] Re: copy confusion
	Date: 	2005 January 12 10:52:10 CET
) -- having the check for issubclass(cls, type) in copy.copy() just as 
we have it in copy.deepcopy() and for the same reason (which is a bit 
wider than the comment in copy.deepcopy about old versions of Boost 
might suggest).


Alex



More information about the Python-Dev mailing list