]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-117482: Expand Tests for Slot Wrappers of Inherited Slots of Static Builtin Types...
authorEric Snow <ericsnowcurrently@gmail.com>
Tue, 23 Jul 2024 19:57:26 +0000 (13:57 -0600)
committerGitHub <noreply@github.com>
Tue, 23 Jul 2024 19:57:26 +0000 (19:57 +0000)
Lib/test/test_embed.py
Lib/test/test_types.py

index 30dab1fbaa48b28f0ae1aa764e4229b5e813c643..fb7995e05152d2fdc2aa2d8b53942c14d31be1eb 100644 (file)
@@ -5,6 +5,7 @@ import unittest
 
 from collections import namedtuple
 import contextlib
+import io
 import json
 import os
 import os.path
@@ -415,6 +416,32 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
         out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
         self.assertEqual(out, '20000101\n' * INIT_LOOPS)
 
+    def test_static_types_inherited_slots(self):
+        slots = []
+        script = ['import sys']
+        from test.test_types import iter_builtin_types, iter_own_slot_wrappers
+        for cls in iter_builtin_types():
+            for slot in iter_own_slot_wrappers(cls):
+                slots.append((cls, slot))
+                attr = f'{cls.__name__}.{slot}'
+                script.append(f'print("{attr}:", {attr}, file=sys.stderr)')
+            script.append('')
+        script = os.linesep.join(script)
+
+        with contextlib.redirect_stderr(io.StringIO()) as stderr:
+            exec(script)
+        expected = stderr.getvalue().splitlines()
+
+        out, err = self.run_embedded_interpreter("test_repeated_init_exec", script)
+        results = err.split('--- Loop #')[1:]
+        results = [res.rpartition(' ---\n')[-1] for res in results]
+
+        self.maxDiff = None
+        for i, result in enumerate(results, start=1):
+            with self.subTest(loop=i):
+                self.assertEqual(result.splitlines(), expected)
+        self.assertEqual(out, '')
+
 
 @unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi")
 class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
index b89380da57884e59cc2817c3a79d25d59cc833a3..fb88daf9742fa9afd32b92cd8ba9b19865e0abc3 100644 (file)
@@ -29,6 +29,26 @@ def clear_typing_caches():
         f()
 
 
+def iter_builtin_types():
+    for obj in __builtins__.values():
+        if not isinstance(obj, type):
+            continue
+        cls = obj
+        if cls.__module__ != 'builtins':
+            continue
+        yield cls
+
+
+@cpython_only
+def iter_own_slot_wrappers(cls):
+    for name, value in vars(cls).items():
+        if not name.startswith('__') or not name.endswith('__'):
+            continue
+        if 'slot wrapper' not in str(value):
+            continue
+        yield name
+
+
 class TypesTests(unittest.TestCase):
 
     def test_truth_values(self):
@@ -2362,24 +2382,33 @@ class SubinterpreterTests(unittest.TestCase):
     def test_slot_wrappers(self):
         rch, sch = interpreters.channels.create()
 
-        # For now it's sufficient to check int.__str__.
-        # See https://github.com/python/cpython/issues/117482
-        # and https://github.com/python/cpython/pull/117660.
-        script = textwrap.dedent('''
-            text = repr(int.__str__)
-            sch.send_nowait(text)
-            ''')
+        slots = []
+        script = ''
+        for cls in iter_builtin_types():
+            for slot in iter_own_slot_wrappers(cls):
+                slots.append((cls, slot))
+                script += textwrap.dedent(f"""
+                    text = repr({cls.__name__}.{slot})
+                    sch.send_nowait(({cls.__name__!r}, {slot!r}, text))
+                    """)
 
         exec(script)
-        expected = rch.recv()
+        all_expected = []
+        for cls, slot in slots:
+            result = rch.recv()
+            assert result == (cls.__name__, slot, result[2]), (cls, slot, result)
+            all_expected.append(result)
 
         interp = interpreters.create()
         interp.exec('from test.support import interpreters')
         interp.prepare_main(sch=sch)
         interp.exec(script)
-        results = rch.recv()
 
-        self.assertEqual(results, expected)
+        for i, _ in enumerate(slots):
+            with self.subTest(cls=cls, slot=slot):
+                expected = all_expected[i]
+                result = rch.recv()
+                self.assertEqual(result, expected)
 
 
 if __name__ == '__main__':