[Zope-CVS] CVS: Products/Ape/lib/apelib/core - io.py:1.3

Shane Hathaway shane@zope.com
Mon, 26 May 2003 22:19:43 -0400


Update of /cvs-repository/Products/Ape/lib/apelib/core
In directory cvs.zope.org:/tmp/cvs-serv3480/core

Modified Files:
	io.py 
Log Message:
Expanded the ExportImport test and fixed a bug in import.  It was only
possible to import one object, which is exactly what the former test did.


=== Products/Ape/lib/apelib/core/io.py 1.2 => 1.3 ===
--- Products/Ape/lib/apelib/core/io.py:1.2	Mon May 26 16:15:47 2003
+++ Products/Ape/lib/apelib/core/io.py	Mon May 26 22:19:12 2003
@@ -206,6 +206,7 @@
     def __init__(self, root_mapper, connections, class_factory=None):
         self._objects = {}     # { keychain -> obj }
         self._keychains = {}   # { id(obj) -> keychain }
+        self._incomplete = {}   # { keychain -> 1 }
         self._class_factory = class_factory
         # Avoid a circular reference by making a weakref proxy
         self.obj_io = ObjectSystemIO(root_mapper, proxy(self))
@@ -255,8 +256,7 @@
     def importObject(self, keychain, obj=None, commit_func=None):
         count = 0
         if obj is None:
-            classified_state, hash_value = self.gw_io.load(keychain)
-            obj = self.obj_io.newObject(classified_state)
+            obj = self.getObject(keychain)
         root_obj = obj
         self._register(keychain, obj)
         todo = [(keychain, obj)]
@@ -264,34 +264,51 @@
             keychain, obj = todo.pop()
             classified_state, hash_value = self.gw_io.load(keychain)
             event = self.obj_io.deserialize(keychain, obj, classified_state)
+            if self._incomplete.has_key(keychain):
+                del self._incomplete[keychain]
             count += 1
             if commit_func is not None:
                 commit_func(obj, count)
             ext_refs = event.getExternalRefs()
             if ext_refs:
                 for ext_keychain, ext_obj in ext_refs:
-                    if self._register(ext_keychain, ext_obj):
+                    if (self._register(ext_keychain, ext_obj)
+                        or self._incomplete.has_key(ext_keychain)):
                         todo.append((ext_keychain, ext_obj))
         return root_obj
 
 
     # IKeyedObjectSystem implementation
 
+    def getClass(self, module, name):
+        # Normally called only while importing
+        if self._class_factory is not None:
+            return self._class_factory.getClass(module, name)
+        else:
+            m = __import__(module, {}, {}, ('__doc__',))
+            return getattr(m, name)
+
     def getObject(self, keychain, hints=None):
-        return self._objects[keychain]
+        # Should be called only while importing
+        try:
+            return self._objects[keychain]
+        except KeyError:
+            # This object has not been loaded yet.  Make a stub.
+            classified_state, hash_value = self.gw_io.load(keychain)
+            obj = self.obj_io.newObject(classified_state)
+            # Don't fill in the state yet, to avoid infinite
+            # recursion.  Just register it.
+            self._incomplete[keychain] = 1
+            self._register(keychain, obj)
+            return obj
 
     loadStub = getObject
 
     def identifyObject(self, obj):
+        # Normally called only while exporting
         return self._keychains.get(id(obj))
 
     def newKey(self):
+        # Should be called only while exporting
         return self.gw_io.newKeychain()[-1]
-
-    def getClass(self, module, name):
-        if self._class_factory is not None:
-            return self._class_factory.getClass(module, name)
-        else:
-            m = __import__(module, {}, {}, ('__doc__',))
-            return getattr(m, name)