Steven D'Aprano <steve+pyt...@pearwood.info> added the comment:
I agree that the rules regarding type and `__class__` and isinstance are not clear or well documented. We have: https://docs.python.org/3/library/stdtypes.html#instance.__class__ https://docs.python.org/3/library/functions.html#isinstance but neither discuss the interaction between a class' "real" type and it's "fake" type. To be honest, I'm not even sure I fully understand the interaction myself, or how they combine with virtual subclasses. A lot of my information comes from this Stackoverflow post: https://stackoverflow.com/questions/1060499/difference-between-typeobj-and-obj-class and in particular this comment: "Some code does this deliberately to lie about the type of objects, such as weakref.proxy. Some people think obj.__class__ should be preferred, because it believes the lie, while some people think type(obj) should be preferred because it ignores the lie. isinstance will return true if an object's real class or its lie class is an instance of the second argument." So I think that the behaviour here is correct, but it is not documented well and we should fix that. What I think happens: * type(obj) always and only returns the actual internal (C-level) type of the object, guaranteed to be a type object. * isinstance(obj, classinfo) returns True if any of the following hold: - the type() of object is a subclass of any of the classes in the classinfo object (a class, a Union of classes, or a tuple of classes); - obj.__class__ is a subclass of any of the classes in classinfo; - or obj is registered as a virtual subclass of any of the classes in classinfo, by calling type(ob).__subclasshook__; * obj.__class__ is determined using the normal attribute lookup mechanism, which means it does not have to be a static attribute but can be dynamically generated using properties, __getattr__, __getattribute__ or any other similar mechanism. And for the avoidance of doubt, a class is always considered a subclass of itself. I'm really not sure about the interaction with virtual subclasses, I probably have that bit wrong. And it is not clear to me what happens if __class__ is a non-type object. It seems to be permitted. Improving the documentation would be excellent. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue32683> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com