|
1 | 1 | # Python test set -- part 6, built-in types
|
2 | 2 |
|
3 | 3 | from test.support import run_with_locale, cpython_only, MISSING_C_DOCSTRINGS
|
| 4 | +from test.test_import import no_rerun |
4 | 5 | import collections.abc
|
5 | 6 | from collections import namedtuple
|
6 | 7 | import copy
|
@@ -28,6 +29,26 @@ def clear_typing_caches():
|
28 | 29 | f()
|
29 | 30 |
|
30 | 31 |
|
| 32 | +def iter_builtin_types(): |
| 33 | + for obj in __builtins__.values(): |
| 34 | + if not isinstance(obj, type): |
| 35 | + continue |
| 36 | + cls = obj |
| 37 | + if cls.__module__ != 'builtins': |
| 38 | + continue |
| 39 | + yield cls |
| 40 | + |
| 41 | + |
| 42 | +@cpython_only |
| 43 | +def iter_own_slot_wrappers(cls): |
| 44 | + for name, value in vars(cls).items(): |
| 45 | + if not name.startswith('__') or not name.endswith('__'): |
| 46 | + continue |
| 47 | + if 'slot wrapper' not in str(value): |
| 48 | + continue |
| 49 | + yield name |
| 50 | + |
| 51 | + |
31 | 52 | class TypesTests(unittest.TestCase):
|
32 | 53 |
|
33 | 54 | def test_truth_values(self):
|
@@ -2264,27 +2285,39 @@ def setUpClass(cls):
|
2264 | 2285 | raise unittest.SkipTest('subinterpreters required')
|
2265 | 2286 |
|
2266 | 2287 | @cpython_only
|
| 2288 | + @no_rerun('channels (and queues) might have a refleak; see gh-122199') |
2267 | 2289 | def test_slot_wrappers(self):
|
2268 | 2290 | rch, sch = interpreters.create_channel()
|
2269 | 2291 |
|
2270 |
| - # For now it's sufficient to check int.__str__. |
2271 |
| - # See https://github.com/python/cpython/issues/117482 |
2272 |
| - # and https://github.com/python/cpython/pull/117660. |
2273 |
| - script = textwrap.dedent(f''' |
2274 |
| - text = repr(int.__str__) |
2275 |
| - sch = interpreters.SendChannel({sch.id}) |
2276 |
| - sch.send_nowait(text) |
2277 |
| - ''') |
| 2292 | + slots = [] |
| 2293 | + script = '' |
| 2294 | + for cls in iter_builtin_types(): |
| 2295 | + for slot in iter_own_slot_wrappers(cls): |
| 2296 | + slots.append((cls, slot)) |
| 2297 | + attr = f'{cls.__name__}.{slot}' |
| 2298 | + script += textwrap.dedent(f""" |
| 2299 | + sch.send_nowait('{attr}: ' + repr({attr})) |
| 2300 | + """) |
2278 | 2301 |
|
2279 | 2302 | exec(script)
|
2280 |
| - expected = rch.recv() |
| 2303 | + all_expected = [] |
| 2304 | + for cls, slot in slots: |
| 2305 | + result = rch.recv() |
| 2306 | + assert result.startswith(f'{cls.__name__}.{slot}: '), (cls, slot, result) |
| 2307 | + all_expected.append(result) |
2281 | 2308 |
|
2282 | 2309 | interp = interpreters.create()
|
2283 |
| - interp.run('from test.support import interpreters') |
| 2310 | + interp.run(textwrap.dedent(f""" |
| 2311 | + from test.support import interpreters |
| 2312 | + sch = interpreters.SendChannel({sch.id}) |
| 2313 | + """)) |
2284 | 2314 | interp.run(script)
|
2285 |
| - results = rch.recv() |
2286 | 2315 |
|
2287 |
| - self.assertEqual(results, expected) |
| 2316 | + for i, _ in enumerate(slots): |
| 2317 | + with self.subTest(cls=cls, slot=slot): |
| 2318 | + expected = all_expected[i] |
| 2319 | + result = rch.recv() |
| 2320 | + self.assertEqual(result, expected) |
2288 | 2321 |
|
2289 | 2322 |
|
2290 | 2323 | if __name__ == '__main__':
|
|
0 commit comments