Skip to content

Commit a4c307e

Browse files
committed
Separate tests for regular and asyncio REPL
1 parent bffac1c commit a4c307e

File tree

1 file changed

+91
-49
lines changed

1 file changed

+91
-49
lines changed

Lib/test/test_repl.py

Lines changed: 91 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,46 @@ def bar(x):
234234
expected = "(30, None, [\'def foo(x):\\n\', \' return x + 1\\n\', \'\\n\'], \'<stdin>\')"
235235
self.assertIn(expected, output, expected)
236236

237+
def test_pythonstartup_success(self):
238+
# errors based on https://github.com/python/cpython/issues/137576
239+
# case 1: error in user input, but PYTHONSTARTUP is fine
240+
startup_code = "print('notice from pythonstartup')"
241+
with new_startup_env(code=startup_code, histfile=".pythonhist") as startup_env:
242+
# -q to suppress noise
243+
p = spawn_repl("-q", env=os.environ | startup_env, isolated=False)
244+
p.stdin.write("1/0")
245+
output_lines = kill_python(p).splitlines()
246+
traceback_lines = output_lines[2:-1]
247+
expected_lines = [
248+
'Traceback (most recent call last):',
249+
' File "<stdin>", line 1, in <module>',
250+
' 1/0',
251+
' ~^~',
252+
'ZeroDivisionError: division by zero',
253+
]
254+
self.assertEqual(output_lines[0], 'notice from pythonstartup')
255+
self.assertEqual(traceback_lines, expected_lines)
256+
257+
def test_pythonstartup_failure(self):
258+
# case 2: error in PYTHONSTARTUP triggered by user input
259+
startup_code = "def foo():\n 1/0\n"
260+
with new_startup_env(code=startup_code, histfile=".asyncio_history") as startup_env:
261+
# -q to suppress noise
262+
p = spawn_repl("-q", env=os.environ | startup_env, isolated=False)
263+
p.stdin.write("foo()")
264+
traceback_lines = kill_python(p).splitlines()[1:-1]
265+
expected_lines = [
266+
'Traceback (most recent call last):',
267+
' File "<stdin>", line 1, in <module>',
268+
' foo()',
269+
' ~~~^^',
270+
f' File "{startup_env['PYTHONSTARTUP']}", line 2, in foo',
271+
' 1/0',
272+
' ~^~',
273+
'ZeroDivisionError: division by zero',
274+
]
275+
self.assertEqual(traceback_lines, expected_lines)
276+
237277
@unittest.skipUnless(pty, "requires pty")
238278
def test_asyncio_repl_is_ok(self):
239279
m, s = pty.openpty()
@@ -279,55 +319,6 @@ def new_startup_env(*, code: str, histfile: str = ".pythonhist"):
279319
yield {"PYTHONSTARTUP": filename, "PYTHON_HISTORY": os.path.join(tmpdir, histfile)}
280320

281321

282-
@support.force_not_colorized_test_class
283-
class TestPythonStartup(unittest.TestCase):
284-
REPLS = [
285-
("REPL", spawn_repl, ".pythonhist"),
286-
("asyncio REPL", spawn_asyncio_repl, ".asyncio_history"),
287-
]
288-
289-
def test_pythonstartup_success(self):
290-
# errors based on https://github.com/python/cpython/issues/137576
291-
# case 1: error in user input, but PYTHONSTARTUP is fine
292-
startup_code = "print('from pythonstartup')"
293-
for repl_name, repl_factory, histfile in self.REPLS:
294-
with (
295-
self.subTest(repl_name),
296-
new_startup_env(code=startup_code, histfile=histfile) as startup_env
297-
):
298-
p = repl_factory(env=os.environ | startup_env, isolated=False)
299-
p.stdin.write("1/0")
300-
output = kill_python(p)
301-
302-
for expected in (
303-
"from pythonstartup",
304-
"Traceback (most recent call last):",
305-
'File "<stdin>", line 1, in <module>',
306-
"ZeroDivisionError: division by zero",
307-
):
308-
self.assertIn(expected, output)
309-
310-
def test_pythonstartup_failure(self):
311-
# case 2: error in PYTHONSTARTUP triggered by user input
312-
startup_code = "def foo():\n 1/0\n"
313-
for repl_name, repl_factory, histfile in self.REPLS:
314-
with (
315-
self.subTest(repl_name),
316-
new_startup_env(code=startup_code, histfile=histfile) as startup_env
317-
):
318-
p = repl_factory(env=os.environ | startup_env, isolated=False)
319-
p.stdin.write('foo()')
320-
output = kill_python(p)
321-
322-
for expected in (
323-
"Traceback (most recent call last):",
324-
'File "<stdin>", line 1, in <module>',
325-
f'File "{startup_env['PYTHONSTARTUP']}", line ',
326-
"ZeroDivisionError: division by zero",
327-
):
328-
self.assertIn(expected, output)
329-
330-
331322
@support.force_not_colorized_test_class
332323
class TestInteractiveModeSyntaxErrors(unittest.TestCase):
333324

