__instancecheck__ metaclasses, how do they work: why do I get True when I tuple, why doesn't print run?
Pieter van Oostrum
pieter-l at vanoostrum.org
Tue Nov 5 10:30:53 EST 2019
Chris Angelico <rosuav at gmail.com> writes:
> On Tue, Nov 5, 2019 at 5:43 PM dieter <dieter at handshake.de> wrote:
>> I suppose that "isinstance" (at least under Python 2) does not
>> behave exactly as stated in PEP 3119. Instead, "isinstance"
>> first directly checks for the instance to be an instance of the
>> class *AND ONLY IF THIS FAILS* calls the class' "__instancecheck__".
>
> PEP 3119 is specifically about Python 3.0; I don't know how much, if
> any, was backported into Python 2.
Yes, it has been there since Python 2.6.
I looked in the implementation, and isinstance(inst, cls) first checks if the class of ins is cls, then the result is True.
There are a few other shortcut cases, and only at the end the __instancecheck__ method is called.
You can check this with the original example:
In [88]: class MA(type):
...: def __instancecheck__(cls, inst):
...: print "MA", cls, inst
...:
...: class AM(list): __metaclass__ = MA
...: class AM2(AM): pass
...:
...: am = AM2()
In [89]: isinstance(am, AM)
MA <class '__main__.AM'> []
Out[89]: False
It returns False because __instancecheck__ returns None
Same for Python3:
In [8]: class MA(type):
...: def __instancecheck__(cls, inst):
...: print ("MA", cls, inst)
...:
...: class AM(list, metaclass = MA): pass
...: class AM2(AM): pass
...:
...: am = AM2()
In [9]: isinstance(am, AM)
MA <class '__main__.AM'> []
Out[9]: False
--
Pieter van Oostrum <piet-l at vanoostrum.org>
WWW: http://pieter.vanoostrum.org/
PGP key: [8DAE142BE17999C4]
More information about the Python-list
mailing list