]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-117482: Expand Tests for Slot Wrappers of Inherited Slots of Static Builtin...
authorEric Snow <ericsnowcurrently@gmail.com>
Tue, 23 Jul 2024 21:17:51 +0000 (15:17 -0600)
committerGitHub <noreply@github.com>
Tue, 23 Jul 2024 21:17:51 +0000 (21:17 +0000)
(cherry picked from commit 33d32faa580fb776cb660e9cc8aa7e45c6c68c08, AKA gh-122192)

Lib/test/test_embed.py
Lib/test/test_types.py

index 24617ab24c69581e20fb3eb26b71713afd6942e7..de705abbc5cdd910f111440aa203a222bb107a02 100644 (file)
@@ -5,6 +5,7 @@ import unittest
 
 from collections import namedtuple
 import contextlib
+import io
 import json
 import os
 import os.path
@@ -389,6 +390,33 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
         out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
         self.assertEqual(out, '9\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, '')
+
+
 class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
     maxDiff = 4096
     UTF8_MODE_ERRORS = ('surrogatepass' if MS_WINDOWS else 'surrogateescape')
index ca41c76649ca992e514367c91d8cc3b2d162bb86..c3d08e5b13682e080aa48ea47f13ddeb8794b4ee 100644 (file)
@@ -1,6 +1,7 @@
 # Python test set -- part 6, built-in types
 
 from test.support import run_with_locale, cpython_only, MISSING_C_DOCSTRINGS
+from test.test_import import no_rerun
 import collections.abc
 from collections import namedtuple
 import copy
@@ -28,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):
@@ -2264,27 +2285,39 @@ class SubinterpreterTests(unittest.TestCase):
             raise unittest.SkipTest('subinterpreters required')
 
     @cpython_only
+    @no_rerun('channels (and queues) might have a refleak; see gh-122199')
     def test_slot_wrappers(self):
         rch, sch = interpreters.create_channel()
 
-        # 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(f'''
-            text = repr(int.__str__)
-            sch = interpreters.SendChannel({sch.id})
-            sch.send_nowait(text)
-            ''')
+        slots = []
+        script = ''
+        for cls in iter_builtin_types():
+            for slot in iter_own_slot_wrappers(cls):
+                slots.append((cls, slot))
+                attr = f'{cls.__name__}.{slot}'
+                script += textwrap.dedent(f"""
+                    sch.send_nowait('{attr}: ' + repr({attr}))
+                    """)
 
         exec(script)
-        expected = rch.recv()
+        all_expected = []
+        for cls, slot in slots:
+            result = rch.recv()
+            assert result.startswith(f'{cls.__name__}.{slot}: '), (cls, slot, result)
+            all_expected.append(result)
 
         interp = interpreters.create()
-        interp.run('from test.support import interpreters')
+        interp.run(textwrap.dedent(f"""
+            from test.support import interpreters
+            sch = interpreters.SendChannel({sch.id})
+            """))
         interp.run(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__':