Commit 9dd11e5e authored by Julien Muchembled's avatar Julien Muchembled

Fix race condition causing PicklingError when there are several Zope threads

parent 11953a74
from types import ModuleType from types import ModuleType
import sys import sys
import threading
class DynamicModule(ModuleType): class DynamicModule(ModuleType):
"""This module may generate new objects at runtime.""" """This module may generate new objects at runtime."""
...@@ -11,11 +12,16 @@ class DynamicModule(ModuleType): ...@@ -11,11 +12,16 @@ class DynamicModule(ModuleType):
def __init__(self, name, factory, doc=None): def __init__(self, name, factory, doc=None):
super(DynamicModule, self).__init__(name, doc=doc) super(DynamicModule, self).__init__(name, doc=doc)
self._factory = factory self._factory = factory
self._lock = threading.Lock()
def __getattr__(self, name): def __getattr__(self, name):
if name[:2] == '__': if name[:2] == '__':
raise AttributeError('%r module has no attribute %r' raise AttributeError('%r module has no attribute %r'
% (self.__name__, name)) % (self.__name__, name))
with self._lock:
try:
return super(DynamicModule, self).__getattribute__(name)
except AttributeError:
obj = self._factory(name) obj = self._factory(name)
# _factory can return an instance, a constant, or a class # _factory can return an instance, a constant, or a class
if isinstance(obj, type): if isinstance(obj, type):
...@@ -25,7 +31,6 @@ class DynamicModule(ModuleType): ...@@ -25,7 +31,6 @@ class DynamicModule(ModuleType):
# if it's a module we want to set the name according to the # if it's a module we want to set the name according to the
# module it's being added to # module it's being added to
obj.__name__ = "%s.%s" % (self.__name__, name) obj.__name__ = "%s.%s" % (self.__name__, name)
setattr(self, name, obj) setattr(self, name, obj)
return obj return obj
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment