[Zodb-checkins] CVS: Zope3/lib/python/Persistence - Module.py:1.16

Jeremy Hylton jeremy@zope.com
Fri, 20 Sep 2002 14:27:12 -0400


Update of /cvs-repository/Zope3/lib/python/Persistence
In directory cvs.zope.org:/tmp/cvs-serv1209

Modified Files:
	Module.py 
Log Message:
Handle "from A.B import D" where A.B.D is a module/package.
Refactor PersistentModuleManager to (hopefully) simplify packages.


=== Zope3/lib/python/Persistence/Module.py 1.15 => 1.16 ===
--- Zope3/lib/python/Persistence/Module.py:1.15	Fri Sep 20 11:21:05 2002
+++ Zope3/lib/python/Persistence/Module.py	Fri Sep 20 14:27:12 2002
@@ -58,11 +58,17 @@
 
 # TODO for persistent packages:
 # handle package-local imports
+# handle from package import submodule
 
 class PersistentPackage(PersistentModule):
     # XXX Is it okay that these packages don't have __path__?
-    pass
-    
+
+    # A PersistentPackage can exist in a registry without a manager.
+    # It only gets a manager if someone creates an __init__ module for
+    # the package.
+
+    def __init__(self, name):
+        self.__name__ = name
 
 __persistent_module_registry__ = "__persistent_module_registry__"
 
@@ -82,21 +88,19 @@
         if self._module is not None:
             raise ValueError, "module already exists"
         if "." in name:
-            parent = self._package(name)
-            modname = name.split(".")[-1]
-            if modname == "__init__":
-                self._module = parent
-            else:
-                self._module = PersistentModule(name)
-                setattr(parent, modname, self._module)
+            parent = self._new_package(name)
         else:
+            parent = None
             self._module = PersistentModule(name)
         try:
             self._registry.setModule(name, self._module)
-        except ValueError:
+        except ValueError, err:
             self._module = None
             raise
         self.update(source)
+        if parent is not None:
+            modname = name.split(".")[-1]
+            setattr(parent, modname, self._module)
 
     def update(self, source):
         moddict = self._module.__dict__
@@ -133,7 +137,19 @@
                     old_v.__setstate__(state)
                     new[k] = old_v
 
-    def _package(self, name):
+    def _new_package(self, name):
+        parent = self._get_parent(name)
+        modname = name.split(".")[-1]
+        if modname == "__init__":
+            self._module = parent
+            return None
+        else:
+            self._module = PersistentModule(name)
+            return parent
+
+    def _get_parent(self, name):
+        # If a module is being created in a package, automatically
+        # created an parent packages that do no already exist.
         parts = name.split(".")[:-1]
         parent = None
         for i in range(len(parts)):
@@ -164,9 +180,12 @@
         __builtin__.__import__ = self._saved_import
 
     def _import(self, registry, name, parent, fromlist):
+        if parent is not None:
+            pass # XXX
         mod = registry.findModule(name)
         if mod is not None:
             if fromlist:
+                self._import_fromlist(registry, mod, fromlist)
                 return mod
             else:
                 i = name.find(".")
@@ -176,6 +195,12 @@
                 assert top is not None, "No package for module %s" % name
                 return top
         return None
+
+    def _import_fromlist(self, registry, mod, fromlist):
+        for name in fromlist:
+            if not hasattr(mod, name):
+                fullname = "%s.%s" % (mod.__name__, name)
+                self._import(registry, fullname, None, [])
 
     def __import__(self, name, globals={}, locals={}, fromlist=[]):
         registry = globals.get(__persistent_module_registry__)