Hey guys,

I was just about to fix dict's get() to call __missing__ if a key doesn't exist 
(before returning the default value) but realized that although small, that 
patch can cause future issues.
Right now there's an inconsistency:

>>> from collections import UserDict
>>> class A(dict):
...  def __missing__(self, key):
...   print(key)
... 
>>> class B(UserDict):
...  def __missing__(self, key):
...   print("UserDict", key)
... 
>>> a = A()
>>> b = B()
>>> a.get(123)
>>> b.get(123)
UserDict 123
>>> a.get(123, "abc")
'abc'
>>> b.get(123, "abc")
UserDict 123

The reason for this inconsistency is because the Mapping abc and dict behave 
differently.
Dict's get doesn't call __getitem__ which causes the call not to route to 
__missing__.
MutableMapping's get calls __getitem__, which UserDict implements as a check to 
__missing__ as well.

According to the doc, the specification requires dict's __getitem__ to call 
__missing__. It doesn't say anything about get().

Should get() call __missing__?

If it does, things like defaultdict.get() might break. It will however be more 
consistent with dict's specification.
If it doesn't, we expect Mapping to not care about __missing__ as it's only a 
dict thing, which will require UserDict to override get(). Dict's get() will 
need to receive a doc update as well stating __missing__ is not called.

Second question is: Is __missing__ only a dict thing, or is it part of the 
Mapping ABC?

I would expect it to be a part of the Mapping ABC, with subclasses not having 
to implement it. Right now it's not.

Looking forward for your inputs,
Bar Harel
_______________________________________________
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/SDXOEMAEM6KQ3CQCJVBVRT5QNSPAVU6X/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to