[Zodb-checkins] CVS: Zope3/lib/python/Persistence - Module.py:1.12
Jeremy Hylton
jeremy@zope.com
Thu, 19 Sep 2002 18:06:51 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv14339
Modified Files:
Module.py
Log Message:
Add partial support for packages.
XXX Still don't handle package relative imports.
Fix __repr__() of PersistentModule to handle subclasses.
Catch KeyError in __getstate__(): Empty packages don't have code
executed in them, so they don't have an __builtins__.
Add _import() helper to PersistentModuleImport to make test subclasses
easier.
=== Zope3/lib/python/Persistence/Module.py 1.11 => 1.12 ===
--- Zope3/lib/python/Persistence/Module.py:1.11 Thu Sep 19 17:37:21 2002
+++ Zope3/lib/python/Persistence/Module.py Thu Sep 19 18:06:50 2002
@@ -36,7 +36,7 @@
self.__name__ = name
def __repr__(self):
- return "<PersistentModule %s>" % self.__name__
+ return "<%s %s>" % (self.__class__.__name__, self.__name__)
# XXX need getattr &c. hooks to update _p_changed?
# XXX what about code that modifies __dict__ directly?
@@ -44,7 +44,10 @@
def __getstate__(self):
d = self.__dict__.copy()
- del d["__builtins__"]
+ try:
+ del d["__builtins__"]
+ except KeyError:
+ pass
return d
def __setstate__(self, state):
@@ -52,6 +55,9 @@
state["__builtins__"] = __builtin__
self.__dict__.update(state)
+class PersistentPackage(PersistentModule):
+ pass
+
__persistent_module_registry__ = "__persistent_module_registry__"
class PersistentModuleManager(Persistent):
@@ -69,7 +75,14 @@
def new(self, name, source):
if self._module is not None:
raise ValueError, "module already exists"
+ if "." in name:
+ parent = self._package(name)
+ else:
+ parent = None
self._module = PersistentModule(name)
+ if parent is not None:
+ modname = name.split(".")[-1]
+ setattr(parent, modname, self._module)
try:
self._registry.setModule(name, self._module)
except ValueError:
@@ -112,6 +125,22 @@
old_v.__setstate__(state)
new[k] = old_v
+ def _package(self, name):
+ parts = name.split(".")[:-1]
+ parent = None
+ for i in range(len(parts)):
+ pname = ".".join(parts[:i+1])
+ package = self._registry.findModule(pname)
+ if package is None:
+ package = PersistentPackage(pname)
+ self._registry.setModule(pname, package)
+ if parent is not None:
+ setattr(parent, parts[i], package)
+ elif not isinstance(package, PersistentPackage):
+ raise ValueError, "%s is module" % pname
+ parent = package
+ return parent
+
class PersistentModuleImporter:
def __init__(self):
@@ -124,12 +153,25 @@
def uninstall(self):
__builtin__.__import__ = self._saved_import
+ def _import(self, registry, name, fromlist):
+ mod = registry.findModule(name)
+ if mod is not None:
+ if fromlist:
+ return mod
+ else:
+ i = name.find(".")
+ if i == -1:
+ return mod
+ top = registry.findModule(name[:i])
+ assert top is not None, "No package for module %s" % name
+ return top
+ return None
+
def __import__(self, name, globals={}, locals={}, fromlist=[]):
registry = globals.get(__persistent_module_registry__)
if registry is not None:
- mod = registry.findModule(name)
+ mod = self._import(registry, name, fromlist)
if mod is not None:
- # XXX package support needed here
return mod
return self._saved_import(name, globals, locals, fromlist)