Commit 66cb84d3 authored by Marius Gedminas's avatar Marius Gedminas

Depend on zodbpickle on Python 3

Since now we need to pass an extra argument to loads() and Unpickler(),
but only on Python 3, the old way of ``from ZODB._compat import pickle``
no longer pays out, and I had to import the names directly.
parent 4630d05f
......@@ -131,7 +131,7 @@ setup(name="ZODB",
'zc.lockfile',
'zdaemon >= 4.0.0a1',
'zope.interface',
],
] + ['zodbpickle'] if PY3 else [],
zip_safe = False,
entry_points = """
[console_scripts]
......
......@@ -31,7 +31,7 @@ import ZODB.interfaces
from ZODB import POSException
from ZODB.utils import z64, oid_repr, byte_ord, byte_chr
from ZODB.UndoLogCompatible import UndoLogCompatible
from ZODB._compat import pickle, py2_hasattr
from ZODB._compat import dumps, py2_hasattr
log = logging.getLogger("ZODB.BaseStorage")
......@@ -235,7 +235,7 @@ class BaseStorage(UndoLogCompatible):
desc = transaction.description
ext = transaction._extension
if ext:
ext = pickle.dumps(ext, 1)
ext = dumps(ext, 1)
else:
ext = ""
......
......@@ -19,8 +19,8 @@ import six
import zope.interface
from ZODB.POSException import ConflictError
from ZODB.loglevels import BLATHER
from ZODB.serialize import _protocol, _Unpickler
from ZODB._compat import BytesIO, pickle
from ZODB.serialize import _protocol
from ZODB._compat import BytesIO, Unpickler, Pickler
# Subtle: Python 2.x has pickle.PicklingError and cPickle.PicklingError,
# and these are unrelated classes! So we shouldn't use pickle.PicklingError,
......@@ -75,7 +75,7 @@ def state(self, oid, serial, prfactory, p=''):
p = p or self.loadSerial(oid, serial)
p = self._crs_untransform_record_data(p)
file = BytesIO(p)
unpickler = _Unpickler(file)
unpickler = Unpickler(file)
unpickler.find_global = find_global
unpickler.persistent_load = prfactory.persistent_load
unpickler.load() # skip the class tuple
......@@ -240,7 +240,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
prfactory = PersistentReferenceFactory()
newpickle = self._crs_untransform_record_data(newpickle)
file = BytesIO(newpickle)
unpickler = _Unpickler(file)
unpickler = Unpickler(file)
unpickler.find_global = find_global
unpickler.persistent_load = prfactory.persistent_load
meta = unpickler.load()
......@@ -283,7 +283,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
resolved = resolve(old, committed, newstate)
file = BytesIO()
pickler = pickle.Pickler(file, _protocol)
pickler = Pickler(file, _protocol)
if sys.version_info[0] < 3:
pickler.inst_persistent_id = persistent_id
else:
......
......@@ -23,7 +23,7 @@ import warnings
from ZODB.broken import find_global
from ZODB.utils import z64
from ZODB.Connection import Connection
from ZODB._compat import pickle, BytesIO
from ZODB._compat import Pickler, BytesIO
import ZODB.serialize
import transaction.weakset
......@@ -448,7 +448,7 @@ class DB(object):
# Manually create a pickle for the root to put in the storage.
# The pickle must be in the special ZODB format.
file = BytesIO()
p = pickle.Pickler(file, ZODB.serialize._protocol)
p = Pickler(file, ZODB.serialize._protocol)
p.dump((root.__class__, None))
p.dump(root.__getstate__())
t = transaction.Transaction()
......
......@@ -25,7 +25,7 @@ from ZODB.interfaces import IBlobStorage
from ZODB.POSException import ExportError
from ZODB.serialize import referencesf, _protocol
from ZODB.utils import p64, u64, cp, mktemp
from ZODB._compat import pickle, BytesIO
from ZODB._compat import Pickler, Unpickler, BytesIO
logger = logging.getLogger('ZODB.ExportImport')
......@@ -167,11 +167,11 @@ class ExportImport:
blob_filename = None
pfile = BytesIO(data)
unpickler = pickle.Unpickler(pfile)
unpickler = Unpickler(pfile)
unpickler.persistent_load = persistent_load
newp = BytesIO()
pickler = pickle.Pickler(newp, _protocol)
pickler = Pickler(newp, _protocol)
if sys.version_info[0] < 3:
pickler.inst_persistent_id = persistent_id
else:
......
......@@ -41,7 +41,7 @@ from ZODB.fsIndex import fsIndex
from ZODB import BaseStorage, ConflictResolution, POSException
from ZODB.POSException import UndoError, POSKeyError, MultipleUndoErrors
from ZODB.utils import p64, u64, z64, as_bytes, as_text
from ZODB._compat import pickle, decodebytes, encodebytes
from ZODB._compat import Pickler, loads, decodebytes, encodebytes
# Not all platforms have fsync
......@@ -369,7 +369,7 @@ class FileStorage(
if not self._is_read_only:
# Save the converted index.
f = open(index_name, 'wb')
p = pickle.Pickler(f, 1)
p = Pickler(f, 1)
info['index'] = index
p.dump(info)
f.close()
......@@ -1001,7 +1001,7 @@ class FileStorage(
th = self._read_txn_header(h.tloc)
if th.ext:
d = pickle.loads(th.ext)
d = loads(th.ext)
else:
d = {}
......@@ -1842,7 +1842,7 @@ class FileIterator(FileStorageFormatter):
e = {}
if h.elen:
try:
e = pickle.loads(h.ext)
e = loads(h.ext)
except:
pass
......@@ -1984,7 +1984,7 @@ class UndoSearch:
e = {}
if el:
try:
e = pickle.loads(self.file.read(el))
e = loads(self.file.read(el))
except:
pass
d = {'id': encodebytes(tid).rstrip(),
......
......@@ -14,16 +14,33 @@
try:
# Python 2.x
import cPickle as pickle
from cPickle import Pickler, Unpickler, dump, dumps, loads
IMPORT_MAPPING = {}
NAME_MAPPING = {}
except ImportError:
# Python 3.x: can't use stdlib's pickle because
# http://bugs.python.org/issue6784
## import zodbpickle as pickle
import pickle
from zodbpickle.pickle import Pickler, dump, dumps
from zodbpickle.pickle import Unpickler as _Unpickler, loads as _loads
from _compat_pickle import IMPORT_MAPPING, NAME_MAPPING
class Unpickler(_Unpickler):
def __init__(self, f):
super(Unpickler, self).__init__(f, encoding='ASCII', errors='bytes')
# Py3: Python 3 doesn't allow assignments to find_global,
# instead, find_class can be overridden
find_global = None
def find_class(self, modulename, name):
if self.find_global is None:
return super(Unpickler, self).find_class(modulename, name)
return self.find_global(modulename, name)
def loads(s):
return _loads(s, encoding='ASCII', errors='bytes')
# XXX: overridable Unpickler.find_global as used in serialize.py?
# XXX: consistent spelling of inst_persistent_id/persistent_id?
......
......@@ -30,9 +30,9 @@ import persistent
import ZODB.interfaces
from ZODB.interfaces import BlobError
from ZODB import utils, serialize
from ZODB import utils
from ZODB.POSException import POSKeyError
from ZODB._compat import BytesIO
from ZODB._compat import BytesIO, Unpickler
if sys.version_info[0] >= 3:
......@@ -934,7 +934,7 @@ def is_blob_record(record):
"""
if record and (b'ZODB.blob' in record):
unpickler = serialize._Unpickler(BytesIO(record))
unpickler = Unpickler(BytesIO(record))
unpickler.find_global = find_global_Blob
try:
......
......@@ -20,7 +20,7 @@ import persistent
import zope.interface
import ZODB.interfaces
from ZODB._compat import pickle, IMPORT_MAPPING, NAME_MAPPING
from ZODB._compat import loads, dumps, IMPORT_MAPPING, NAME_MAPPING
broken_cache = {}
......@@ -82,7 +82,7 @@ class Broken(object):
>>> r[2]
{'x': 1}
>>> a2 = pickle.loads(pickle.dumps(a, 1))
>>> a2 = loads(dumps(a, 1))
>>> a2
<broken not.there.Atall instance>
>>> a2.__Broken_newargs__
......
......@@ -44,7 +44,7 @@ from BTrees._fsBTree import fsBucket
from BTrees.OOBTree import OOBTree
import six
from ZODB._compat import pickle
from ZODB._compat import Pickler, Unpickler
# convert between numbers and six-byte strings
......@@ -97,7 +97,7 @@ class fsIndex(object):
def save(self, pos, fname):
with open(fname, 'wb') as f:
pickler = pickle.Pickler(f, 1)
pickler = Pickler(f, 1)
pickler.fast = True
pickler.dump(pos)
for k, v in six.iteritems(self._data):
......@@ -107,7 +107,7 @@ class fsIndex(object):
@classmethod
def load(class_, fname):
with open(fname, 'rb') as f:
unpickler = pickle.Unpickler(f)
unpickler = Unpickler(f)
pos = unpickler.load()
if not isinstance(pos, int):
return pos # Old format
......
......@@ -83,7 +83,7 @@ except ImportError:
import ZODB.FileStorage
from ZODB.utils import u64, as_text
from ZODB.FileStorage import TransactionRecord
from ZODB._compat import pickle
from ZODB._compat import loads
from persistent.TimeStamp import TimeStamp
......@@ -144,7 +144,7 @@ def read_txn_header(f, pos, file_size, outp, ltid):
user = f.read(ul)
description = f.read(dl)
if el:
try: e = pickle.loads(f.read(el))
try: e = loads(f.read(el))
except: e = {}
else: e = {}
......
......@@ -23,7 +23,7 @@ import struct
from ZODB.FileStorage.format import TRANS_HDR, DATA_HDR, TRANS_HDR_LEN
from ZODB.FileStorage.format import DATA_HDR_LEN
from ZODB.utils import u64
from ZODB._compat import pickle
from ZODB._compat import loads
from persistent.TimeStamp import TimeStamp
......@@ -65,7 +65,7 @@ class TxnHeader:
self.descr = self._file.read(self.descr_len)
if self.ext_len:
self._ext = self._file.read(self.ext_len)
self.ext = pickle.loads(self._ext)
self.ext = loads(self._ext)
def get_data_offset(self):
return (self._pos + TRANS_HDR_LEN + self.user_len + self.descr_len
......
......@@ -6,11 +6,8 @@ from __future__ import print_function
import sys
from ZODB.FileStorage import FileStorage
from ZODB._compat import BytesIO
from ZODB._compat import Unpickler, BytesIO
# We must not use cPickle on Python 2: cPickle.Unpickler cannot be
# subclassed.
import pickle
class FakeError(Exception):
......@@ -19,10 +16,17 @@ class FakeError(Exception):
self.module = module
self.name = name
class FakeUnpickler(pickle.Unpickler):
def find_class(self, module, name):
def fake_find_class(module, name):
raise FakeError(module, name)
def FakeUnpickler(f):
unpickler = Unpickler(f)
unpickler.find_global = fake_find_class
return unpickler
class Report:
def __init__(self):
self.OIDMAP = {}
......@@ -105,8 +109,6 @@ def get_type(record):
unpickled = FakeUnpickler(BytesIO(record.data)).load()
except FakeError as err:
return "%s.%s" % (err.module, err.name)
except:
raise
classinfo = unpickled[0]
if isinstance(classinfo, tuple):
mod, klass = classinfo
......
......@@ -140,19 +140,8 @@ from persistent import Persistent
from persistent.wref import WeakRefMarker, WeakRef
from ZODB import broken
from ZODB.POSException import InvalidObjectReference
from ZODB._compat import pickle, BytesIO
if sys.version_info[0] < 3:
_Unpickler = pickle.Unpickler
else:
# Py3: Python 3 doesn't allow assignments to find_global,
# instead, find_class can be overridden
class _Unpickler(pickle.Unpickler):
find_global = None
def find_class(self, modulename, name):
if self.find_global is None:
return super(_Unpickler, self).find_class(modulename, name)
return self.find_global(modulename, name)
from ZODB._compat import Pickler, Unpickler, BytesIO
_oidtypes = bytes, type(None)
......@@ -186,7 +175,7 @@ class ObjectWriter:
def __init__(self, obj=None):
self._file = BytesIO()
self._p = pickle.Pickler(self._file, _protocol)
self._p = Pickler(self._file, _protocol)
if sys.version_info[0] < 3:
self._p.inst_persistent_id = self.persistent_id
else:
......@@ -483,7 +472,7 @@ class ObjectReader:
def _get_unpickler(self, pickle):
file = BytesIO(pickle)
unpickler = _Unpickler(file)
unpickler = Unpickler(file)
unpickler.persistent_load = self._persistent_load
factory = self._factory
conn = self._conn
......@@ -642,7 +631,7 @@ def referencesf(p, oids=None):
"""
refs = []
u = pickle.Unpickler(BytesIO(p))
u = Unpickler(BytesIO(p))
if sys.version_info[0] < 3:
u.persistent_load = refs
u.noload()
......@@ -685,7 +674,7 @@ def get_refs(a_pickle):
"""
refs = []
u = pickle.Unpickler(BytesIO(a_pickle))
u = Unpickler(BytesIO(a_pickle))
if sys.version_info[0] < 3:
u.persistent_load = refs
u.noload()
......
......@@ -22,11 +22,11 @@ from persistent import Persistent
from persistent.mapping import PersistentMapping
from ZODB import DB
from ZODB.POSException import ConflictError, StorageError
from ZODB.serialize import referencesf, _Unpickler, _protocol
from ZODB.serialize import referencesf, _protocol
from ZODB.tests.MinPO import MinPO
from ZODB.tests.MTStorage import TestThread
from ZODB.tests.StorageTestBase import snooze
from ZODB._compat import pickle, BytesIO
from ZODB._compat import loads, Pickler, Unpickler, BytesIO
import transaction
import ZODB.interfaces
import ZODB.tests.util
......@@ -78,7 +78,7 @@ def dumps(obj):
return obj.getoid()
return None
s = BytesIO()
p = pickle.Pickler(s, _protocol)
p = Pickler(s, _protocol)
if sys.version_info[0] < 3:
p.inst_persistent_id = getpersid
else:
......@@ -89,7 +89,7 @@ def dumps(obj):
def pdumps(obj):
s = BytesIO()
p = pickle.Pickler(s)
p = Pickler(s)
p.dump(obj)
p.dump(None)
return s.getvalue()
......@@ -131,7 +131,7 @@ class PackableStorageBase:
# special one. All the Object instances should use pickle.loads().
def loads(str, persfunc=self._cache.get):
fp = BytesIO(str)
u = _Unpickler(fp)
u = Unpickler(fp)
u.persistent_load = persfunc
return u.load()
return loads
......@@ -142,7 +142,7 @@ class PackableStorageBase:
except KeyError:
from transaction import Transaction
file = BytesIO()
p = pickle.Pickler(file, _protocol)
p = Pickler(file, _protocol)
p.dump((PersistentMapping, None))
p.dump({'_container': {}})
t=Transaction()
......@@ -342,15 +342,15 @@ class PackableStorage(PackableStorageBase):
revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj))
# Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid, revid1)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 1)
data = self._storage.loadSerial(oid, revid2)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 2)
data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 3)
# Now pack all transactions; need to sleep a second to make
......@@ -395,15 +395,15 @@ class PackableStorage(PackableStorageBase):
revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj))
# Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid, revid1)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 1)
data = self._storage.loadSerial(oid, revid2)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 2)
data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 3)
# Now pack just revisions 1 and 2. The object's current revision
......@@ -420,12 +420,12 @@ class PackableStorage(PackableStorageBase):
raises(KeyError, self._storage.loadSerial, oid, revid1)
raises(KeyError, self._storage.loadSerial, oid, revid2)
data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 3)
data, revid = self._storage.load(oid, '')
eq(revid, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 3)
......@@ -463,15 +463,15 @@ class PackableStorage(PackableStorageBase):
revid3 = self._dostoreNP(oid1, revid=revid2, data=pdumps(obj1))
# Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid1, revid1)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid1)
eq(pobj.value, 1)
data = self._storage.loadSerial(oid1, revid2)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid1)
eq(pobj.value, 2)
data = self._storage.loadSerial(oid1, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid1)
eq(pobj.value, 3)
# Now commit a revision of the second object
......@@ -479,7 +479,7 @@ class PackableStorage(PackableStorageBase):
revid4 = self._dostoreNP(oid2, data=pdumps(obj2))
# And make sure the revision can be extracted
data = self._storage.loadSerial(oid2, revid4)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid2)
eq(pobj.value, 11)
# Now pack just revisions 1 and 2 of object1. Object1's current
......@@ -497,19 +497,19 @@ class PackableStorage(PackableStorageBase):
raises(KeyError, self._storage.loadSerial, oid1, revid1)
raises(KeyError, self._storage.loadSerial, oid1, revid2)
data = self._storage.loadSerial(oid1, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid1)
eq(pobj.value, 3)
data, revid = self._storage.load(oid1, '')
eq(revid, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid1)
eq(pobj.value, 3)
data, revid = self._storage.load(oid2, '')
eq(revid, revid4)
eq(loads(data).value, 11)
data = self._storage.loadSerial(oid2, revid4)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid2)
eq(pobj.value, 11)
......@@ -531,15 +531,15 @@ class PackableStorageWithOptionalGC(PackableStorage):
revid3 = self._dostoreNP(oid, revid=revid2, data=pdumps(obj))
# Now make sure all three revisions can be extracted
data = self._storage.loadSerial(oid, revid1)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 1)
data = self._storage.loadSerial(oid, revid2)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 2)
data = self._storage.loadSerial(oid, revid3)
pobj = pickle.loads(data)
pobj = loads(data)
eq(pobj.getoid(), oid)
eq(pobj.value, 3)
# Now pack all transactions; need to sleep a second to make
......
......@@ -25,7 +25,7 @@ import transaction
from ZODB.utils import u64
from ZODB.tests.MinPO import MinPO
from ZODB._compat import pickle, BytesIO
from ZODB._compat import Pickler, Unpickler, BytesIO
import ZODB.tests.util
......@@ -50,7 +50,7 @@ def _persistent_id(obj):
def zodb_pickle(obj):
"""Create a pickle in the format expected by ZODB."""
f = BytesIO()
p = pickle.Pickler(f, 1)
p = Pickler(f, 1)
if sys.version_info[0] < 3:
p.inst_persistent_id = _persistent_id
else:
......@@ -76,7 +76,7 @@ def persistent_load(pid):
def zodb_unpickle(data):
"""Unpickle an object stored using the format expected by ZODB."""
f = BytesIO(data)
u = pickle.Unpickler(f)
u = Unpickler(f)
u.persistent_load = persistent_load
klass_info = u.load()
if isinstance(klass_info, tuple):
......
......@@ -32,7 +32,7 @@ from ZODB.tests import HistoryStorage, IteratorStorage, Corruption
from ZODB.tests import RevisionStorage, PersistentStorage, MTStorage
from ZODB.tests import ReadOnlyStorage, RecoveryStorage
from ZODB.tests.StorageTestBase import MinPO, zodb_pickle
from ZODB._compat import pickle
from ZODB._compat import dump, dumps
class FileStorageTests(
......@@ -91,7 +91,7 @@ class FileStorageTests(
newindex = dict(index)
data['index'] = newindex
pickle.dump(data, open('FileStorageTests.fs.index', 'wb'), 1)
dump(data, open('FileStorageTests.fs.index', 'wb'), 1)
return index
def check_conversion_to_fsIndex(self, read_only=False):
......@@ -368,7 +368,7 @@ class AnalyzeDotPyTest(StorageTestBase.StorageTestBase):
self._storage = ZODB.FileStorage.FileStorage("Source.fs", create=True)
def checkanalyze(self):
import types, sys, pickle
import types, sys
from BTrees.OOBTree import OOBTree
from ZODB.scripts import analyze
......@@ -390,14 +390,14 @@ class AnalyzeDotPyTest(StorageTestBase.StorageTestBase):
j = 0
oid, revid = oids[j]
serial = self._storage.store(
oid, revid, pickle.dumps(OOBTree, 1), "", t)
oid, revid, dumps(OOBTree, 1), "", t)
oids[j][1] = serial
# and it could be from a broken module
j = 1
oid, revid = oids[j]
serial = self._storage.store(
oid, revid, pickle.dumps(Broken, 1), "", t)
oid, revid, dumps(Broken, 1), "", t)
oids[j][1] = serial
# but mostly it looks like this
......
......@@ -28,7 +28,7 @@ from transaction import Transaction
import ZODB
from ZODB.MappingStorage import MappingStorage
from ZODB._compat import pickle
from ZODB._compat import Unpickler
try:
import cStringIO
......@@ -87,7 +87,7 @@ class PMTests(unittest.TestCase):
# XXX not BytesIO really?
f = cStringIO.StringIO(root_pickle)
u = pickle.Unpickler(f)
u = Unpickler(f)
klass_info = u.load()
klass = find_global(*klass_info[0])
inst = klass.__new__(klass)
......
......@@ -17,7 +17,7 @@ import unittest
import ZODB.tests.util
from ZODB import serialize
from ZODB._compat import pickle, BytesIO
from ZODB._compat import Pickler, BytesIO
class ClassWithNewargs(int):
......@@ -33,7 +33,7 @@ class ClassWithoutNewargs(object):
def make_pickle(ob):
sio = BytesIO()
p = pickle.Pickler(sio, 1)
p = Pickler(sio, 1)
p.dump(ob)
return sio.getvalue()
......
......@@ -20,7 +20,7 @@ from persistent import Persistent
from zope.testing import renormalizing
from ZODB.utils import U64, p64, u64
from ZODB._compat import pickle, long
from ZODB._compat import loads, long
NUM = 100
......@@ -85,7 +85,7 @@ class TestUtils(unittest.TestCase):
data = data.replace(b'cZODB.tests.MinPO\nMinPO\n',
b'cpath.that.does.not.exist\nlikewise.the.class\n')
# Pickle can't resolve that GLOBAL opcode -- gets ImportError.
self.assertRaises(ImportError, pickle.loads, data)
self.assertRaises(ImportError, loads, data)
# Verify that building ConflictError doesn't get ImportError.
try:
......
......@@ -220,8 +220,8 @@ Note that we pass a file position, which gets saved with the index data.
If we save the data in the old format, we can still read it:
>>> from ZODB._compat import pickle
>>> pickle.dump(dict(pos=42, index=index), open('old', 'wb'), 1)
>>> from ZODB._compat import dump
>>> dump(dict(pos=42, index=index), open('old', 'wb'), 1)
>>> info = fsIndex.load('old')
>>> info['pos']
42
......
......@@ -22,7 +22,7 @@ from tempfile import mkstemp
from persistent.TimeStamp import TimeStamp
from ZODB._compat import pickle, BytesIO
from ZODB._compat import Unpickler, BytesIO
__all__ = ['z64',
......@@ -233,7 +233,7 @@ def get_pickle_metadata(data):
# Else there are a bunch of other possible formats.
f = BytesIO(data)
u = pickle.Unpickler(f)
u = Unpickler(f)
try:
class_info = u.load()
except Exception as err:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment