mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
cPickle.c: Full support for the new LONG1 and LONG4. Added comments.
Assorted code cleanups; e.g., sizeof(char) is 1 by definition, so there's no need to do things like multiply by sizeof(char) in hairy malloc arguments. Fixed an undetected-overflow bug in readline_file(). longobject.c: Fixed a really stupid bug in the new _PyLong_NumBits. pickle.py: Fixed stupid bug in save_long(): When proto is 2, it wrote LONG1 or LONG4, but forgot to return then -- it went on to append the proto 1 LONG opcode too. Fixed equally stupid cancelling bugs in load_long1() and load_long4(): they *returned* the unpickled long instead of pushing it on the stack. The return values were ignored. Tests passed before only because save_long() pickled the long twice. Fixed bugs in encode_long(). Noted that decode_long() is quadratic-time despite our hopes, because long(string, 16) is still quadratic-time in len(string). It's hex() that's linear-time. I don't know a way to make decode_long() linear-time in Python, short of maybe transforming the 256's-complement bytes into marshal's funky internal format, and letting marshal decode that. It would be more valuable to make long(string, 16) linear time. pickletester.py: Added a global "protocols" vector so tests can try all the protocols in a sane way. Changed test_ints() and test_unicode() to do so. Added a new test_long(), but the tail end of it is disabled because it "takes forever" under pickle.py (but runs very quickly under cPickle: cPickle proto 2 for longs is linear-time).
This commit is contained in:
parent
5bd2a79b22
commit
ee1a53cbb1
4 changed files with 227 additions and 41 deletions
|
@ -1,6 +1,11 @@
|
|||
import unittest
|
||||
from test.test_support import TestFailed, have_unicode, TESTFN
|
||||
|
||||
# Tests that try a number of pickle protocols should have a
|
||||
# for proto in protocols:
|
||||
# kind of outer loop. Bump the 3 to 4 if/when protocol 3 is invented.
|
||||
protocols = range(3)
|
||||
|
||||
class C:
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.__dict__, other.__dict__)
|
||||
|
@ -28,6 +33,9 @@ class metaclass(type):
|
|||
class use_metaclass(object):
|
||||
__metaclass__ = metaclass
|
||||
|
||||
# DATA and BINDATA are the protocol 0 and protocol 1 pickles of the object
|
||||
# returned by create_data().
|
||||
|
||||
# break into multiple strings to avoid confusing font-lock-mode
|
||||
DATA = """(lp1
|
||||
I0
|
||||
|
@ -210,20 +218,22 @@ class AbstractPickleTests(unittest.TestCase):
|
|||
def test_unicode(self):
|
||||
endcases = [unicode(''), unicode('<\\u>'), unicode('<\\\u1234>'),
|
||||
unicode('<\n>'), unicode('<\\>')]
|
||||
for u in endcases:
|
||||
p = self.dumps(u)
|
||||
u2 = self.loads(p)
|
||||
self.assertEqual(u2, u)
|
||||
for proto in protocols:
|
||||
for u in endcases:
|
||||
p = self.dumps(u, proto)
|
||||
u2 = self.loads(p)
|
||||
self.assertEqual(u2, u)
|
||||
|
||||
def test_ints(self):
|
||||
import sys
|
||||
n = sys.maxint
|
||||
while n:
|
||||
for expected in (-n, n):
|
||||
s = self.dumps(expected)
|
||||
n2 = self.loads(s)
|
||||
self.assertEqual(expected, n2)
|
||||
n = n >> 1
|
||||
for proto in protocols:
|
||||
n = sys.maxint
|
||||
while n:
|
||||
for expected in (-n, n):
|
||||
s = self.dumps(expected, proto)
|
||||
n2 = self.loads(s)
|
||||
self.assertEqual(expected, n2)
|
||||
n = n >> 1
|
||||
|
||||
def test_maxint64(self):
|
||||
maxint64 = (1L << 63) - 1
|
||||
|
@ -235,6 +245,34 @@ class AbstractPickleTests(unittest.TestCase):
|
|||
data = 'I' + str(maxint64) + 'JUNK\n.'
|
||||
self.assertRaises(ValueError, self.loads, data)
|
||||
|
||||
def test_long(self):
|
||||
for proto in protocols:
|
||||
# 256 bytes is where LONG4 begins
|
||||
for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
|
||||
nbase = 1L << nbits
|
||||
for npos in nbase-1, nbase, nbase+1:
|
||||
for n in npos, -npos:
|
||||
pickle = self.dumps(n, proto)
|
||||
got = self.loads(pickle)
|
||||
self.assertEqual(n, got)
|
||||
# Try a monster. This is quadratic-time in protos 0 & 1, so don't
|
||||
# bother with those.
|
||||
# XXX Damn. pickle.py is still quadratic-time here, due to
|
||||
# XXX long(string, 16). cPickle runs this in an eyeblink, but I
|
||||
# XXX gave up waiting for pickle.py to get beyond "loading". Giving
|
||||
# XXX up for now.
|
||||
return
|
||||
print "building long"
|
||||
nbase = long("deadbeeffeedface", 16)
|
||||
nbase += nbase << 1000000
|
||||
for n in nbase, -nbase:
|
||||
print "dumping"
|
||||
p = self.dumps(n, 2)
|
||||
print "loading"
|
||||
got = self.loads(p)
|
||||
print "checking"
|
||||
self.assertEqual(n, got)
|
||||
|
||||
def test_reduce(self):
|
||||
pass
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue