40
40
update_path_extents )
41
41
from numpy .linalg import inv
42
42
43
- from weakref import WeakValueDictionary
43
+ import weakref
44
44
import warnings
45
45
try :
46
46
set
@@ -92,10 +92,7 @@ def __init__(self, shorthand_name=None):
92
92
other than to improve the readability of
93
93
``str(transform)`` when DEBUG=True.
94
94
"""
95
- # Parents are stored in a WeakValueDictionary, so that if the
96
- # parents are deleted, references from the children won't keep
97
- # them alive.
98
- self ._parents = WeakValueDictionary ()
95
+ self ._parents = {}
99
96
100
97
# TransformNodes start out as invalid until their values are
101
98
# computed for the first time.
@@ -109,14 +106,17 @@ def __str__(self):
109
106
110
107
def __getstate__ (self ):
111
108
d = self .__dict__ .copy ()
112
- # turn the weakkey dictionary into a normal dictionary
113
- d ['_parents' ] = dict (six .iteritems (self ._parents ))
109
+ # turn the dictionary with weak values into a normal dictionary
110
+ d ['_parents' ] = dict ((k , v ()) for (k , v ) in
111
+ six .iteritems (self ._parents ))
114
112
return d
115
113
116
114
def __setstate__ (self , data_dict ):
117
115
self .__dict__ = data_dict
118
- # turn the normal dictionary back into a WeakValueDictionary
119
- self ._parents = WeakValueDictionary (self ._parents )
116
+ # turn the normal dictionary back into a dictionary with weak
117
+ # values
118
+ self ._parents = dict ((k , weakref .ref (v )) for (k , v ) in
119
+ six .iteritems (self ._parents ) if v is not None )
120
120
121
121
def __copy__ (self , * args ):
122
122
raise NotImplementedError (
@@ -156,8 +156,11 @@ def _invalidate_internal(self, value, invalidating_node):
156
156
self ._invalid = value
157
157
158
158
for parent in list (six .itervalues (self ._parents )):
159
- parent ._invalidate_internal (value = value ,
160
- invalidating_node = self )
159
+ # Dereference the weak reference
160
+ parent = parent ()
161
+ if parent is not None :
162
+ parent ._invalidate_internal (
163
+ value = value , invalidating_node = self )
161
164
162
165
def set_children (self , * children ):
163
166
"""
@@ -166,8 +169,11 @@ def set_children(self, *children):
166
169
Should be called from the constructor of any transforms that
167
170
depend on other transforms.
168
171
"""
172
+ # Parents are stored as weak references, so that if the
173
+ # parents are destroyed, references from the children won't
174
+ # keep them alive.
169
175
for child in children :
170
- child ._parents [id (self )] = self
176
+ child ._parents [id (self )] = weakref . ref ( self )
171
177
172
178
if DEBUG :
173
179
_set_children = set_children
@@ -1560,8 +1566,9 @@ def __getstate__(self):
1560
1566
'child' : self ._child ,
1561
1567
'input_dims' : self .input_dims ,
1562
1568
'output_dims' : self .output_dims ,
1563
- # turn the weakkey dictionary into a normal dictionary
1564
- 'parents' : dict (six .iteritems (self ._parents ))
1569
+ # turn the weak-values dictionary into a normal dictionary
1570
+ 'parents' : dict ((k , v ()) for (k , v ) in
1571
+ six .iteritems (self ._parents ))
1565
1572
}
1566
1573
1567
1574
def __setstate__ (self , state ):
@@ -1570,8 +1577,10 @@ def __setstate__(self, state):
1570
1577
# The child may not be unpickled yet, so restore its information.
1571
1578
self .input_dims = state ['input_dims' ]
1572
1579
self .output_dims = state ['output_dims' ]
1573
- # turn the normal dictionary back into a WeakValueDictionary
1574
- self ._parents = WeakValueDictionary (state ['parents' ])
1580
+ # turn the normal dictionary back into a dictionary with weak
1581
+ # values
1582
+ self ._parents = dict ((k , weakref .ref (v )) for (k , v ) in
1583
+ six .iteritems (state ['parents' ]) if v is not None )
1575
1584
1576
1585
def __repr__ (self ):
1577
1586
return "TransformWrapper(%r)" % self ._child
0 commit comments