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,23 +12,27 @@ class DynamicModule(ModuleType): ...@@ -11,23 +12,27 @@ 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))
obj = self._factory(name) with self._lock:
# _factory can return an instance, a constant, or a class try:
if isinstance(obj, type): return super(DynamicModule, self).__getattribute__(name)
# if it's a class we want to set __module__ except AttributeError:
obj.__module__ = self.__name__ obj = self._factory(name)
elif isinstance(obj, ModuleType): # _factory can return an instance, a constant, or a class
# if it's a module we want to set the name according to the if isinstance(obj, type):
# module it's being added to # if it's a class we want to set __module__
obj.__name__ = "%s.%s" % (self.__name__, name) obj.__module__ = self.__name__
elif isinstance(obj, ModuleType):
setattr(self, name, obj) # if it's a module we want to set the name according to the
return obj # module it's being added to
obj.__name__ = "%s.%s" % (self.__name__, name)
setattr(self, name, obj)
return obj
def registerDynamicModule(name, factory): def registerDynamicModule(name, factory):
d = DynamicModule(name, factory) d = DynamicModule(name, factory)
......
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