Hello Python Dev,

I am trying to understand the correct semantic of the isinstance built-in 
function and while doing so, I came across few cases which raise some questions.

1) First example - a class instance pretends to have different class via 
__class__.

>>> class D(object):
...     def getclass(self):
...         print "D.getclass"
...         return C
...     __class__ = property(getclass)
...
>>> isinstance(D(), D)
True
>>> isinstance(D(), C)
D.getclass
True

isinstance in this case returns True to both C and D test. I would expect to 
see the __class__ property being called in both cases and get:

>>> isinstance(D(), D)
D.getclass
False

but that's not the case for some reason. It seems that the __class__ is only 
accessed in some cases, but not always, leading to what I think is a semantic 
inconsistency.

2) Second, slightly more complicated example, uses an instance with __bases__ 
on it as the 2nd parameter to isinstance:

class E(object):
    def getbases(self):
        print "E.getbases"
        return ()
    __bases__ = property(getbases)

class C(object):
    def getbases(self):
        print "C.getbases"
        return (E,)                     # C() claims: "E is my base class"
    __bases__ = property(getbases)

class D(object):
    def getclass(self):
        print "D.getclass"
        return C()                      # D() claims: "C() is my __class__"
    __class__ = property(getclass)


class F(object): pass


print "Test 1"
print isinstance(D(), E())              # testing against E() instance
print "Test 2"
print isinstance(D(), E)                # testing against E class

The output here is:

Test 1
E.getbases
D.getclass
C.getbases
False

Test 2
D.getclass
False

In the 2nd test, D.getclass is called to get the __class__ of D(), which 
returns C() instance. At this point I would expect that C.getbases gets called 
as __bases__ are retrieved, which would return tuple consisting of E and 
ultimately produce True result. However, in this case the __bases__ are never 
accessed on C() (the class of D()). The test_isinstance.py actually tests for 
similar case.

My question is based on what assumptions does the standard Python 
implementation bypass the access to __bases__, __class__ etc. when evaluating 
isinstance? Did I happen to come across a bug or an inconsistency in Python 
implementation, or am I hitting an intentional behavior?

Thanks very much for reading and some insights!
Martin
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to