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