From 71206ef5bde231fa1bb785418d08d4d22dbd8762 Mon Sep 17 00:00:00 2001 From: James Broadhead Date: Sat, 16 May 2015 18:37:03 +0100 Subject: [PATCH] Print error messages from SystemExit to stderr --- pex/pex.py | 6 ++++++ tests/test_pex.py | 22 ++++++++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/pex/pex.py b/pex/pex.py index 9d5ee95f7..1d401a9f2 100644 --- a/pex/pex.py +++ b/pex/pex.py @@ -320,6 +320,12 @@ def execute(self): # finally, then reraise so that the exit status is reflected correctly. sys.excepthook(*sys.exc_info()) raise + except SystemExit as se: + # Print a SystemExit error message, avoiding a traceback in python3. + # This must happen here, as sys.stderr is about to be torn down + if not isinstance(se.code, int): + print(se.code, file=sys.stderr) + raise finally: # squash all exceptions on interpreter teardown -- the primary type here are # atexit handlers failing to run because of things such as: diff --git a/tests/test_pex.py b/tests/test_pex.py index 2dd47491d..14bfa5454 100644 --- a/tests/test_pex.py +++ b/tests/test_pex.py @@ -7,6 +7,7 @@ import pytest +from pex.compatibility import to_bytes from pex.installer import EggInstaller, WheelInstaller from pex.pex import PEX from pex.testing import make_installer, run_simple_pex_test @@ -39,11 +40,24 @@ def excepthook(ex_type, ex, tb): assert rc == 42 -def test_pex_sys_exit_does_not_raise(): - body = "import sys; sys.exit(2)" +def _test_sys_exit(arg, expected_output, expected_rc): + body = "import sys; sys.exit({arg})".format(arg=arg) so, rc = run_simple_pex_test(body) - assert so == b'', 'Should not print SystemExit exception.' - assert rc == 2 + assert so == expected_output, 'Should not print SystemExit traceback.' + assert rc == expected_rc + + +def test_pex_sys_exit_does_not_print_for_numeric_value(): + _test_sys_exit(2, b'', 2) + + +def test_pex_sys_exit_prints_non_numeric_value_no_traceback(): + text = 'something went wrong' + + sys_exit_arg = '"' + text + '"' + # encode the string somehow that's compatible with 2 and 3 + expected_output = to_bytes(text) + b'\n' + _test_sys_exit(sys_exit_arg, expected_output, 1) @pytest.mark.skipif('hasattr(sys, "pypy_version_info")')