Skip to content

Commit 857d315

Browse files
gh-76785: Consolidate Some Interpreter-related Testing Helpers (gh-117485)
This eliminates the duplication of functionally identical helpers in the _testinternalcapi and _xxsubinterpreters modules.
1 parent f341d60 commit 857d315

File tree

10 files changed

+526
-312
lines changed

10 files changed

+526
-312
lines changed

Lib/test/support/interpreters/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def __str__(self):
7373

7474
def create():
7575
"""Return a new (idle) Python interpreter."""
76-
id = _interpreters.create(isolated=True)
76+
id = _interpreters.create(reqrefs=True)
7777
return Interpreter(id)
7878

7979

@@ -109,13 +109,13 @@ def __new__(cls, id, /):
109109
assert hasattr(self, '_ownsref')
110110
except KeyError:
111111
# This may raise InterpreterNotFoundError:
112-
_interpreters._incref(id)
112+
_interpreters.incref(id)
113113
try:
114114
self = super().__new__(cls)
115115
self._id = id
116116
self._ownsref = True
117117
except BaseException:
118-
_interpreters._deccref(id)
118+
_interpreters.decref(id)
119119
raise
120120
_known[id] = self
121121
return self
@@ -142,7 +142,7 @@ def _decref(self):
142142
return
143143
self._ownsref = False
144144
try:
145-
_interpreters._decref(self.id)
145+
_interpreters.decref(self.id)
146146
except InterpreterNotFoundError:
147147
pass
148148

