[Zodb-checkins] CVS: Zope3/lib/python/Persistence - Module.py:1.25
Jeremy Hylton
jeremy@zope.com
Mon, 7 Oct 2002 19:29:04 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv7635/Persistence
Modified Files:
Module.py
Log Message:
Add some hackery to make sure module registry is not a ghost.
There is a delicate dance going on here between the registry and the
importer. The registry must be unghostified before the importer tries
to use it, or hard-to-debug failures occur.
We need _p_incref() / _p_decref() methods that guarantee the object
won't be ghostified, but we don't have them yet.
=== Zope3/lib/python/Persistence/Module.py 1.24 => 1.25 ===
--- Zope3/lib/python/Persistence/Module.py:1.24 Thu Oct 3 15:44:23 2002
+++ Zope3/lib/python/Persistence/Module.py Mon Oct 7 19:29:03 2002
@@ -21,6 +21,7 @@
import sys
from Persistence import Persistent
+from Persistence.cPersistence import GHOST
from Persistence.Class import PersistentMetaClass
from Persistence.Function import PersistentFunction
from Persistence.IPersistentModuleManager import IPersistentModuleManager
@@ -114,6 +115,7 @@
self._module._p_changed = True
moddict = self._module.__dict__
copy = moddict.copy()
+ self._registry._p_activate() # should lock
moddict[__persistent_module_registry__] = self._registry
exec source in moddict
del moddict[__persistent_module_registry__]
@@ -177,6 +179,23 @@
return parent
class PersistentModuleImporter:
+ """An import hook that loads persistent modules.
+
+ The importer cooperates with other objects to make sure imports of
+ persistent modules work correctly. The default importer depends
+ on finding a persistent module registry in the globals passed to
+ __import__(). It looks for the name __persistent_module_registry__.
+ A PersistentModuleManager places its registry in the globals used
+ to exec module source.
+
+ It is important that the registry be activated before it is used
+ to handle imports. If a ghost registry is used for importing, a
+ circular import occurs. The second import occurs when the
+ machinery searches for the class of the registry. It will re-use
+ the registry and fail, because the registry will be marked as
+ changed but not yet have its stated loaded. XXX There ought to be
+ a way to deal with this.
+ """
def __init__(self):
self._saved_import = None
@@ -245,8 +264,9 @@
self.__modules = {}
def findModule(self, name):
+ assert self._p_state != GHOST
return self.__modules.get(name)
-
+
def setModule(self, name, module):
if name in self.__modules:
raise ValueError, name