0

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?
facehugger
  • 388
  • 1
  • 2
  • 11
  • What do you mean by "get the wrapped dict of this proxy"? Do you want to extract some information out of `A.__dict__`? – byxor Feb 04 '20 at 16:30
  • @byxor e.g, `d = {1: 2}; mpd = types.MappingProxyType(d)`. How to extract `d` from `mpd`? – facehugger Feb 04 '20 at 16:36

1 Answers1

4

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.

byxor
  • 5,930
  • 4
  • 27
  • 44
  • @facehugger No problem, my answer isn't very satisfying. What are you trying to do in particular? There might be a better way to go about it. (This might be an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)) – byxor Feb 04 '20 at 19:03
  • "MappingProxyType is like a dict with no __setattr__ method." No it has: `hasattr(m, "__setattr__")`. Also `print(type(dictionary_copy))` prints `` but I think is is just a hack. It dont seems like a dict. Try `pickle.dumps(proxy.copy())` – Ekrem Dinçel Feb 04 '20 at 21:13