[Zodb-checkins] SVN: ZODB/branches/3.3/ Change ConflictError
constructor to stop importing app objects.
Tim Peters
tim.one at comcast.net
Thu Nov 11 10:31:30 EST 2004
Log message for revision 28435:
Change ConflictError constructor to stop importing app objects.
When the ConflictError constructor is passed a pickle, extract
the module and class names without loading the pickle. A ZEO
server doesn't necessarily have the implementation code for
application classes, and when that's so the attempt to raise
ConflictError was itself dying with an ImportError.
Changed:
U ZODB/branches/3.3/NEWS.txt
U ZODB/branches/3.3/src/ZODB/POSException.py
U ZODB/branches/3.3/src/ZODB/tests/testUtils.py
-=-
Modified: ZODB/branches/3.3/NEWS.txt
===================================================================
--- ZODB/branches/3.3/NEWS.txt 2004-11-11 03:18:30 UTC (rev 28434)
+++ ZODB/branches/3.3/NEWS.txt 2004-11-11 15:31:30 UTC (rev 28435)
@@ -17,6 +17,17 @@
problem in a release build (``ghostify()`` is supposed to be so simple that
it "can't fail").
+ConflictError
+-------------
+
+New in 3.3, a ``ConflictError`` exception may attempt to insert the path to
+the object's class in its message. However, a ZEO server may not have
+access to application class implementations, and then the attempt by the
+server to raise ``ConflictError`` could raise ``ImportError`` instead while
+trying to determine the object's class path. This was confusing. The code
+has been changed to obtain the class path from the object's pickle, without
+trying to import application modules or classes.
+
Install
-------
Modified: ZODB/branches/3.3/src/ZODB/POSException.py
===================================================================
--- ZODB/branches/3.3/src/ZODB/POSException.py 2004-11-11 03:18:30 UTC (rev 28434)
+++ ZODB/branches/3.3/src/ZODB/POSException.py 2004-11-11 15:31:30 UTC (rev 28435)
@@ -90,8 +90,8 @@
if data is not None:
# avoid circular import chain
- from ZODB.serialize import SimpleObjectReader
- self.class_name = SimpleObjectReader().getClassName(data)
+ from ZODB.utils import get_pickle_metadata
+ self.class_name = "%s.%s" % get_pickle_metadata(data)
## else:
## if message != "data read conflict error":
## raise RuntimeError
Modified: ZODB/branches/3.3/src/ZODB/tests/testUtils.py
===================================================================
--- ZODB/branches/3.3/src/ZODB/tests/testUtils.py 2004-11-11 03:18:30 UTC (rev 28434)
+++ ZODB/branches/3.3/src/ZODB/tests/testUtils.py 2004-11-11 15:31:30 UTC (rev 28435)
@@ -53,6 +53,41 @@
writer = BaseObjectWriter(None)
self.assertEqual(writer.persistent_id(P), None)
+ # It's hard to know where to put this test. We're checking that the
+ # ConflictError constructor uses utils.py's get_pickle_metadata() to
+ # deduce the class path from a pickle, instead of actually loading
+ # the pickle (and so also trying to import application module and
+ # class objects, which isn't a good idea on a ZEO server when avoidable).
+ def checkConflictErrorDoesntImport(self):
+ from ZODB.serialize import BaseObjectWriter
+ from ZODB.POSException import ConflictError
+ from ZODB.tests.MinPO import MinPO
+ import cPickle as pickle
+
+ obj = MinPO()
+ data = BaseObjectWriter().serialize(obj)
+
+ # The pickle contains a GLOBAL ('c') opcode resolving to MinPO's
+ # module and class.
+ self.assert_('cZODB.tests.MinPO\nMinPO\n' in data)
+
+ # Fiddle the pickle so it points to something "impossible" instead.
+ data = data.replace('cZODB.tests.MinPO\nMinPO\n',
+ 'cpath.that.does.not.exist\nlikewise.the.class\n')
+ # Pickle can't resolve that GLOBAL opcode -- gets ImportError.
+ self.assertRaises(ImportError, pickle.loads, data)
+
+ # Verify that building ConflictError doesn't get ImportError.
+ try:
+ raise ConflictError(object=obj, data=data)
+ except ConflictError, detail:
+ # And verify that the msg names the impossible path.
+ self.assert_('path.that.does.not.exist.likewise.the.class' in
+ str(detail))
+ else:
+ self.fail("expected ConflictError, but no exception raised")
+
+
def test_suite():
return unittest.makeSuite(TestUtils, 'check')
More information about the Zodb-checkins
mailing list