mirror of
https://github.com/python/cpython.git
synced 2025-08-14 22:01:08 +00:00
[3.12] gh-117482: Expand Tests for Slot Wrappers of Inherited Slots of Static Builtin Types (gh-122197)
(cherry picked from commit 33d32faa58
, AKA gh-122192)
This commit is contained in:
parent
cde9a26eb5
commit
d7c67e0aca
2 changed files with 73 additions and 12 deletions
|
@ -5,6 +5,7 @@ import unittest
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import io
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -389,6 +390,33 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
|
out, err = self.run_embedded_interpreter("test_repeated_init_exec", code)
|
||||||
self.assertEqual(out, '9\n' * INIT_LOOPS)
|
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):
|
class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
||||||
maxDiff = 4096
|
maxDiff = 4096
|
||||||
UTF8_MODE_ERRORS = ('surrogatepass' if MS_WINDOWS else 'surrogateescape')
|
UTF8_MODE_ERRORS = ('surrogatepass' if MS_WINDOWS else 'surrogateescape')
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# Python test set -- part 6, built-in types
|
# Python test set -- part 6, built-in types
|
||||||
|
|
||||||
from test.support import run_with_locale, cpython_only, MISSING_C_DOCSTRINGS
|
from test.support import run_with_locale, cpython_only, MISSING_C_DOCSTRINGS
|
||||||
|
from test.test_import import no_rerun
|
||||||
import collections.abc
|
import collections.abc
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
import copy
|
import copy
|
||||||
|
@ -28,6 +29,26 @@ def clear_typing_caches():
|
||||||
f()
|
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):
|
class TypesTests(unittest.TestCase):
|
||||||
|
|
||||||
def test_truth_values(self):
|
def test_truth_values(self):
|
||||||
|
@ -2264,27 +2285,39 @@ class SubinterpreterTests(unittest.TestCase):
|
||||||
raise unittest.SkipTest('subinterpreters required')
|
raise unittest.SkipTest('subinterpreters required')
|
||||||
|
|
||||||
@cpython_only
|
@cpython_only
|
||||||
|
@no_rerun('channels (and queues) might have a refleak; see gh-122199')
|
||||||
def test_slot_wrappers(self):
|
def test_slot_wrappers(self):
|
||||||
rch, sch = interpreters.create_channel()
|
rch, sch = interpreters.create_channel()
|
||||||
|
|
||||||
# For now it's sufficient to check int.__str__.
|
slots = []
|
||||||
# See https://github.com/python/cpython/issues/117482
|
script = ''
|
||||||
# and https://github.com/python/cpython/pull/117660.
|
for cls in iter_builtin_types():
|
||||||
script = textwrap.dedent(f'''
|
for slot in iter_own_slot_wrappers(cls):
|
||||||
text = repr(int.__str__)
|
slots.append((cls, slot))
|
||||||
sch = interpreters.SendChannel({sch.id})
|
attr = f'{cls.__name__}.{slot}'
|
||||||
sch.send_nowait(text)
|
script += textwrap.dedent(f"""
|
||||||
''')
|
sch.send_nowait('{attr}: ' + repr({attr}))
|
||||||
|
""")
|
||||||
|
|
||||||
exec(script)
|
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 = 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)
|
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__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue