From ccf160dfbbb0ad419720e01acb819e4f77cd7610 Mon Sep 17 00:00:00 2001 From: Guilherme Leobas Date: Thu, 7 Aug 2025 03:10:56 -0300 Subject: [PATCH] gh-137463: Update `validate_abstract_methods` in `test_collections.py` (GH-137464) Update `validate_abstract_methods` in `test_collections.py` The test for missing abstract methods in `validate_abstract_methods` incorrectly attempted to instantiate the generated class `C` with an argument (`C(name)`), which always raises a `TypeError: C() takes no arguments`. Although the test originally passes, it passes for the wrong reason. This change makes the test correctly validate the enforcement of abstract methods in ABCs. (cherry picked from commit 5be872350d562e6c9987b09ff4b7bda80a2f9cd0) Co-authored-by: Guilherme Leobas --- Lib/test/test_collections.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index d9d61e5c2053e3..f33e4b3256a9b9 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -736,7 +736,7 @@ def validate_abstract_methods(self, abc, *names): stubs = methodstubs.copy() del stubs[name] C = type('C', (abc,), stubs) - self.assertRaises(TypeError, C, name) + self.assertRaises(TypeError, C) def validate_isinstance(self, abc, name): stub = lambda s, *args: 0 @@ -963,7 +963,7 @@ class AnextOnly: async def __anext__(self): raise StopAsyncIteration self.assertNotIsInstance(AnextOnly(), AsyncIterator) - self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') + self.validate_abstract_methods(AsyncIterator, '__anext__') def test_Iterable(self): # Check some non-iterables @@ -1159,7 +1159,7 @@ def test_Iterator(self): for x in samples: self.assertIsInstance(x, Iterator) self.assertIsSubclass(type(x), Iterator) - self.validate_abstract_methods(Iterator, '__next__', '__iter__') + self.validate_abstract_methods(Iterator, '__next__') # Issue 10565 class NextOnly: @@ -1843,8 +1843,7 @@ def test_Mapping(self): for sample in [dict]: self.assertIsInstance(sample(), Mapping) self.assertIsSubclass(sample, Mapping) - self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', - '__getitem__') + self.validate_abstract_methods(Mapping, '__iter__', '__len__', '__getitem__') class MyMapping(Mapping): def __len__(self): return 0 @@ -1859,7 +1858,7 @@ def test_MutableMapping(self): for sample in [dict]: self.assertIsInstance(sample(), MutableMapping) self.assertIsSubclass(sample, MutableMapping) - self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', + self.validate_abstract_methods(MutableMapping, '__iter__', '__len__', '__getitem__', '__setitem__', '__delitem__') def test_MutableMapping_subclass(self): @@ -1898,8 +1897,7 @@ def test_Sequence(self): self.assertIsInstance(memoryview(b""), Sequence) self.assertIsSubclass(memoryview, Sequence) self.assertIsSubclass(str, Sequence) - self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', - '__getitem__') + self.validate_abstract_methods(Sequence, '__len__', '__getitem__') def test_Sequence_mixins(self): class SequenceSubclass(Sequence): @@ -1954,8 +1952,8 @@ def test_MutableSequence(self): self.assertIsSubclass(sample, MutableSequence) self.assertIsSubclass(array.array, MutableSequence) self.assertNotIsSubclass(str, MutableSequence) - self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', - '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') + self.validate_abstract_methods(MutableSequence, '__len__', '__getitem__', + '__setitem__', '__delitem__', 'insert') def test_MutableSequence_mixins(self): # Test the mixins of MutableSequence by creating a minimal concrete