diff options
author | Guido van Rossum <guido@python.org> | 2003-01-29 17:58:45 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2003-01-29 17:58:45 (GMT) |
commit | 5d9113d8be81596bc93f2b1a37f57e5110d39a77 (patch) | |
tree | f7bdf7fc9aa5afbf967e9e110baea0e4cdd9ffec /Lib | |
parent | d3590f937f4493445beeb253e5048771d1663ab7 (diff) | |
download | cpython-5d9113d8be81596bc93f2b1a37f57e5110d39a77.zip cpython-5d9113d8be81596bc93f2b1a37f57e5110d39a77.tar.gz cpython-5d9113d8be81596bc93f2b1a37f57e5110d39a77.tar.bz2 |
Implement appropriate __getnewargs__ for all immutable subclassable builtin
types. The special handling for these can now be removed from save_newobj().
Add some testing for this.
Also add support for setting the 'fast' flag on the Python Pickler class,
which suppresses use of the memo.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/pickle.py | 12 | ||||
-rw-r--r-- | Lib/test/pickletester.py | 46 | ||||
-rw-r--r-- | Lib/test/test_pickle.py | 18 |
3 files changed, 61 insertions, 15 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py index e36e6a6..739c24f 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -191,6 +191,7 @@ class Pickler: self.memo = {} self.proto = int(proto) self.bin = proto >= 1 + self.fast = 0 def clear_memo(self): """Clears the pickler's "memo". @@ -230,6 +231,8 @@ class Pickler: # But there appears no advantage to any other scheme, and this # scheme allows the Unpickler memo to be implemented as a plain (but # growable) array, indexed by memo key. + if self.fast: + return memo_len = len(self.memo) self.write(self.put(memo_len)) self.memo[id(obj)] = memo_len, obj @@ -378,14 +381,7 @@ class Pickler: if getnewargs: args = getnewargs() # This bette not reference obj else: - # XXX These types should each grow a __getnewargs__ - # implementation so this special-casing is unnecessary. - for cls in int, long, float, complex, str, UnicodeType, tuple: - if cls and isinstance(obj, cls): - args = (cls(obj),) - break - else: - args = () + args = () save = self.save write = self.write diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 33b96e5..ed0e436 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -324,6 +324,21 @@ class AbstractPickleTests(unittest.TestCase): ## print ## pickletools.dis(s) + def test_newobj_generic(self): + for proto in [0, 1, 2]: + for C in myclasses: + B = C.__base__ + x = C(C.sample) + x.foo = 42 + s = self.dumps(x, proto) +## import pickletools +## print +## pickletools.dis(s) + y = self.loads(s) + detail = (proto, C, B, x, y, type(y)) + self.assertEqual(B(x), B(y), detail) + self.assertEqual(x.__dict__, y.__dict__, detail) + # XXX Temporary hack, so long as the C implementation of pickle protocol # XXX 2 isn't ready. When it is, move the methods in TempAbstractPickleTests # XXX into AbstractPickleTests above, and get rid of TempAbstractPickleTests @@ -405,11 +420,38 @@ class TempAbstractPickleTests(unittest.TestCase): finally: copy_reg.remove_extension(__name__, "MyList", 0xfffff0) +class MyInt(int): + sample = 1 + +class MyLong(long): + sample = 1L + +class MyFloat(float): + sample = 1.0 + +class MyComplex(complex): + sample = 1.0 + 0.0j + +class MyStr(str): + sample = "hello" + +class MyUnicode(unicode): + sample = u"hello \u1234" + class MyTuple(tuple): - pass + sample = (1, 2, 3) class MyList(list): - pass + sample = [1, 2, 3] + +class MyDict(dict): + sample = {"a": 1, "b": 2} + +myclasses = [MyInt, MyLong, MyFloat, + # MyComplex, # XXX complex somehow doesn't work here :-( + MyStr, MyUnicode, + MyTuple, MyList, MyDict] + class SlotList(MyList): __slots__ = ["foo"] diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index d30e084..8870904 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -11,9 +11,13 @@ from test.pickletester import AbstractPersistentPicklerTests class PickleTests(AbstractPickleTests, AbstractPickleModuleTests, XXXTemp): - def setUp(self): - self.dumps = pickle.dumps - self.loads = pickle.loads + def dumps(self, arg, proto=0, fast=0): + # Ignore fast + return pickle.dumps(arg, proto) + + def loads(self, buf): + # Ignore fast + return pickle.loads(buf) module = pickle error = KeyError @@ -22,9 +26,11 @@ class PicklerTests(AbstractPickleTests): error = KeyError - def dumps(self, arg, proto=0): + def dumps(self, arg, proto=0, fast=0): f = StringIO() p = pickle.Pickler(f, proto) + if fast: + p.fast = fast p.dump(arg) f.seek(0) return f.read() @@ -36,12 +42,14 @@ class PicklerTests(AbstractPickleTests): class PersPicklerTests(AbstractPersistentPicklerTests): - def dumps(self, arg, proto=0): + def dumps(self, arg, proto=0, fast=0): class PersPickler(pickle.Pickler): def persistent_id(subself, obj): return self.persistent_id(obj) f = StringIO() p = PersPickler(f, proto) + if fast: + p.fast = fast p.dump(arg) f.seek(0) return f.read() |