Commit 1b21b3a8 authored by Jason Madden's avatar Jason Madden

Use pickle protocol 3 on the wire.

parent b823ccde
Changelog Changelog
========= =========
5.1.3 (unreleased) 5.2.0 (unreleased)
------------------ ------------------
- Fix ``ZEO.server`` relying on test dependencies. See `issue 105 - Fix ``ZEO.server`` relying on test dependencies. See `issue 105
...@@ -20,6 +20,10 @@ Changelog ...@@ -20,6 +20,10 @@ Changelog
had ``zodbpickle.binary`` OIDs. See `issue 113 had ``zodbpickle.binary`` OIDs. See `issue 113
<https://github.com/zopefoundation/ZEO/issues/113>`_. <https://github.com/zopefoundation/ZEO/issues/113>`_.
- ZEO now uses pickle protocol 3 for both Python 2 and Python 3.
(Previously protocol 1 was used for Python 2.) This matches the
change in ZODB 5.4.0.
5.1.2 (2018-03-27) 5.1.2 (2018-03-27)
------------------ ------------------
......
...@@ -22,7 +22,7 @@ PYPY = getattr(platform, 'python_implementation', lambda: None)() == 'PyPy' ...@@ -22,7 +22,7 @@ PYPY = getattr(platform, 'python_implementation', lambda: None)() == 'PyPy'
WIN = sys.platform.startswith('win') WIN = sys.platform.startswith('win')
if PY3: if PY3:
from pickle import Pickler, Unpickler as _Unpickler, dump, dumps, loads from zodbpickle.pickle import Pickler, Unpickler as _Unpickler, dump, dumps, loads
class Unpickler(_Unpickler): class Unpickler(_Unpickler):
# Py3: Python 3 doesn't allow assignments to find_global, # Py3: Python 3 doesn't allow assignments to find_global,
# instead, find_class can be overridden # instead, find_class can be overridden
...@@ -34,8 +34,15 @@ if PY3: ...@@ -34,8 +34,15 @@ if PY3:
return super(Unpickler, self).find_class(modulename, name) return super(Unpickler, self).find_class(modulename, name)
return self.find_global(modulename, name) return self.find_global(modulename, name)
else: else:
# Pickle support try:
from cPickle import Pickler, Unpickler, dump, dumps, loads import zodbpickle.fastpickle as cPickle
except ImportError:
import zodbpickle.pickle as cPickle
Pickler = cPickle.Pickler
Unpickler = cPickle.Unpickler
dump = cPickle.dump
dumps = cPickle.dumps
loads = cPickle.loads
# String and Bytes IO # String and Bytes IO
from ZODB._compat import BytesIO from ZODB._compat import BytesIO
......
...@@ -42,25 +42,18 @@ def encoder(protocol, server=False): ...@@ -42,25 +42,18 @@ def encoder(protocol, server=False):
else: else:
assert protocol[:1] == b'Z' assert protocol[:1] == b'Z'
if PY3 or PYPY: f = BytesIO()
f = BytesIO() getvalue = f.getvalue
getvalue = f.getvalue seek = f.seek
seek = f.seek truncate = f.truncate
truncate = f.truncate pickler = Pickler(f, 3)
pickler = Pickler(f, 3 if PY3 else 1) pickler.fast = 1
pickler.fast = 1 dump = pickler.dump
dump = pickler.dump def encode(*args):
def encode(*args): seek(0)
seek(0) truncate()
truncate() dump(args)
dump(args) return getvalue()
return getvalue()
else:
pickler = Pickler(1)
pickler.fast = 1
dump = pickler.dump
def encode(*args):
return dump(args, 2)
return encode return encode
......
...@@ -32,24 +32,13 @@ def encode(*args): # args: (msgid, flags, name, args) ...@@ -32,24 +32,13 @@ def encode(*args): # args: (msgid, flags, name, args)
# being represented by \xij escapes in proto 0). # being represented by \xij escapes in proto 0).
# Undocumented: cPickle.Pickler accepts a lone protocol argument; # Undocumented: cPickle.Pickler accepts a lone protocol argument;
# pickle.py does not. # pickle.py does not.
if PY3: # XXX: Py3: Needs optimization.
# XXX: Py3: Needs optimization. f = BytesIO()
f = BytesIO() pickler = Pickler(f, 3)
pickler = Pickler(f, 3) pickler.fast = 1
pickler.fast = 1 pickler.dump(args)
pickler.dump(args) res = f.getvalue()
res = f.getvalue() return res
return res
else:
pickler = Pickler(1)
pickler.fast = 1
# Only CPython's cPickle supports dumping
# and returning in one operation:
# return pickler.dump(args, 1)
# For PyPy we must return the value; fortunately this
# works the same on CPython and is no more expensive
pickler.dump(args)
return pickler.getvalue()
......
...@@ -487,7 +487,9 @@ class ClientConflictResolutionTests( ...@@ -487,7 +487,9 @@ class ClientConflictResolutionTests(
return '<mappingstorage>\n</mappingstorage>\n' return '<mappingstorage>\n</mappingstorage>\n'
def getZEOConfig(self): def getZEOConfig(self):
return forker.ZEOConfig(('', 0), client_conflict_resolution=True) # Using '' can result in binding to :: and cause problems
# connecting to the MTAcceptor on Travis CI
return forker.ZEOConfig(('127.0.0.1', 0), client_conflict_resolution=True)
class MappingStorageTests(GenericTests): class MappingStorageTests(GenericTests):
"""ZEO backed by a Mapping storage.""" """ZEO backed by a Mapping storage."""
......
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