I have the need to ensure that a dict
can only accept a certain type of objects as values. It also have to be pickable.
Here is my first attempt:
import pickle
class TypedDict(dict):
_dict_type = None
def __init__(self, dict_type, *args, **kwargs):
super().__init__(*args, **kwargs)
self._dict_type = dict_type
def __setitem__(self, key, value):
if not isinstance(value, self._dict_type):
raise TypeError('Wrong type')
super().__setitem__(key, value)
If I test it with the following code (python 3.5)
my_dict = TypedDict(int)
my_dict['foo'] = 98
with open('out.pkl', 'wb') as fin:
pickle.dump(my_dict, fin)
with open('out.pkl', 'rb') as fin:
out = pickle.load(fin)
I get the error: TypeError: isinstance() arg 2 must be a type or tuple of types
.
It seems that it is not loading the correct value for _dict_type
and it is instead using the default None
.
Also, It seems to be dependent on the protocol as if it is working correctly with protocol=0
However, if I override the __reduce__
method and just call the super everything magically works.
def __reduce__(self):
return super().__reduce__()
How it is possible? Shouldn't be the two classes (w/o __reduce__
) equivalent? What am I missing?