Chris, Yes, the following works: """ (Note that any object `x` is always considered to be an instance of `type(x)`, and this cannot be overridden.) """
NOTE: I fixed your sentence of `x.__class__` to `type(x)` since it is not always true that `x.__class__ == type(x)`. For example the actual code reference above: https://github.com/python/cpython/blob/master/Objects/abstract.c#L2397-L2405 Says "if (Py_TYPE(inst) == (PyTypeObject *)cls)" in the actual C Python implementation: So it using `type(x)` not `x.__class__` Thanks, Joy Diamond. ==== ADDENDUM: Here is an example where `type(x) is not x.__class__` (there are other not as perverse examples where you want `.__class__` to differ from `type`) NOTE: The final assert will fail, showing that `type(x) is not x.__class__` # # This really perverse code demonstrates that `t.__class__` is *NOT* # always the same as type(t). # # The code shows an metaclass that when you derive objects from its classes, creates a `7` # instead of a derived class. # def not_really_a_metaclass__make_a_7(name, bases, member): return 7 @property def not_really_a_class__make_a_7(t): return not_really_a_metaclass__make_a_7 class Metaclass__Make_A_7(type): __class__ = not_really_a_class__make_a_7 Make_A_7 = Metaclass__Make_A_7('Make_A_7', ((object,)), {}) # # Now then: # # `Make_A_7` is a class that when inherited from creates a '7' instead # of a class ... :( # # Works for python 2 & pypy (not yet fixed to work for python 3) # class Seven(Make_A_7): # Calls `Make_A_7.__class__('Seven, (('Make_A_7,)), {})` which returns `7` pass print('Seven is: %s' % Seven) assert isinstance(Make_A_7, Metaclass__Make_A_7) assert Make_A_7.__class__ == Metaclass__Make_A_7 # This will *FAIL* due to the perverse definition of `.__class__` On Sat, Oct 27, 2018 at 2:25 PM Chris Angelico <ros...@gmail.com> wrote: > On Sun, Oct 28, 2018 at 5:03 AM Joy Diamond <python....@gmail.com> wrote: > > > > Greetings, > > > > This is a request to fix the documentation for __instancecheck__. > > > > Please add the following (please rewrite better than I can -- I am not > good at explaining concepts in short sentences): > > > > NOTE: As an optimization, isinstance(object, classinfo) does NOT call > classinfo.__instancecheck__(instance) when type(object) == classinfo. > > > > Consider the following program: > > > > class M(type): > > def __instancecheck__(m, t): > > print('instancecheck(%s, %s)' % (m, t)) > > return False # LIE! > > > > Test = M('Test', ((object,)), {}) > > > > something = Test() > > > > print('Does *NOT* call __instancecheck__:') > > print('isinstance(something, Test): %s' % isinstance(something, Test)) > > Here's the passage in question, for reference: > > """ > The following methods are used to override the default behavior of the > isinstance() and issubclass() built-in functions. > > In particular, the metaclass abc.ABCMeta implements these methods in > order to allow the addition of Abstract Base Classes (ABCs) as > “virtual base classes” to any class or type (including built-in > types), including other ABCs. > """ > > https://docs.python.org/3/reference/datamodel.html#customizing-instance-and-subclass-checks > > Since it uses the word "override", I agree that it's not entirely > correct. The implication of "override" is that you can completely > replace the normal behaviour. In this case, you can change the > behaviour of subclass testing (for instance, you can "disown" a > subclass by denying that instances of it are instances of yourself), > and of course, you can claim an object as an instance of a class it > didn't directly inherit from (the way ABCs work), but you cannot fib > about direct instances. I think the behaviour is close enough to > accurate that it doesn't need major rewording; how about adding this > parenthesis: > > """ > (Note that any object `x` is always considered to be an instance of > `x.__class__`, and this cannot be overridden.) > """ > > Would that work? > > ChrisA > _______________________________________________ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/