Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Split up test_subinterpreters into more specific tests.
  • Loading branch information
ericsnowcurrently committed May 24, 2017
commit e592cc79a9a00c755e91dee193694ea13877fbb7
87 changes: 47 additions & 40 deletions Lib/test/test_capi.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ def run_embedded_interpreter(self, *args):
(p.returncode, err))
return out, err

def test_subinterps(self):
def run_repeated_init_and_subinterpreters(self):
out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
self.assertEqual(err, "")

Expand All @@ -404,74 +404,81 @@ def test_subinterps(self):
r"id\(modules\) = ([\d]+)$")
Interp = namedtuple("Interp", "id interp tstate modules")

main = None
lastmain = None
numinner = None
numloops = 0
current_run = []
for line in out.splitlines():
if line == "--- Pass {} ---".format(numloops):
if numinner is not None:
self.assertEqual(numinner, 5)
self.assertEqual(len(current_run), 0)
if support.verbose:
print(line)
lastmain = main
main = None
mainid = 0
numloops += 1
numinner = 0
continue
numinner += 1

self.assertLessEqual(numinner, 5)
self.assertLess(len(current_run), 5)
match = re.match(interp_pat, line)
if match is None:
self.assertRegex(line, interp_pat)

# The last line in the loop should be the same as the first.
if numinner == 5:
self.assertEqual(match.groups(), main)
continue

# Parse the line from the loop. The first line is the main
# interpreter and the 3 afterward are subinterpreters.
interp = Interp(*match.groups())
if support.verbose:
print(interp)
if numinner == 1:
main = interp
id = str(mainid)
else:
subid = mainid + numinner - 1
id = str(subid)

# Validate the loop line for each interpreter.
self.assertEqual(interp.id, id)
self.assertTrue(interp.interp)
self.assertTrue(interp.tstate)
self.assertTrue(interp.modules)
if '0x0' in interp:
current_run.append(interp)

# The last line in the loop should be the same as the first.
if len(current_run) == 5:
main = current_run[0]
self.assertEqual(interp, main)
yield current_run
current_run = []

def test_subinterps_main(self):
for run in self.run_repeated_init_and_subinterpreters():
main = run[0]

self.assertEqual(main.id, '0')

def test_subinterps_different_ids(self):
for run in self.run_repeated_init_and_subinterpreters():
main, *subs, _ = run

mainid = int(main.id)
for i, sub in enumerate(subs):
self.assertEqual(sub.id, str(mainid + i + 1))

def test_subinterps_distinct_state(self):
lastmain = None
for run in self.run_repeated_init_and_subinterpreters():
main, *subs, _ = run

if '0x0' in main:
# XXX Fix on Windows (and other platforms): something
# is going on with the pointers in Programs/_testembed.c.
# interp.interp is 0x0 and interp.modules is the same
# between interpreters.
warnings.warn('platform prints pointers as 0x0; skipping...')
continue
if interp is main:
if lastmain is not None:
# A new main interpreter may have the same interp
# and/or tstate pointer as an earlier finalized/
# destroyed one. So we do not check interp or
# tstate here.
self.assertNotEqual(interp.modules, lastmain.modules)
else:
raise unittest.SkipTest('platform prints pointers as 0x0')

if lastmain is not None:
# A new main interpreter may have the same interp
# and/or tstate pointer as an earlier finalized/
# destroyed one. So we do not check interp or
# tstate here.
self.assertNotEqual(main.modules, lastmain.modules)
lastmain = main

for sub in subs:
# A new subinterpreter may have the same
# PyInterpreterState pointer as a previous one if
# the earlier one has already been destroyed. So
# we compare with the main interpreter. The same
# applies to tstate.
self.assertNotEqual(interp.interp, main.interp)
self.assertNotEqual(interp.tstate, main.tstate)
self.assertNotEqual(interp.modules, main.modules)
self.assertNotEqual(sub.interp, main.interp)
self.assertNotEqual(sub.tstate, main.tstate)
self.assertNotEqual(sub.modules, main.modules)

@staticmethod
def _get_default_pipe_encoding():
Expand Down