Skip to content

Commit d1c3c13

Browse files
bpo-30447: Fix/skip the subinterpreters test on some platforms. (#1791)
1 parent 9498782 commit d1c3c13

2 files changed

Lines changed: 43 additions & 44 deletions

File tree

Lib/test/test_capi.py

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ def run_embedded_interpreter(self, *args):
385385
(p.returncode, err))
386386
return out, err
387387

388-
def test_subinterps(self):
388+
def run_repeated_init_and_subinterpreters(self):
389389
out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
390390
self.assertEqual(err, "")
391391

@@ -404,73 +404,72 @@ def test_subinterps(self):
404404
r"id\(modules\) = ([\d]+)$")
405405
Interp = namedtuple("Interp", "id interp tstate modules")
406406

407-
main = None
408-
lastmain = None
409-
numinner = None
410407
numloops = 0
408+
current_run = []
411409
for line in out.splitlines():
412410
if line == "--- Pass {} ---".format(numloops):
413-
if numinner is not None:
414-
self.assertEqual(numinner, 5)
411+
self.assertEqual(len(current_run), 0)
415412
if support.verbose:
416413
print(line)
417-
lastmain = main
418-
main = None
419-
mainid = 0
420414
numloops += 1
421-
numinner = 0
422415
continue
423-
numinner += 1
424416

425-
self.assertLessEqual(numinner, 5)
417+
self.assertLess(len(current_run), 5)
426418
match = re.match(interp_pat, line)
427419
if match is None:
428420
self.assertRegex(line, interp_pat)
429421

430-
# The last line in the loop should be the same as the first.
431-
if numinner == 5:
432-
self.assertEqual(match.groups(), main)
433-
continue
434-
435422
# Parse the line from the loop. The first line is the main
436423
# interpreter and the 3 afterward are subinterpreters.
437424
interp = Interp(*match.groups())
438425
if support.verbose:
439426
print(interp)
440-
if numinner == 1:
441-
main = interp
442-
id = str(mainid)
443-
else:
444-
subid = mainid + numinner - 1
445-
id = str(subid)
446-
447-
# Validate the loop line for each interpreter.
448-
self.assertEqual(interp.id, id)
449427
self.assertTrue(interp.interp)
450428
self.assertTrue(interp.tstate)
451429
self.assertTrue(interp.modules)
452-
if platform.system() == 'Windows':
453-
# XXX Fix on Windows: something is going on with the
454-
# pointers in Programs/_testembed.c. interp.interp
455-
# is 0x0 and # interp.modules is the same between
456-
# interpreters.
457-
continue
458-
if interp is main:
459-
if lastmain is not None:
460-
# A new main interpreter may have the same interp
461-
# and/or tstate pointer as an earlier finalized/
462-
# destroyed one. So we do not check interp or
463-
# tstate here.
464-
self.assertNotEqual(interp.modules, lastmain.modules)
465-
else:
430+
current_run.append(interp)
431+
432+
# The last line in the loop should be the same as the first.
433+
if len(current_run) == 5:
434+
main = current_run[0]
435+
self.assertEqual(interp, main)
436+
yield current_run
437+
current_run = []
438+
439+
def test_subinterps_main(self):
440+
for run in self.run_repeated_init_and_subinterpreters():
441+
main = run[0]
442+
443+
self.assertEqual(main.id, '0')
444+
445+
def test_subinterps_different_ids(self):
446+
for run in self.run_repeated_init_and_subinterpreters():
447+
main, *subs, _ = run
448+
449+
mainid = int(main.id)
450+
for i, sub in enumerate(subs):
451+
self.assertEqual(sub.id, str(mainid + i + 1))
452+
453+
def test_subinterps_distinct_state(self):
454+
for run in self.run_repeated_init_and_subinterpreters():
455+
main, *subs, _ = run
456+
457+
if '0x0' in main:
458+
# XXX Fix on Windows (and other platforms): something
459+
# is going on with the pointers in Programs/_testembed.c.
460+
# interp.interp is 0x0 and interp.modules is the same
461+
# between interpreters.
462+
raise unittest.SkipTest('platform prints pointers as 0x0')
463+
464+
for sub in subs:
466465
# A new subinterpreter may have the same
467466
# PyInterpreterState pointer as a previous one if
468467
# the earlier one has already been destroyed. So
469468
# we compare with the main interpreter. The same
470469
# applies to tstate.
471-
self.assertNotEqual(interp.interp, main.interp)
472-
self.assertNotEqual(interp.tstate, main.tstate)
473-
self.assertNotEqual(interp.modules, main.modules)
470+
self.assertNotEqual(sub.interp, main.interp)
471+
self.assertNotEqual(sub.tstate, main.tstate)
472+
self.assertNotEqual(sub.modules, main.modules)
474473

475474
@staticmethod
476475
def _get_default_pipe_encoding():

Programs/_testembed.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static void print_subinterp(void)
2828
PyThreadState *ts = PyThreadState_Get();
2929
PyInterpreterState *interp = ts->interp;
3030
int64_t id = PyInterpreterState_GetID(interp);
31-
printf("interp %lu <0x%" PRIXPTR ">, thread state <0x%" PRIXPTR ">: ",
31+
printf("interp %" PRId64 " <0x%" PRIXPTR ">, thread state <0x%" PRIXPTR ">: ",
3232
id, (uintptr_t)interp, (uintptr_t)ts);
3333
fflush(stdout);
3434
PyRun_SimpleString(

0 commit comments

Comments
 (0)