[Python-Dev] Semantic of isinstance
Martin Maly
Martin.Maly at microsoft.com
Tue Jun 27 02:16:45 CEST 2006
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
More information about the Python-Dev
mailing list