Lib/test/test__xxsubinterpreters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ def f():
584584
def test_create_daemon_thread(self):
585585
with self.subTest('isolated'):
586586
expected = 'spam spam spam spam spam'
587-
subinterp = interpreters.create(isolated=True)
587+
subinterp = interpreters.create('isolated')
588588
script, file = _captured_script(f"""
589589
import threading
590590
def f():
@@ -604,7 +604,7 @@ def f():
604604
self.assertEqual(out, expected)
605605

606606
with self.subTest('not isolated'):
607-
subinterp = interpreters.create(isolated=False)
607+
subinterp = interpreters.create('legacy')
608608
script, file = _captured_script("""
609609
import threading
610610
def f():

Lib/test/test_capi/test_misc.py

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,6 +2204,7 @@ def test_module_state_shared_in_global(self):
22042204
self.assertEqual(main_attr_id, subinterp_attr_id)
22052205

22062206

2207+
@requires_subinterpreters
22072208
class InterpreterConfigTests(unittest.TestCase):
22082209

22092210
supported = {
@@ -2277,11 +2278,11 @@ def check(name, expected):
22772278
expected = self.supported[expected]
22782279
args = (name,) if name else ()
22792280

2280-
config1 = _testinternalcapi.new_interp_config(*args)
2281+
config1 = _interpreters.new_config(*args)
22812282
self.assert_ns_equal(config1, expected)
22822283
self.assertIsNot(config1, expected)
22832284

2284-
config2 = _testinternalcapi.new_interp_config(*args)
2285+
config2 = _interpreters.new_config(*args)
22852286
self.assert_ns_equal(config2, expected)
22862287
self.assertIsNot(config2, expected)
22872288
self.assertIsNot(config2, config1)
@@ -2298,7 +2299,7 @@ def test_update_from_dict(self):
22982299
with self.subTest(f'noop ({name})'):
22992300
expected = vanilla
23002301
overrides = vars(vanilla)
2301-
config = _testinternalcapi.new_interp_config(name, **overrides)
2302+
config = _interpreters.new_config(name, **overrides)
23022303
self.assert_ns_equal(config, expected)
23032304

23042305
with self.subTest(f'change all ({name})'):
@@ -2308,7 +2309,7 @@ def test_update_from_dict(self):
23082309
continue
23092310
overrides['gil'] = gil
23102311
expected = types.SimpleNamespace(**overrides)
2311-
config = _testinternalcapi.new_interp_config(
2312+
config = _interpreters.new_config(
23122313
name, **overrides)
23132314
self.assert_ns_equal(config, expected)
23142315

@@ -2324,14 +2325,14 @@ def test_update_from_dict(self):
23242325
expected = types.SimpleNamespace(
23252326
**dict(vars(vanilla), **overrides),
23262327
)
2327-
config = _testinternalcapi.new_interp_config(
2328+
config = _interpreters.new_config(
23282329
name, **overrides)
23292330
self.assert_ns_equal(config, expected)
23302331

23312332
with self.subTest('unsupported field'):
23322333
for name in self.supported:
23332334
with self.assertRaises(ValueError):
2334-
_testinternalcapi.new_interp_config(name, spam=True)
2335+
_interpreters.new_config(name, spam=True)
23352336

23362337
# Bad values for bool fields.
23372338
for field, value in vars(self.supported['empty']).items():
@@ -2341,19 +2342,18 @@ def test_update_from_dict(self):
23412342
for value in [1, '', 'spam', 1.0, None, object()]:
23422343
with self.subTest(f'unsupported value ({field}={value!r})'):
23432344
with self.assertRaises(TypeError):
2344-
_testinternalcapi.new_interp_config(**{field: value})
2345+
_interpreters.new_config(**{field: value})
23452346

23462347
# Bad values for .gil.
23472348
for value in [True, 1, 1.0, None, object()]:
23482349
with self.subTest(f'unsupported value(gil={value!r})'):
23492350
with self.assertRaises(TypeError):
2350-
_testinternalcapi.new_interp_config(gil=value)
2351+
_interpreters.new_config(gil=value)
23512352
for value in ['', 'spam']:
23522353
with self.subTest(f'unsupported value (gil={value!r})'):
23532354
with self.assertRaises(ValueError):
2354-
_testinternalcapi.new_interp_config(gil=value)
2355+
_interpreters.new_config(gil=value)
23552356

2356-
@requires_subinterpreters
23572357
def test_interp_init(self):
23582358
questionable = [
23592359
# strange
@@ -2412,11 +2412,10 @@ def check(config):
24122412
with self.subTest(f'valid: {config}'):
24132413
check(config)
24142414

2415-
@requires_subinterpreters
24162415
def test_get_config(self):
24172416
@contextlib.contextmanager
24182417
def new_interp(config):
2419-
interpid = _testinternalcapi.new_interpreter(config)
2418+
interpid = _interpreters.create(config, reqrefs=False)
24202419
try:
24212420
yield interpid
24222421
finally:
@@ -2426,32 +2425,32 @@ def new_interp(config):
24262425
pass
24272426

24282427
with self.subTest('main'):
2429-
expected = _testinternalcapi.new_interp_config('legacy')
2428+
expected = _interpreters.new_config('legacy')
24302429
expected.gil = 'own'
24312430
interpid = _interpreters.get_main()
2432-
config = _testinternalcapi.get_interp_config(interpid)
2431+
config = _interpreters.get_config(interpid)
24332432
self.assert_ns_equal(config, expected)
24342433

24352434
with self.subTest('isolated'):
2436-
expected = _testinternalcapi.new_interp_config('isolated')
2435+
expected = _interpreters.new_config('isolated')
24372436
with new_interp('isolated') as interpid:
2438-
config = _testinternalcapi.get_interp_config(interpid)
2437+
config = _interpreters.get_config(interpid)
24392438
self.assert_ns_equal(config, expected)
24402439

24412440
with self.subTest('legacy'):
2442-
expected = _testinternalcapi.new_interp_config('legacy')
2441+
expected = _interpreters.new_config('legacy')
24432442
with new_interp('legacy') as interpid:
2444-
config = _testinternalcapi.get_interp_config(interpid)
2443+
config = _interpreters.get_config(interpid)
24452444
self.assert_ns_equal(config, expected)
24462445

24472446
with self.subTest('custom'):
2448-
orig = _testinternalcapi.new_interp_config(
2447+
orig = _interpreters.new_config(
24492448
'empty',
24502449
use_main_obmalloc=True,
24512450
gil='shared',
24522451
)
24532452
with new_interp(orig) as interpid:
2454-
config = _testinternalcapi.get_interp_config(interpid)
2453+
config = _interpreters.get_config(interpid)
24552454
self.assert_ns_equal(config, orig)
24562455

24572456

@@ -2529,14 +2528,19 @@ def test_lookup_destroyed(self):
25292528
self.assertFalse(
25302529
_testinternalcapi.interpreter_exists(interpid))
25312530

2531+
def get_refcount_helpers(self):
2532+
return (
2533+
_testinternalcapi.get_interpreter_refcount,
2534+
(lambda id: _interpreters.incref(id, implieslink=False)),
2535+
_interpreters.decref,
2536+
)
2537+
25322538
def test_linked_lifecycle_does_not_exist(self):
25332539
exists = _testinternalcapi.interpreter_exists
25342540
is_linked = _testinternalcapi.interpreter_refcount_linked
25352541
link = _testinternalcapi.link_interpreter_refcount
25362542
unlink = _testinternalcapi.unlink_interpreter_refcount
2537-
get_refcount = _testinternalcapi.get_interpreter_refcount
2538-
incref = _testinternalcapi.interpreter_incref
2539-
decref = _testinternalcapi.interpreter_decref
2543+
get_refcount, incref, decref = self.get_refcount_helpers()
25402544

25412545
with self.subTest('never existed'):
25422546
interpid = _testinternalcapi.unused_interpreter_id()
@@ -2578,8 +2582,7 @@ def test_linked_lifecycle_initial(self):
25782582
get_refcount = _testinternalcapi.get_interpreter_refcount
25792583

25802584
# A new interpreter will start out not linked, with a refcount of 0.
2581-
interpid = _testinternalcapi.new_interpreter()
2582-
self.add_interp_cleanup(interpid)
2585+
interpid = self.new_interpreter()
25832586
linked = is_linked(interpid)
25842587
refcount = get_refcount(interpid)
25852588

@@ -2589,12 +2592,9 @@ def test_linked_lifecycle_initial(self):
25892592
def test_linked_lifecycle_never_linked(self):
25902593
exists = _testinternalcapi.interpreter_exists
25912594
is_linked = _testinternalcapi.interpreter_refcount_linked
2592-
get_refcount = _testinternalcapi.get_interpreter_refcount
2593-
incref = _testinternalcapi.interpreter_incref
2594-
decref = _testinternalcapi.interpreter_decref
2595+
get_refcount, incref, decref = self.get_refcount_helpers()
25952596

2596-
interpid = _testinternalcapi.new_interpreter()
2597-
self.add_interp_cleanup(interpid)
2597+
interpid = self.new_interpreter()
25982598

25992599
# Incref will not automatically link it.
26002600
incref(interpid)
@@ -2618,8 +2618,7 @@ def test_linked_lifecycle_link_unlink(self):
26182618
link = _testinternalcapi.link_interpreter_refcount
26192619
unlink = _testinternalcapi.unlink_interpreter_refcount
26202620

2621-
interpid = _testinternalcapi.new_interpreter()
2622-
self.add_interp_cleanup(interpid)
2621+
interpid = self.new_interpreter()
26232622

26242623
# Linking at refcount 0 does not destroy the interpreter.
26252624
link(interpid)
@@ -2639,12 +2638,9 @@ def test_linked_lifecycle_link_incref_decref(self):
26392638
exists = _testinternalcapi.interpreter_exists
26402639
is_linked = _testinternalcapi.interpreter_refcount_linked
26412640
link = _testinternalcapi.link_interpreter_refcount
2642-
get_refcount = _testinternalcapi.get_interpreter_refcount
2643-
incref = _testinternalcapi.interpreter_incref
2644-
decref = _testinternalcapi.interpreter_decref
2641+
get_refcount, incref, decref = self.get_refcount_helpers()
26452642

2646-
interpid = _testinternalcapi.new_interpreter()
2647-
self.add_interp_cleanup(interpid)
2643+
interpid = self.new_interpreter()
26482644

26492645
# Linking it will not change the refcount.
26502646
link(interpid)
@@ -2666,11 +2662,9 @@ def test_linked_lifecycle_link_incref_decref(self):
26662662
def test_linked_lifecycle_incref_link(self):
26672663
is_linked = _testinternalcapi.interpreter_refcount_linked
26682664
link = _testinternalcapi.link_interpreter_refcount
2669-
get_refcount = _testinternalcapi.get_interpreter_refcount
2670-
incref = _testinternalcapi.interpreter_incref
2665+
get_refcount, incref, _ = self.get_refcount_helpers()
26712666

2672-
interpid = _testinternalcapi.new_interpreter()
2673-
self.add_interp_cleanup(interpid)
2667+
interpid = self.new_interpreter()
26742668

26752669
incref(interpid)
26762670
self.assertEqual(
@@ -2688,12 +2682,9 @@ def test_linked_lifecycle_link_incref_unlink_decref(self):
26882682
is_linked = _testinternalcapi.interpreter_refcount_linked
26892683
link = _testinternalcapi.link_interpreter_refcount
26902684
unlink = _testinternalcapi.unlink_interpreter_refcount
2691-
get_refcount = _testinternalcapi.get_interpreter_refcount
2692-
incref = _testinternalcapi.interpreter_incref
2693-
decref = _testinternalcapi.interpreter_decref
2685+
get_refcount, incref, decref = self.get_refcount_helpers()
26942686

2695-
interpid = _testinternalcapi.new_interpreter()
2696-
self.add_interp_cleanup(interpid)
2687+
interpid = self.new_interpreter()
26972688

26982689
link(interpid)
26992690
self.assertTrue(

Lib/test/test_import/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2163,7 +2163,7 @@ def re_load(self, name, mod):
21632163
# subinterpreters
21642164

21652165
def add_subinterpreter(self):
2166-
interpid = _interpreters.create(isolated=False)
2166+
interpid = _interpreters.create('legacy')
21672167
def ensure_destroyed():
21682168
try:
21692169
_interpreters.destroy(interpid)

Lib/test/test_importlib/test_util.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ def test_magic_number(self):
656656
class IncompatibleExtensionModuleRestrictionsTests(unittest.TestCase):
657657

658658
def run_with_own_gil(self, script):
659-
interpid = _interpreters.create(isolated=True)
659+
interpid = _interpreters.create('isolated')
660660
def ensure_destroyed():
661661
try:
662662
_interpreters.destroy(interpid)
@@ -669,7 +669,7 @@ def ensure_destroyed():
669669
raise ImportError(excsnap.msg)
670670

671671
def run_with_shared_gil(self, script):
672-
interpid = _interpreters.create(isolated=False)
672+
interpid = _interpreters.create('legacy')
673673
def ensure_destroyed():
674674
try:
675675
_interpreters.destroy(interpid)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy