My stupidity / strange inconsistency overriding class methods

Discussion in 'Python' started by andrew cooke, Apr 20, 2011.

  1. andrew cooke

    andrew cooke Guest

    Hi,

    I've been staring at this problem, in various forms, all day. Am I missing something obvious, or is there some strange hardwiring of isinstance? This is with Python 3.2.

    class A(metaclass=ABCMeta):
    @classmethod
    def __instancecheck__(cls, instance): return False
    # no override
    assert isinstance(A(), A)
    assert A.__class__.__instancecheck__(A, A())

    class B(type):
    def foo(self): return 42
    class C(metaclass=B):
    @classmethod
    def foo(cls): return 7
    # override
    assert C().__class__.foo() == 7

    It seems to me that the above two cases are inconsistent. ABCMeta declares __instancecheck__ just like B declares foo. Yet C can override foo, but A is unable to override the instance check.

    Please help!

    Thanks,
    Andrew
     
    andrew cooke, Apr 20, 2011
    #1
    1. Advertising

  2. andrew cooke

    Chris Rebert Guest

    On Tue, Apr 19, 2011 at 4:52 PM, andrew cooke <> wrote:
    > Hi,
    >
    > I've been staring at this problem, in various forms, all day.  Am I missing something obvious, or is there some strange hardwiring of isinstance?  This is with Python 3.2.
    >
    >        class A(metaclass=ABCMeta):
    >            @classmethod
    >            def __instancecheck__(cls, instance): return False
    >        # no override
    >        assert isinstance(A(), A)
    >        assert A.__class__.__instancecheck__(A, A())


    [You've already figured out the issue, but since I spent a while
    composing this, and for the benefit for the archives, I'll post
    anyway.]

    Makes sense after a little thought.
    http://docs.python.org/reference/datamodel.html#customizing-instance-and-subclass-checks
    "Note that [ __instancecheck__() is ] looked up on the type
    (metaclass) of a class. [It] cannot be defined as [a classmethod] in
    the actual class. This is consistent with the lookup of special
    methods that are called on instances, only in this case the instance
    is itself a class."

    Recall from http://docs.python.org/reference/datamodel.html#special-method-lookup-for-new-style-classes
    that lookup of __special__ methods never consults instance
    dictionaries, instead skipping directly to the type's namespace; as
    the quote says, in this case, the instance (of ABCMeta) is itself a
    class/type (namely A). Your two assert statements are therefore almost
    precisely equivalent in this case; and since the latter involves
    A.__class__ (a.k.a. ABCMeta) rather than A itself, it's understandable
    that that A's namespace is not consulted.

    >        class B(type):
    >            def foo(self): return 42
    >        class C(metaclass=B):
    >            @classmethod
    >            def foo(cls): return 7
    >        # override
    >        assert C().__class__.foo() == 7


    More simply: assert C.foo() == 7

    "foo" is not a __special__ method name; therefore we look in the
    instance dictionary of the receiver (i.e. C) before consulting the
    receiver's type (i.e. B). Our check in the instance dictionary is
    successful (we find C.foo), and therefore we don't even bother looking
    at C's type (i.e. B, where we would find B.foo).

    > It seems to me that the above two cases are inconsistent.  ABCMeta declares __instancecheck__ just like B declares foo.  Yet C can override foo, but A is unable to override the instance check.


    The difference is in the __special__-ness of the method names in question.

    Cheers,
    Chris
    --
    http://blog.rebertia.com
     
    Chris Rebert, Apr 20, 2011
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roman Werpachowski
    Replies:
    6
    Views:
    287
    Markus Becker
    Jan 2, 2006
  2. Replies:
    3
    Views:
    401
    Lasse Reichstein Nielsen
    Sep 6, 2008
  3. trans.  (T. Onoma)
    Replies:
    21
    Views:
    229
    Kristof Neirynck
    Jan 18, 2005
  4. Kenneth McDonald
    Replies:
    5
    Views:
    326
    Kenneth McDonald
    Sep 26, 2008
  5. Zachary Buckholz
    Replies:
    11
    Views:
    156
    G Klinedinst
    Jan 17, 2004
Loading...

Share This Page