Align frozendict copy support and tests with CPython 3.15

Import exact-final copy.py with update_lib; defer Mapping ABC registration to the later library stage. Generate only proven marker corrections, retain observed debug recursion-limit expected failures, and copy the complete canonical builtin-doc discovery test using hash-pinned update_lib copy-test.

Assisted-by: OpenAI Codex:model identifier unavailable
This commit is contained in:
dot committed 2026-10-13 14:26:12 +09:00
1 parent 4880699d23
commit 691a3586d4
7 files changed
+39 -19

No files matched your search

Vendored
+25 -10
View File
@@ -100,14 +100,14 @@ def copy(x):
return _reconstruct(x, None, *rv)
_copy_atomic_types = {types.NoneType, int, float, bool, complex, str, tuple,
bytes, frozenset, type, range, slice, property,
_copy_atomic_types = frozenset({types.NoneType, int, float, bool, complex, str, tuple,
bytes, frozendict, frozenset, type, range, slice, property,
types.BuiltinFunctionType, types.EllipsisType,
types.NotImplementedType, types.FunctionType, types.CodeType,
weakref.ref, super}
_copy_builtin_containers = {list, dict, set, bytearray}
weakref.ref, super})
_copy_builtin_containers = frozenset({list, dict, set, bytearray})
def deepcopy(x, memo=None, _nil=[]):
def deepcopy(x, memo=None):
"""Deep copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
@@ -122,8 +122,8 @@ def deepcopy(x, memo=None, _nil=[]):
if memo is None:
memo = {}
else:
y = memo.get(d, _nil)
if y is not _nil:
y = memo.get(d, None)
if y is not None:
return y
copier = _deepcopy_dispatch.get(cls)
@@ -162,9 +162,9 @@ 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,
_atomic_types = frozenset({types.NoneType, types.EllipsisType, types.NotImplementedType,
int, float, bool, complex, bytes, str, types.CodeType, type, range,
types.BuiltinFunctionType, types.FunctionType, weakref.ref, property}
types.BuiltinFunctionType, types.FunctionType, weakref.ref, property})
_deepcopy_dispatch = d = {}
@@ -203,6 +203,21 @@ def _deepcopy_dict(x, memo, deepcopy=deepcopy):
return y
d[dict] = _deepcopy_dict
def _deepcopy_frozendict(x, memo, deepcopy=deepcopy):
y = {}
for key, value in x.items():
y[deepcopy(key, memo)] = deepcopy(value, memo)
# We're not going to put the frozendict in the memo, but it's still
# important we check for it, in case the frozendict contains recursive
# mutable structures.
try:
return memo[id(x)]
except KeyError:
pass
return frozendict(y)
d[frozendict] = _deepcopy_frozendict
def _deepcopy_method(x, memo): # Copy instance methods
return type(x)(x.__func__, deepcopy(x.__self__, memo))
d[types.MethodType] = _deepcopy_method
@@ -230,7 +245,7 @@ def _reconstruct(x, memo, func, args,
*, deepcopy=deepcopy):
deep = memo is not None
if deep and args:
args = (deepcopy(arg, memo) for arg in args)
args = [deepcopy(arg, memo) for arg in args]
y = func(*args)
if deep:
memo[id(x)] = y
-4
View File
@@ -4394,8 +4394,6 @@ class AbstractPickleTests:
def test_fast_save_enter_set(self):
self.fast_save_enter(lambda i: set([i]))
# TODO: RUSTPYTHON; frozendict support: https://github.com/RustPython/RustPython/pull/8951
@unittest.expectedFailure
def test_fast_save_enter_frozendict(self):
if self.py_version < (3, 15):
self.skipTest('need frozendict')
@@ -4443,8 +4441,6 @@ class AbstractPickleTests:
depth=FAST_NESTING_LIMIT+1,
compare_equal=False)
# TODO: RUSTPYTHON; frozendict support: https://github.com/RustPython/RustPython/pull/8951
@unittest.expectedFailure
def test_deep_nested_struct_frozendict(self):
if self.py_version < (3, 15):
self.skipTest('need frozendict')
-2
View File
@@ -951,7 +951,6 @@ class DictTest(unittest.TestCase):
'f': None, 'g': None, 'h': None}
d = {}
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_container_iterator(self):
# Bug #3680: tp_traverse was not implemented for dictiter and
# dictview objects.
@@ -1264,7 +1263,6 @@ class DictTest(unittest.TestCase):
support.check_free_after_iterating(self, lambda d: iter(d.values()), dict)
support.check_free_after_iterating(self, lambda d: iter(d.items()), dict)
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_equal_operator_modifying_operand(self):
# test fix for seg fault reported in bpo-27945 part 3.
class X():
+1 -1
View File
@@ -742,7 +742,7 @@ plain ol' Python and is guaranteed to be available.
>>> import builtins
>>> tests = doctest.DocTestFinder().find(builtins)
>>> 750 < len(tests) < 800 # approximate number of objects with docstrings
>>> 750 < len(tests) < 850 # approximate number of objects with docstrings
True
>>> real_tests = [t for t in tests if len(t.examples) > 0]
>>> len(real_tests) # objects that actually have doctests
+1 -1
View File
@@ -135,7 +135,7 @@ class RebindBuiltinsTests(unittest.TestCase):
self.assertEqual(foo(), 7)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailureIf(sys.getrecursionlimit() == 256, "TODO: RUSTPYTHON; default debug recursion limit is 256")
@skip_wasi_stack_overflow()
def test_load_global_specialization_failure_keeps_oparg(self):
# https://github.com/python/cpython/issues/91625
+12
View File
@@ -107,6 +107,10 @@ class PyPicklerTests(AbstractPickleTests, unittest.TestCase):
def test_c_methods(self):
return super().test_c_methods()
@unittest.expectedFailureIf(sys.getrecursionlimit() == 256, "TODO: RUSTPYTHON; default debug recursion limit is 256")
def test_deep_nested_struct_frozendict(self):
return super().test_deep_nested_struct_frozendict()
@@ -408,6 +412,10 @@ if has_c_implementation:
pickler = _pickle.Pickler
unpickler = _pickle.Unpickler
@unittest.expectedSuccess # TODO: RUSTPYTHON; native pickler passes at the default debug recursion limit
def test_deep_nested_struct_frozendict(self):
return super().test_deep_nested_struct_frozendict()
class CPersPicklerTests(PyPersPicklerTests):
pickler = _pickle.Pickler
unpickler = _pickle.Unpickler
@@ -421,6 +429,10 @@ if has_c_implementation:
pickler = _pickle.Pickler
unpickler = pickle._Unpickler
@unittest.expectedSuccess # TODO: RUSTPYTHON; native pickler passes at the default debug recursion limit
def test_deep_nested_struct_frozendict(self):
return super().test_deep_nested_struct_frozendict()
class DumpPickle_CLoadPickle(PyPicklerTests):
pickler = pickle._Pickler
unpickler = _pickle.Unpickler
-1
View File
@@ -45,7 +45,6 @@ class AnyTest(unittest.TestCase):
mock.assert_called_with(ANY, foo=ANY)
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_any_mock_calls_comparison_order(self):
mock = Mock()
class Foo(object):