Reputation: 408
Is there any cross-platform way to get a reference to some mapping object by having a MappingProxyType instance of that mapping?
>>> class A: pass
>>> A.__dict__ # is there a way to get the wrapped dict of this proxy?
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})
or
>>> import types
>>> m = {1: 2}
>>> mp = types.MappingProxyType(m) # how to extract m from mp?
Upvotes: 2
Views: 2686
Reputation: 451
There is a way, though it is hacky (see the python bug tracker page):
from types import MappingProxyType
class _get_original_dict:
def __eq__(self, other: MappingProxyType) -> dict:
return other
_get_original_dict = _get_original_dict()
# https://bugs.python.org/issue43838
def get_original_dict(proxy: MappingProxyType) -> dict:
return proxy == _get_original_dict
orig = {1: 2}
proxy = MappingProxyType(orig)
dct = get_original_dict(proxy)
dct[25] = 3
assert dct[25] == 3
assert proxy[25] == 3
T = type("T", (), {})
get_original_dict(T.__dict__)["xxxx"] = 25
assert T.xxxx == 25
Upvotes: 0
Reputation: 6359
MappingProxyType is like a dict
where the __setattr__
method will always throw an error. By design, you cannot add any new key/value pairs. However, you can obtain a shallow copy of its contents in a normal dictionary.
Assuming you have a mapping proxy...
import types
# Given a normal dictionary...
dictionary = {
"foo": 10,
"bar": 20,
}
# That has been wrapped in a mapping proxy...
proxy = types.MappingProxyType(dictionary)
# That cannot accept new key/value pairs...
proxy["baz"] = 30 # Throws TypeError: 'mappingproxy' object does not support item assignment
You can create a shallow copy of its inner dictionary like so:
dictionary_copy = proxy.copy()
print(type(dictionary_copy)) # Prints "<class 'dict'>"
print(dictionary_copy is dictionary) # Prints "False" because it's a copy
dictionary_copy["baz"] = 30 # Doesn't throw any errors
As far as I'm aware, there's no way to extract the original dictionary, or add new key/value pairs without making a copy first.
Upvotes: 4