diff options
author | Bar Harel <bar.harel@biocatch.com> | 2022-05-10 21:23:45 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-10 21:23:45 (GMT) |
commit | 30a43586f0d1776d25beb71b92f9880be7997e1b (patch) | |
tree | ee687cdb9f119fefe39f1eefa9941ad8af25e835 | |
parent | f481a02e6c7c981d1316267bad5fb94fee912ad6 (diff) | |
download | cpython-30a43586f0d1776d25beb71b92f9880be7997e1b.zip cpython-30a43586f0d1776d25beb71b92f9880be7997e1b.tar.gz cpython-30a43586f0d1776d25beb71b92f9880be7997e1b.tar.bz2 |
bpo-39264: Fix UserDict.get() to account for __missing__() (GH-17910)
Here's the patch according to the discussion at the [Python-Dev mailing list](https://mail.python.org/archives/list/python-dev@python.org/thread/SDXOEMAEM6KQ3CQCJVBVRT5QNSPAVU6X/).
UserDict.get() will match dict's behavior and not call `__missing__`.
Automerge-Triggered-By: GH:rhettinger
-rw-r--r-- | Lib/collections/__init__.py | 9 | ||||
-rw-r--r-- | Lib/test/test_collections.py | 8 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2020-01-09-01-57-12.bpo-39264.GsBL9-.rst | 3 |
3 files changed, 19 insertions, 1 deletions
diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 7af8dcd..5860787 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1132,10 +1132,17 @@ class UserDict(_collections_abc.MutableMapping): 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): + if key in self: + return self[key] + return default + + # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index fa1d0e0..59b3f2e 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -71,6 +71,14 @@ class TestUserObjects(unittest.TestCase): 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) diff --git a/Misc/NEWS.d/next/Library/2020-01-09-01-57-12.bpo-39264.GsBL9-.rst b/Misc/NEWS.d/next/Library/2020-01-09-01-57-12.bpo-39264.GsBL9-.rst new file mode 100644 index 0000000..5f9ffdf --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-01-09-01-57-12.bpo-39264.GsBL9-.rst @@ -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. |