Skip to content

bpo-39264: Fix UserDict.get() to account for __missing__() #17910

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 10, 2022
9 changes: 8 additions & 1 deletion Lib/collections/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -973,10 +973,17 @@ def __delitem__(self, key): del self.data[key]
def __iter__(self):
return iter(self.data)

# Modify __contains__ to work correctly when __missing__ is present
# Modify __contains__ and get() to work like dict
# does when __missing__ is present.
def __contains__(self, key):
return key in self.data

def get(self, key, default=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment that get() is overridden to avoid a False positive when _missing_ is defined.

if key in self:
return self[key]
return default

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Only one blank line so as to match the surrounding code.


# Now, add the methods in dicts but not in MutableMapping
def __repr__(self): return repr(self.data)
def __copy__(self):
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ def test_dict_copy(self):
obj[123] = "abc"
self._copy_test(obj)

def test_dict_missing(self):
class A(UserDict):
def __missing__(self, key):
return 456
self.assertEqual(A()[123], 456)
# get() ignores __missing__ on dict
self.assertIs(A().get(123), None)


################################################################################
### ChainMap (helper class for configparser and the string module)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed :meth:`collections.UserDict.get` to not call
:meth:`__missing__` when a value is not found. This matches the behavior of
:class:`dict`. Patch by Bar Harel.