[Python-3000] ABC PEP isinstance issue Was: PEP 31XX: A Type Hierarchy for Numbers (and other algebraic entities)
Jean-Paul Calderone
exarkun at divmod.com
Sat Apr 28 18:12:04 CEST 2007
On Sat, 28 Apr 2007 07:54:58 -0700, Guido van Rossum <guido at python.org> wrote:
>On 4/28/07, Calvin Spealman <ironfroggy at gmail.com> wrote:
>> On 4/26/07, Guido van Rossum <guido at python.org> wrote:
>> > On 4/25/07, Jim Jewett <jimjjewett at gmail.com> wrote:
>> > > The current ABC proposal is to use isinstance as the test; Jeffrey
>> > > Yaskin's numbers PEP highlighted the weakness there with a concrete
>> > > example.
>> > >
>> > > If you need to an abstraction less powerful than an existing ABC,
>> > > you're out of luck; you can't just assert that the existing class is
>> > > already sufficient, nor can you expect everyone else to use multiple
>> > > annotations.
>> >
>> > I now have a proposal to allow overloading isinstance() and
>> > issubclass(), by defining special (class) methods on the second
>> > argument. See http://python.org/sf/1708353. Does this need a PEP? The
>> > unit test shows that it can be used to support the use case described
>> > above:
>> >
>> >
>> > class ABC(type):
>> >
>> > def __instancecheck__(cls, inst):
>> > """Implement isinstance(inst, cls)."""
>> > return any(cls.__subclasscheck__(c)
>> > for c in {type(inst), inst.__class__})
>> >
>> > def __subclasscheck__(cls, sub):
>> > """Implement issubclass(sub, cls)."""
>> > candidates = cls.__dict__.get("__subclass__", set())
>> > return any(c in candidates for c in sub.mro())
>> >
>> >
>> > class Integer(metaclass=ABC):
>> >
>> > __subclass__ = {int}
>> >
>> >
>> > --
>> > --Guido van Rossum (home page: http://www.python.org/~guido/)
>> > _______________________________________________
>> > Python-3000 mailing list
>> > Python-3000 at python.org
>> > http://mail.python.org/mailman/listinfo/python-3000
>> > Unsubscribe: http://mail.python.org/mailman/options/python-3000/ironfroggy%40gmail.com
>>
>> I'm just going to jump into this and voice a concern that allowing
>> overriding of isinstance and issubclass seems like a Bad Idea. They
>> should be trustworthy and predictable, and allowing classes to change
>> how objects are considered instances of them seems like the wrong
>> thing to do. I'm not saying that I don't think it should be done, but
>> that it feels quite wrong. When I do, rarely, use isinstance or such,
>> and I need to check isinstance(f, Foo), I know exactly what I am
>> saying. But if Foo can change the meaning of that, can I trust it
>> anymore?
>>
>> Not everything should be dynamic. I am not sure which side of the
>> fence this falls on, but right now, in my mind, it teeters right on
>> the fence itself.
>
>Note though that only the second argument to either function can
>overload the rules. IOW if you write isinstance(x, C), there is no way
>that x could attempt to lie; but C could. Similar for issubclass(D, C)
>-- only D can change the outcome. Whether or not a particular class
>overload these functions ought to be part of its documentation. The
>builtins won't be overloading them; you will be able to trust e.g.
>isinstance(x, int). But it might be true that isinstance(42, Ring) if
>Ring overloads isinstance -- however you will have been duly warned of
>this possibility.
>
Aside from the way in which `x' can already lie:
>>> class X(object):
... __class__ = property(lambda self: int)
...
>>> isinstance(X(), int)
True
>>>
Is this behavior changed/going to be changed in Py3k?
Jean-Paul
More information about the Python-3000
mailing list