[Python-Dev] Python 3, new-style classes and __class__
Guido van Rossum
guido at python.org
Mon Nov 21 19:42:31 CET 2011
On Mon, Nov 21, 2011 at 9:22 AM, Michael Foord
<fuzzyman at voidspace.org.uk> wrote:
> On 20/11/2011 21:41, Guido van Rossum wrote:
>> On Sun, Nov 20, 2011 at 10:44 AM, Michael Foord
>> <fuzzyman at voidspace.org.uk> wrote:
>>> On 20 Nov 2011, at 16:35, Guido van Rossum wrote:
>>>> Um, what?! __class__ *already* has a special meaning. Those examples
>>>> violate that meaning. No wonder they get garbage results.
>>>> The correct way to override isinstance is explained here:
>>> Proxy classes have been using __class__ as a descriptor for this purpose
>>> for years before ABCs were introduced. This worked fine up until Python 3
>>> where the compiler magic broke it when super is used. That is now fixed
>> Hm, okay. Though it's disheartening that it took three releases of 3.x
>> to figure this out. And there was a PEP even!
>>> If I understand correctly, ABCs are great for allowing classes of objects
>>> to pass isinstance checks (etc) - what proxy, lazy and mock objects need is
>>> to be able to allow individual instances to pass different isinstance
>> Ah, oops. Yes, __instancecheck__ is for the class to override
>> isinstance(inst, cls); for the *instance* to override apparently
>> you'll need to mess with __class__.
>> I guess my request at this point would be to replace '@__class__' with
>> some other *legal* __identifier__ that doesn't clash with existing use
>> -- I don't like the arbitrary use of @ here.
> The problem with using a valid identifier name is that it leaves open the
> possibility of the same "broken" behaviour (removing from the class
> namespace) for whatever name we pick.
> That means we should document the name used - and it's then more likely that
> users will start to rely on this odd (but documented) internal
> implementation detail. This in turn puts a burden on other implementations
> to use the same mechanism, even if this is less than ideal for them.
> This is why a deliberately invalid identifier was picked.
Hm. There are many, many places in Python where a __special__
identifier is used in such a way that a user who stomps on it can
cause themselves pain. This is why the language reference is quite
serious about reserving *all* __special__ names and states that only
documented uses of them are allowed (and at least implying that
undocumented uses are not necessarily flagged as errors).
While I see that PEP 3119 made a mistake in giving __class__ two
different, incompatible special uses, I don't agree that this case is
so special that we should use an "invalid" identifier. I don't see
that the name use should actually be documented -- users should not
make *any* use of undocumented __names__. Let's please continue the
tradition of allowing experts to mess around creatively with
--Guido van Rossum (python.org/~guido)
More information about the Python-Dev