mirror of
https://github.com/python/cpython.git
synced 2026-04-14 07:41:00 +00:00
[3.13] gh-77188: Add pickle tests for objects with slots (GH-144116) (GH-144120)
(cherry picked from commit cf71e34940)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
015b90dc02
commit
ac9715bf13
2 changed files with 116 additions and 2 deletions
|
|
@ -26,7 +26,7 @@ def __getinitargs__(self):
|
|||
E.__module__ = "__main__"
|
||||
|
||||
# Simple mutable object.
|
||||
class Object:
|
||||
class Object(object):
|
||||
pass
|
||||
|
||||
# Hashable immutable key object containing unheshable mutable data.
|
||||
|
|
@ -38,6 +38,43 @@ def __reduce__(self):
|
|||
# Shouldn't support the recursion itself
|
||||
return K, (self.value,)
|
||||
|
||||
class WithSlots(object):
|
||||
__slots__ = ('a', 'b')
|
||||
|
||||
class WithSlotsSubclass(WithSlots):
|
||||
__slots__ = ('c',)
|
||||
|
||||
class WithSlotsAndDict(object):
|
||||
__slots__ = ('a', '__dict__')
|
||||
|
||||
class WithPrivateAttrs(object):
|
||||
def __init__(self, a):
|
||||
self.__private = a
|
||||
def get(self):
|
||||
return self.__private
|
||||
|
||||
class WithPrivateAttrsSubclass(WithPrivateAttrs):
|
||||
def __init__(self, a, b):
|
||||
super().__init__(a)
|
||||
self.__private = b
|
||||
def get2(self):
|
||||
return self.__private
|
||||
|
||||
class WithPrivateSlots(object):
|
||||
__slots__ = ('__private',)
|
||||
def __init__(self, a):
|
||||
self.__private = a
|
||||
def get(self):
|
||||
return self.__private
|
||||
|
||||
class WithPrivateSlotsSubclass(WithPrivateSlots):
|
||||
__slots__ = ('__private',)
|
||||
def __init__(self, a, b):
|
||||
super().__init__(a)
|
||||
self.__private = b
|
||||
def get2(self):
|
||||
return self.__private
|
||||
|
||||
# For test_misc
|
||||
class myint(int):
|
||||
def __init__(self, x):
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
from test.support.import_helper import forget
|
||||
from test.support.os_helper import TESTFN
|
||||
from test.support import threading_helper
|
||||
from test.support.testcase import ExtraAssertions
|
||||
from test.support.warnings_helper import save_restore_warnings_filters
|
||||
from test import picklecommon
|
||||
from test.picklecommon import *
|
||||
|
|
@ -2023,7 +2024,7 @@ def check(code, exc):
|
|||
check(-2**1000, (OverflowError, struct.error))
|
||||
|
||||
|
||||
class AbstractPickleTests:
|
||||
class AbstractPickleTests(ExtraAssertions):
|
||||
# Subclass must define self.dumps, self.loads.
|
||||
|
||||
py_version = sys.version_info # for test_xpickle
|
||||
|
|
@ -3617,6 +3618,82 @@ def test_c_methods(self):
|
|||
with self.subTest(proto=proto, descr=descr):
|
||||
self.assertRaises(TypeError, self.dumps, descr, proto)
|
||||
|
||||
def test_object_with_attrs(self):
|
||||
obj = Object()
|
||||
obj.a = 1
|
||||
for proto in protocols:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.a, obj.a)
|
||||
|
||||
def test_object_with_slots(self):
|
||||
obj = WithSlots()
|
||||
obj.a = 1
|
||||
self.assertRaises(TypeError, self.dumps, obj, 0)
|
||||
self.assertRaises(TypeError, self.dumps, obj, 1)
|
||||
for proto in protocols[2:]:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.a, obj.a)
|
||||
self.assertNotHasAttr(unpickled, 'b')
|
||||
|
||||
obj = WithSlotsSubclass()
|
||||
obj.a = 1
|
||||
obj.c = 2
|
||||
self.assertRaises(TypeError, self.dumps, obj, 0)
|
||||
self.assertRaises(TypeError, self.dumps, obj, 1)
|
||||
for proto in protocols[2:]:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.a, obj.a)
|
||||
self.assertEqual(unpickled.c, obj.c)
|
||||
self.assertNotHasAttr(unpickled, 'b')
|
||||
|
||||
obj = WithSlotsAndDict()
|
||||
obj.a = 1
|
||||
obj.c = 2
|
||||
self.assertRaises(TypeError, self.dumps, obj, 0)
|
||||
self.assertRaises(TypeError, self.dumps, obj, 1)
|
||||
for proto in protocols[2:]:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.a, obj.a)
|
||||
self.assertEqual(unpickled.c, obj.c)
|
||||
self.assertEqual(unpickled.__dict__, obj.__dict__)
|
||||
self.assertNotHasAttr(unpickled, 'b')
|
||||
|
||||
def test_object_with_private_attrs(self):
|
||||
obj = WithPrivateAttrs(1)
|
||||
for proto in protocols:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.get(), obj.get())
|
||||
|
||||
obj = WithPrivateAttrsSubclass(1, 2)
|
||||
for proto in protocols:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.get(), obj.get())
|
||||
self.assertEqual(unpickled.get2(), obj.get2())
|
||||
|
||||
def test_object_with_private_slots(self):
|
||||
obj = WithPrivateSlots(1)
|
||||
self.assertRaises(TypeError, self.dumps, obj, 0)
|
||||
self.assertRaises(TypeError, self.dumps, obj, 1)
|
||||
for proto in protocols[2:]:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.get(), obj.get())
|
||||
|
||||
obj = WithPrivateSlotsSubclass(1, 2)
|
||||
self.assertRaises(TypeError, self.dumps, obj, 0)
|
||||
self.assertRaises(TypeError, self.dumps, obj, 1)
|
||||
for proto in protocols[2:]:
|
||||
with self.subTest(proto=proto):
|
||||
unpickled = self.loads(self.dumps(obj, proto))
|
||||
self.assertEqual(unpickled.get(), obj.get())
|
||||
self.assertEqual(unpickled.get2(), obj.get2())
|
||||
|
||||
def test_compat_pickle(self):
|
||||
if self.py_version < (3, 4):
|
||||
self.skipTest("doesn't work in Python < 3.4'")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue