Skip to content

Commit

Permalink
pythongh-117482: Expand Tests for Slot Wrappers of Inherited Slots of…
Browse files Browse the repository at this point in the history
… Static Builtin Types (pythongh-122192)
  • Loading branch information
ericsnowcurrently committed Jul 23, 2024
1 parent 9d996b5 commit 34cb17d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 12 deletions.
28 changes: 28 additions & 0 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from collections import namedtuple
import contextlib
import io
import json
import os
import os.path
Expand Down Expand Up @@ -389,6 +390,33 @@ def test_ucnhash_capi_reset(self):
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')
Expand Down
55 changes: 43 additions & 12 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,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):
Expand Down Expand Up @@ -2267,24 +2287,35 @@ def setUpClass(cls):
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__':
Expand Down

0 comments on commit 34cb17d

Please sign in to comment.