diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 19597eb75f9168..72d51361e0b4d1 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -285,6 +285,27 @@ def check_exit_message(code, expected, **env_vars): r'import sys; sys.exit("h\xe9")', b"h\xe9", PYTHONIOENCODING='latin-1') + @support.requires_subprocess() + def test_exit_codes_under_repl(self): + # GH-129900: SystemExit, or things that raised it, didn't + # get their return code propagated by the REPL + import tempfile + + exit_ways = [ + "exit", + "__import__('sys').exit", + "raise SystemExit" + ] + + for exitfunc in exit_ways: + for return_code in (0, 123): + with self.subTest(exitfunc=exitfunc, return_code=return_code): + with tempfile.TemporaryFile("w+") as stdin: + stdin.write(f"{exitfunc}({return_code})\n") + stdin.seek(0) + proc = subprocess.run([sys.executable], stdin=stdin) + self.assertEqual(proc.returncode, return_code) + def test_getdefaultencoding(self): self.assertRaises(TypeError, sys.getdefaultencoding, 42) # can't check more than the type, as the user might have changed it diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-02-09-09-54-37.gh-issue-129900.GAGGPn.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-09-09-54-37.gh-issue-129900.GAGGPn.rst new file mode 100644 index 00000000000000..df15114cff7eb6 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-02-09-09-54-37.gh-issue-129900.GAGGPn.rst @@ -0,0 +1 @@ +Fix return codes inside :exc:`SystemExit` not getting returned by the REPL. diff --git a/Modules/main.c b/Modules/main.c index 3bf2241f2837a3..581c87270ff93f 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -572,8 +572,7 @@ pymain_run_stdin(PyConfig *config) int run = PyRun_AnyFileExFlags(stdin, "", 0, &cf); return (run != 0); } - int run = pymain_run_module(L"_pyrepl", 0); - return (run != 0); + return pymain_run_module(L"_pyrepl", 0); }