This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: MappingProxyType cannot hash a hashable underlying mapping
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: andymaier, rhettinger, serhiy.storchaka
Priority: low Keywords:

Created on 2021-04-13 08:25 by andymaier, last changed 2022-04-11 14:59 by admin.

Messages (4)
msg390936 - (view) Author: Andy Maier (andymaier) * Date: 2021-04-13 08:25
Objects of MappingProxyType do expose a __hash__() method, but if the underlying mapping is hashable, it still does not support hashing it.

Example:

Content of mp_hash.py:

------
#!/usr/bin/env python

from nocasedict import NocaseDict, HashableMixin
from types import MappingProxyType

class HashableDict(HashableMixin, NocaseDict):
    """A hashable dictionary"""
    pass

hd = HashableDict({'a': 1, 'b': 2})
print("hash(hd): {}".format(hash(hd)))

mp = MappingProxyType(hd)
print("hash(mp): {}".format(hash(mp)))
-------

Running the mp_hash.py script:

hash(hd): 3709951335832776636
Traceback (most recent call last):
  File "/Users/maiera/Projects/Python/cpython/issues/mappingproxy/./mp_hash.py", line 14, in <module>
    print("hash(mp): {}".format(hash(mp)))
TypeError: unhashable type: 'mappingproxy'

There are use cases where a function wants to return an immutable view on an internal dictionary, and the caller of the function should be able to use the returned object like a dictionary, except that it is read-only.

Note there is https://bugs.python.org/issue31209 on the inability to pickle MappingProxyType objects which was closed without adding the capability. That would fall under the same argument.
msg391028 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2021-04-14 03:12
Serhiy, what do you think?  Would it make sense to pass through the underlying hash?  I don't think there is much use for this but don't see any particular reason to block it.
msg391038 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-04-14 07:24
Perhaps MappingProxyType is unhashable by accident. It implements __eq__, and it makes it unhashable by default. And nobody made request for this feature before. I think that implementing __hash__ would not make anything wrong.
msg391041 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2021-04-14 07:46
But there is an issue with comparison implementation in MappingProxyType (see issue43838). Resolving that issue can affect the decision about hashability.

There should be always true the following predicate: if x == y then hash(x) == hash(y).
History
Date User Action Args
2022-04-11 14:59:44adminsetgithub: 87995
2021-04-14 07:46:45serhiy.storchakasetmessages: + msg391041
2021-04-14 07:24:00serhiy.storchakasetmessages: + msg391038
2021-04-14 03:12:29rhettingersetpriority: normal -> low
versions: + Python 3.10, - Python 3.9
nosy: + rhettinger, serhiy.storchaka

messages: + msg391028
2021-04-13 08:25:32andymaiercreate