mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update copy module and test_copy from CPython v3.14.3 (#7062)
This commit is contained in:
1 parent
3910f5f71a
commit
725ffafd13
2 files changed
+27
-45
No files matched your search
Vendored
+19
-39
@@ -67,13 +67,15 @@ def copy(x):
|
||||
|
||||
cls = type(x)
|
||||
|
||||
copier = _copy_dispatch.get(cls)
|
||||
if copier:
|
||||
return copier(x)
|
||||
if cls in _copy_atomic_types:
|
||||
return x
|
||||
if cls in _copy_builtin_containers:
|
||||
return cls.copy(x)
|
||||
|
||||
|
||||
if issubclass(cls, type):
|
||||
# treat it as a regular class:
|
||||
return _copy_immutable(x)
|
||||
return x
|
||||
|
||||
copier = getattr(cls, "__copy__", None)
|
||||
if copier is not None:
|
||||
@@ -98,23 +100,12 @@ def copy(x):
|
||||
return _reconstruct(x, None, *rv)
|
||||
|
||||
|
||||
_copy_dispatch = d = {}
|
||||
|
||||
def _copy_immutable(x):
|
||||
return x
|
||||
for t in (types.NoneType, int, float, bool, complex, str, tuple,
|
||||
_copy_atomic_types = {types.NoneType, int, float, bool, complex, str, tuple,
|
||||
bytes, frozenset, type, range, slice, property,
|
||||
types.BuiltinFunctionType, types.EllipsisType,
|
||||
types.NotImplementedType, types.FunctionType, types.CodeType,
|
||||
weakref.ref):
|
||||
d[t] = _copy_immutable
|
||||
|
||||
d[list] = list.copy
|
||||
d[dict] = dict.copy
|
||||
d[set] = set.copy
|
||||
d[bytearray] = bytearray.copy
|
||||
|
||||
del d, t
|
||||
weakref.ref, super}
|
||||
_copy_builtin_containers = {list, dict, set, bytearray}
|
||||
|
||||
def deepcopy(x, memo=None, _nil=[]):
|
||||
"""Deep copy operation on arbitrary Python objects.
|
||||
@@ -122,6 +113,11 @@ def deepcopy(x, memo=None, _nil=[]):
|
||||
See the module's __doc__ string for more info.
|
||||
"""
|
||||
|
||||
cls = type(x)
|
||||
|
||||
if cls in _atomic_types:
|
||||
return x
|
||||
|
||||
d = id(x)
|
||||
if memo is None:
|
||||
memo = {}
|
||||
@@ -130,14 +126,12 @@ def deepcopy(x, memo=None, _nil=[]):
|
||||
if y is not _nil:
|
||||
return y
|
||||
|
||||
cls = type(x)
|
||||
|
||||
copier = _deepcopy_dispatch.get(cls)
|
||||
if copier is not None:
|
||||
y = copier(x, memo)
|
||||
else:
|
||||
if issubclass(cls, type):
|
||||
y = _deepcopy_atomic(x, memo)
|
||||
y = x # atomic copy
|
||||
else:
|
||||
copier = getattr(x, "__deepcopy__", None)
|
||||
if copier is not None:
|
||||
@@ -168,26 +162,12 @@ def deepcopy(x, memo=None, _nil=[]):
|
||||
_keep_alive(x, memo) # Make sure x lives at least as long as d
|
||||
return y
|
||||
|
||||
_atomic_types = {types.NoneType, types.EllipsisType, types.NotImplementedType,
|
||||
int, float, bool, complex, bytes, str, types.CodeType, type, range,
|
||||
types.BuiltinFunctionType, types.FunctionType, weakref.ref, property}
|
||||
|
||||
_deepcopy_dispatch = d = {}
|
||||
|
||||
def _deepcopy_atomic(x, memo):
|
||||
return x
|
||||
d[types.NoneType] = _deepcopy_atomic
|
||||
d[types.EllipsisType] = _deepcopy_atomic
|
||||
d[types.NotImplementedType] = _deepcopy_atomic
|
||||
d[int] = _deepcopy_atomic
|
||||
d[float] = _deepcopy_atomic
|
||||
d[bool] = _deepcopy_atomic
|
||||
d[complex] = _deepcopy_atomic
|
||||
d[bytes] = _deepcopy_atomic
|
||||
d[str] = _deepcopy_atomic
|
||||
d[types.CodeType] = _deepcopy_atomic
|
||||
d[type] = _deepcopy_atomic
|
||||
d[range] = _deepcopy_atomic
|
||||
d[types.BuiltinFunctionType] = _deepcopy_atomic
|
||||
d[types.FunctionType] = _deepcopy_atomic
|
||||
d[weakref.ref] = _deepcopy_atomic
|
||||
d[property] = _deepcopy_atomic
|
||||
|
||||
def _deepcopy_list(x, memo, deepcopy=deepcopy):
|
||||
y = []
|
||||
|
||||
Vendored
+8
-6
@@ -19,7 +19,7 @@ class TestCopy(unittest.TestCase):
|
||||
|
||||
def test_exceptions(self):
|
||||
self.assertIs(copy.Error, copy.error)
|
||||
self.assertTrue(issubclass(copy.Error, Exception))
|
||||
self.assertIsSubclass(copy.Error, Exception)
|
||||
|
||||
# The copy() method
|
||||
|
||||
@@ -371,6 +371,8 @@ class TestCopy(unittest.TestCase):
|
||||
self.assertIsNot(x, y)
|
||||
self.assertIsNot(x[0], y[0])
|
||||
|
||||
@support.skip_emscripten_stack_overflow()
|
||||
@support.skip_wasi_stack_overflow()
|
||||
def test_deepcopy_reflexive_list(self):
|
||||
x = []
|
||||
x.append(x)
|
||||
@@ -398,6 +400,8 @@ class TestCopy(unittest.TestCase):
|
||||
y = copy.deepcopy(x)
|
||||
self.assertIs(x, y)
|
||||
|
||||
@support.skip_emscripten_stack_overflow()
|
||||
@support.skip_wasi_stack_overflow()
|
||||
def test_deepcopy_reflexive_tuple(self):
|
||||
x = ([],)
|
||||
x[0].append(x)
|
||||
@@ -415,6 +419,8 @@ class TestCopy(unittest.TestCase):
|
||||
self.assertIsNot(x, y)
|
||||
self.assertIsNot(x["foo"], y["foo"])
|
||||
|
||||
@support.skip_emscripten_stack_overflow()
|
||||
@support.skip_wasi_stack_overflow()
|
||||
def test_deepcopy_reflexive_dict(self):
|
||||
x = {}
|
||||
x['foo'] = x
|
||||
@@ -666,7 +672,7 @@ class TestCopy(unittest.TestCase):
|
||||
def test_reduce_5tuple(self):
|
||||
class C(dict):
|
||||
def __reduce__(self):
|
||||
return (C, (), self.__dict__, None, self.items())
|
||||
return (C, (), self.__dict__, None, iter(self.items()))
|
||||
def __eq__(self, other):
|
||||
return (dict(self) == dict(other) and
|
||||
self.__dict__ == other.__dict__)
|
||||
@@ -837,15 +843,12 @@ class TestCopy(unittest.TestCase):
|
||||
v[x] = y
|
||||
self.assertNotIn(x, u)
|
||||
|
||||
|
||||
def test_copy_weakkeydict(self):
|
||||
self._check_copy_weakdict(weakref.WeakKeyDictionary)
|
||||
|
||||
|
||||
def test_copy_weakvaluedict(self):
|
||||
self._check_copy_weakdict(weakref.WeakValueDictionary)
|
||||
|
||||
|
||||
def test_deepcopy_weakkeydict(self):
|
||||
class C(object):
|
||||
def __init__(self, i):
|
||||
@@ -866,7 +869,6 @@ class TestCopy(unittest.TestCase):
|
||||
support.gc_collect() # For PyPy or other GCs.
|
||||
self.assertEqual(len(v), 1)
|
||||
|
||||
|
||||
def test_deepcopy_weakvaluedict(self):
|
||||
class C(object):
|
||||
def __init__(self, i):
|
||||
|
||||
Reference in new issue
Block a user