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/JMNLIZJ6XBDCDR6PZWUN33PYOWO4ZFLP/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to