gh-87995: Make MappingProxyType hashable (GH-94252)

This commit is contained in:
Serhiy Storchaka 2022-06-28 12:54:58 +03:00 committed by GitHub
parent 71d5299b73
commit efdc9d68de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 1 deletions

View File

@ -417,6 +417,12 @@ Standard names are defined for the following types:
.. versionadded:: 3.9
.. describe:: hash(proxy)
Return a hash of the underlying mapping.
.. versionadded:: 3.12
Additional Utility Classes and Functions
----------------------------------------

View File

@ -79,6 +79,9 @@ New Features
Other Language Changes
======================
* :class:`types.MappingProxyType` instances are now hashable if the underlying
mapping is hashable.
(Contributed by Serhiy Storchaka in :gh:`87995`.)
New Modules

View File

@ -1203,6 +1203,16 @@ class MappingProxyTests(unittest.TestCase):
self.assertDictEqual(mapping, {'a': 0, 'b': 1, 'c': 2})
self.assertDictEqual(other, {'c': 3, 'p': 0})
def test_hash(self):
class HashableDict(dict):
def __hash__(self):
return 3844817361
view = self.mappingproxy({'a': 1, 'b': 2})
self.assertRaises(TypeError, hash, view)
mapping = HashableDict({'a': 1, 'b': 2})
view = self.mappingproxy(mapping)
self.assertEqual(hash(view), hash(mapping))
class ClassCreationTests(unittest.TestCase):

View File

@ -0,0 +1,2 @@
:class:`types.MappingProxyType` instances are now hashable if the underlying
mapping is hashable.

View File

@ -1178,6 +1178,12 @@ mappingproxy_getiter(mappingproxyobject *pp)
return PyObject_GetIter(pp->mapping);
}
static Py_hash_t
mappingproxy_hash(mappingproxyobject *pp)
{
return PyObject_Hash(pp->mapping);
}
static PyObject *
mappingproxy_str(mappingproxyobject *pp)
{
@ -1901,7 +1907,7 @@ PyTypeObject PyDictProxy_Type = {
&mappingproxy_as_number, /* tp_as_number */
&mappingproxy_as_sequence, /* tp_as_sequence */
&mappingproxy_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
(hashfunc)mappingproxy_hash, /* tp_hash */
0, /* tp_call */
(reprfunc)mappingproxy_str, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */