Skip to content

Commit 66dd5fe

Browse files
committed
oops, _observers should be thread-local (so a thread pushing/popping a dynamic scope won't invalidate iterators to live view instances in other threads)
1 parent f6c46c5 commit 66dd5fe

1 file changed

Lines changed: 9 additions & 5 deletions

File tree

unpythonic/dynassign.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,32 @@ def _getstack():
3131
_L._stack = _L.default_stack.copy() # copy main thread's current stack
3232
return _L._stack
3333

34-
_observers = {}
34+
def _getobservers():
35+
if not hasattr(_L, "_observers"):
36+
_L._observers = {}
37+
return _L._observers
38+
3539
class _EnvBlock(object):
3640
def __init__(self, bindings):
3741
self.bindings = bindings
3842
def __enter__(self):
3943
if self.bindings: # optimization, skip pushing an empty scope
4044
_getstack().append(self.bindings)
41-
for o in _observers.values():
45+
for o in _getobservers().values():
4246
o._refresh()
4347
def __exit__(self, t, v, tb):
4448
if self.bindings:
4549
_getstack().pop()
46-
for o in _observers.values():
50+
for o in _getobservers().values():
4751
o._refresh()
4852

4953
class _DynLiveView(ChainMap):
5054
def __init__(self):
5155
super().__init__(self)
5256
self._refresh()
53-
_observers[id(self)] = self
57+
_getobservers()[id(self)] = self
5458
def __del__(self):
55-
del _observers[id(self)]
59+
del _getobservers()[id(self)]
5660
def _refresh(self):
5761
self.maps = list(reversed(_getstack())) + [_global_dynvars]
5862

0 commit comments

Comments
 (0)