It actually is documented as being supported here: 
https://docs.python.org/3.10/reference/datamodel.html#id2, and as mentioned 
there __iter__(), __reversed__() and __contains__() also have special support 
so they avoid trying to fallback to __getitem__ etc. Also some discussion at 
https://github.com/python/cpython/issues/70146. For most methods the conclusion 
back then makes sense, a specific exception message being raised would just 
potentially slow the interpreter.

- Spencer

On 1 May 2022, at 3:22 pm, Serhiy Storchaka <storch...@gmail.com> wrote:

There is a special handling of `__hash__` set to None in the interpreter core. 
This is because every class inherited the `__hash__` attribute from "object", 
and setting `__hash__ = None` is a simple way to make it unhashable. It makes 
hash() raising the correct type of exception (TypeError), but with unhelpful 
error message "'NoneType' object is not callable". The special case was added 
to make the error message more relevant: "unhashable type: '{typename}'".

There is similar situation with other special methods defined in "object" or 
other common classes. Sometimes we want to cancel the default inherited 
behavior.

  >>> dir(object)
  ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', 
'__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', 
'__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', 
'__subclasshook__']

I propose to support officially the idiom "__dunder__ = None" and add special 
cases to raise more specialized exception instead of "TypeError: 'NoneType' 
object is not callable" for most of special method where cancelling the default 
behavior makes sense (for example I do not think that we need better error 
message for `__repr__ = None`).

The question is how to interpret value None:

* Always raise TypeError (with changed message)? This is what happen currently 
when you set the method to None, this is the most compatible option.
* Always raise an error, but allow to change it to more appropriate type (for 
example AttributeError for __setattr__)?
* Interpret value None the same way as an absent attribute?

For `__hash__` or `__class_getitem__` all three options mean the same. But 
absent `__mro_entries__` and `__mro_entries__ = None` currently give different 
results. It is even more complicated for pickling: absent `__reduce_ex__` and 
`__reduce_ex__ = None` mean the same in the Python implementation, but give 
different results in the C implementation.

_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/YGAK34DRWJFSIV2VZ4NC2J24XO37GCMM/
Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/VFNIUX6K6ZVLUOHNDSD7NGPCWGLESLE7/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to