@@ -347,6 +338,7 @@ def f():
347338
self.assertEqual(traceback_lines, expected_lines)
348339

349340

341+
@support.force_not_colorized_test_class
350342
class TestAsyncioREPL(unittest.TestCase):
351343
def test_multiple_statements_fail_early(self):
352344
user_input = "1 / 0; print(f'afterwards: {1+1}')"
@@ -391,6 +383,56 @@ def test_toplevel_contextvars_async(self):
391383
expected = "toplevel contextvar test: ok"
392384
self.assertIn(expected, output, expected)
393385

386+
def test_pythonstartup_success(self):
387+
startup_code = "import sys\nprint('notice from pythonstartup in asyncio repl', file=sys.stderr)"
388+
with new_startup_env(code=startup_code, histfile=".asyncio_history") as startup_env:
389+
p = spawn_asyncio_repl(env=os.environ | startup_env, stderr=subprocess.PIPE, isolated=False)
390+
p.stdin.write("1/0")
391+
kill_python(p)
392+
output_lines = p.stderr.read().splitlines()
393+
p.stderr.close()
394+
self.assertEqual(output_lines[3], 'notice from pythonstartup in asyncio repl')
395+
tb_start_lines = output_lines[4:6]
396+
tb_final_lines = output_lines[13:]
397+
expected_lines = [
398+
'>>> import asyncio',
399+
'Traceback (most recent call last):',
400+
' File "<stdin>", line 1, in <module>',
401+
' 1/0',
402+
' ~^~',
403+
'ZeroDivisionError: division by zero',
404+
'',
405+
'exiting asyncio REPL...',
406+
]
407+
self.assertEqual(tb_start_lines + tb_final_lines, expected_lines)
408+
self.assertEqual(tb_start_lines + tb_final_lines, expected_lines)
409+
410+
def test_pythonstartup_failure(self):
411+
startup_code = "def foo():\n 1/0\n"
412+
with new_startup_env(code=startup_code, histfile=".asyncio_history") as startup_env:
413+
p = spawn_asyncio_repl(env=os.environ | startup_env, stderr=subprocess.PIPE, isolated=False)
414+
p.stdin.write("foo()")
415+
kill_python(p)
416+
output = p.stderr.read()
417+
p.stderr.close()
418+
tb_start_lines = output.splitlines()[3:5]
419+
tb_final_lines = output.splitlines()[12:]
420+
421+
expected_lines = [
422+
'>>> import asyncio',
423+
'Traceback (most recent call last):',
424+
' File "<stdin>", line 1, in <module>',
425+
' foo()',
426+
' ~~~^^',
427+
f' File "{startup_env['PYTHONSTARTUP']}", line 2, in foo',
428+
' 1/0',
429+
' ~^~',
430+
'ZeroDivisionError: division by zero',
431+
'',
432+
'exiting asyncio REPL...',
433+
]
434+
self.assertEqual(tb_start_lines + tb_final_lines, expected_lines)
435+
394436

395437
if __name__ == "__main__":
396438
unittest.main()

0 commit comments

Comments
 (0)