Skip to content

Commit

Permalink
fix copy and pickle so they work with freezing
Browse files Browse the repository at this point in the history
  • Loading branch information
jpn-- committed Apr 8, 2021
1 parent 75284f9 commit 03a9506
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
8 changes: 7 additions & 1 deletion addict/addict.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,16 @@ def __getnewargs__(self):
return tuple(self.items())

def __getstate__(self):
return self
state = self.to_dict()
isFrozen = (hasattr(self, '__frozen') and
object.__getattribute__(self, '__frozen'))
state['__addict__frozen__'] = isFrozen
return state

def __setstate__(self, state):
shouldFreeze = state.pop('__addict__frozen__', False)
self.update(state)
self.freeze(shouldFreeze)

def __or__(self, other):
if not isinstance(other, (Dict, dict)):
Expand Down
42 changes: 42 additions & 0 deletions test_addict.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,38 @@ def __init__(self):
b.child = "new stuff"
self.assertTrue(isinstance(a.child, self.dict_class))

def test_copy_with_freeze(self):
class MyMutableObject(object):

def __init__(self):
self.attribute = None

foo = MyMutableObject()
foo.attribute = True

a = self.dict_class()
a.child.immutable = 42
a.child.mutable = foo
a.freeze()

b = a.copy()

# immutable object should not change
b.child.immutable = 21
self.assertEqual(a.child.immutable, 21)

# mutable object should change
b.child.mutable.attribute = False
self.assertEqual(a.child.mutable.attribute, b.child.mutable.attribute)

# changing child of b should not affect a
b.child = "new stuff"
self.assertTrue(isinstance(a.child, self.dict_class))

# b should be frozen
with self.assertRaises(KeyError):
b.missing

def test_deepcopy(self):
class MyMutableObject(object):
def __init__(self):
Expand Down Expand Up @@ -450,6 +482,16 @@ def test_pickle(self):
a = self.dict_class(TEST_DICT)
self.assertEqual(a, pickle.loads(pickle.dumps(a)))

def test_pickle_with_freeze(self):
a = self.dict_class(TEST_DICT)
a.freeze()
aa = pickle.loads(pickle.dumps(a))
self.assertEqual(a, aa)
with self.assertRaises(KeyError):
a.missing
with self.assertRaises(KeyError):
aa.missing

def test_add_on_empty_dict(self):
d = self.dict_class()
d.x.y += 1
Expand Down

0 comments on commit 03a9506

Please sign in to comment.