[Zodb-checkins] SVN: ZODB/branches/3.3/ get_pickle_metadata(): This did crazy stuff if the ZODB pickle

Tim Peters tim.one at comcast.net
Fri Aug 20 18:46:26 EDT 2004

Log message for revision 27202:
  get_pickle_metadata():  This did crazy stuff if the ZODB pickle
  started with a pickle GLOBAL opcode.  Curiously, it handled the
  case of starting with a MARK GLOBAL opcode *sequence* fine.

  U   ZODB/branches/3.3/NEWS.txt
  U   ZODB/branches/3.3/src/ZODB/FileStorage/fsdump.py

Modified: ZODB/branches/3.3/NEWS.txt
--- ZODB/branches/3.3/NEWS.txt	2004-08-20 22:14:11 UTC (rev 27201)
+++ ZODB/branches/3.3/NEWS.txt	2004-08-20 22:46:26 UTC (rev 27202)
@@ -34,7 +34,16 @@
 finding a data record for an object uncreation or version abort.  These
 no longer appear.
+fsdump.py's get_pickle_metadata() function (which is used by several
+tools) was confused about what to do when the ZODB pickle started with
+a pickle GLOBAL opcode.  It actually loaded the class then, which it
+intends never to do, leading to stray messages on stdout when the class
+wasn't available, and leading to a strange return value even when it was
+available (the repr of the type object was returned as "the module name",
+and an empty string was returned as "the class name").  This has been
 What's new in ZODB3 3.3 beta 2
 Release date: 13-Aug-2004

Modified: ZODB/branches/3.3/src/ZODB/FileStorage/fsdump.py
--- ZODB/branches/3.3/src/ZODB/FileStorage/fsdump.py	2004-08-20 22:14:11 UTC (rev 27201)
+++ ZODB/branches/3.3/src/ZODB/FileStorage/fsdump.py	2004-08-20 22:46:26 UTC (rev 27202)
@@ -1,3 +1,8 @@
+from cPickle import Unpickler
+from cStringIO import StringIO
+import md5
+import struct
 from ZODB.FileStorage import FileIterator
 from ZODB.FileStorage.format \
@@ -5,23 +10,27 @@
 from ZODB.utils import u64
 from ZODB.tests.StorageTestBase import zodb_unpickle
-from cPickle import Unpickler
-from cStringIO import StringIO
-import md5
-import struct
-import types
 def get_pickle_metadata(data):
     # ZODB's data records contain two pickles.  The first is the class
     # of the object, the second is the object.  We're only trying to
     # pick apart the first here, to extract the module and class names.
-    if data.startswith('(c'):   # pickle MARK GLOBAL sequence
+    if data.startswith('(c'):   # pickle MARK GLOBAL opcode sequence
+        global_prefix = 2
+    elif data.startswith('c'):  # pickle GLOBAL opcode
+        global_prefix = 1
+    else:
+        global_prefix = 0
+    if global_prefix:
         # Don't actually unpickle a class, because it will attempt to
         # load the class.  Just break open the pickle and get the
-        # module and class from it.
+        # module and class from it.  The module and the class names are
+        # given by newline-terminated strings following the GLOBAL opcode.
         modname, classname, rest = data.split('\n', 2)
-        modname = modname[2:]   # strip leading '(c'
+        modname = modname[global_prefix:]   # strip GLOBAL opcode
         return modname, classname
+    # Else there are a bunch of other possible formats.
     f = StringIO(data)
     u = Unpickler(f)
@@ -29,8 +38,8 @@
     except Exception, err:
         print "Error", err
         return '', ''
-    if isinstance(class_info, types.TupleType):
-        if isinstance(class_info[0], types.TupleType):
+    if isinstance(class_info, tuple):
+        if isinstance(class_info[0], tuple):
             modname, classname = class_info[0]
             modname, classname = class_info

More information about the Zodb-checkins mailing list