Skip to content

Commit 077d67b

Browse files
authored
Merge pull request #220 from hnykda/master
Optionally propagate the exit code
2 parents 218afbe + 5ee0a90 commit 077d67b

3 files changed

Lines changed: 54 additions & 1 deletion

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ test:
1616
$(PYTHON) test/test_memory_usage.py
1717
$(PYTHON) test/test_precision_import.py
1818
$(PYTHON) test/test_exception.py
19+
$(PYTHON) test/test_exit_code.py
1920
$(PYTHON) test/test_mprof.py
2021

2122
develop:

mprof.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import copy
77
import time
88
import math
9+
import logging
910

1011
from collections import defaultdict
1112
from argparse import ArgumentParser, ArgumentError, REMAINDER, RawTextHelpFormatter
@@ -26,6 +27,9 @@
2627
For example, mprof plot --help will list all plotting options.
2728
"""
2829

30+
logger = logging.getLogger(__name__)
31+
logging.basicConfig()
32+
2933

3034
def print_usage():
3135
print("Usage: %s <command> <options> <arguments>"
@@ -185,6 +189,7 @@ def run_action():
185189
help="""Monitors forked processes as well (sum up all process memory)""")
186190
parser.add_argument("--multiprocess", "-M", dest="multiprocess", action="store_true",
187191
help="""Monitors forked processes creating individual plots for each child (disables --python features)""")
192+
parser.add_argument("--exit-code", "-E", dest="exit_code", action="store_true", help="""Propagate the exit code""")
188193
parser.add_argument("--output", "-o", dest="filename",
189194
default="mprofile_%s.dat" % time.strftime("%Y%m%d%H%M%S", time.localtime()),
190195
help="""File to store results in, defaults to 'mprofile_<YYYYMMDDhhmmss>.dat' in the current directory,
@@ -197,7 +202,7 @@ def run_action():
197202
'Option 4: (--python flag present) "<PYTHON_MODULE> <ARG1> <ARG2>..." - profile python module\n'
198203
)
199204
args = parser.parse_args()
200-
205+
201206
if len(args.program) == 0:
202207
print("A program to run must be provided. Use -h for help")
203208
sys.exit(1)
@@ -236,6 +241,11 @@ def run_action():
236241
include_children=args.include_children,
237242
multiprocess=args.multiprocess, stream=f)
238243

244+
if args.exit_code:
245+
if p.returncode != 0:
246+
logger.error('Program resulted with a non-zero exit code: %s', p.returncode)
247+
sys.exit(p.returncode)
248+
239249

240250
def add_brackets(xloc, yloc, xshift=0, color="r", label=None, options=None):
241251
"""Add two brackets on the memory line plot.

test/test_exit_code.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import unittest
2+
import sys
3+
import tempfile
4+
5+
6+
class TestExitCode(unittest.TestCase):
7+
8+
def setUp(self):
9+
# to be able to import mprof
10+
sys.path.append('.')
11+
from mprof import run_action
12+
self.run_action = run_action
13+
14+
def test_exit_code_success(self):
15+
s = "1+1"
16+
tmpfile = tempfile.NamedTemporaryFile('w', suffix='.py')
17+
with tmpfile as ofile:
18+
ofile.write(s)
19+
ofile.flush()
20+
sys.argv = ['<ignored>', '--exit-code', tmpfile.name]
21+
self.assertRaisesRegexp(SystemExit, '0', self.run_action)
22+
23+
def test_exit_code_fail(self):
24+
s = "raise RuntimeError('I am not working nicely')"
25+
tmpfile = tempfile.NamedTemporaryFile('w', suffix='.py')
26+
with tmpfile as ofile:
27+
ofile.write(s)
28+
ofile.flush()
29+
sys.argv = ['<ignored>', '--exit-code', tmpfile.name]
30+
self.assertRaisesRegexp(SystemExit, '1', self.run_action)
31+
32+
def test_no_exit_code_success(self):
33+
s = "raise RuntimeError('I am not working nicely')"
34+
tmpfile = tempfile.NamedTemporaryFile('w', suffix='.py')
35+
with tmpfile as ofile:
36+
ofile.write(s)
37+
ofile.flush()
38+
sys.argv = ['<ignored>', tmpfile.name]
39+
self.run_action()
40+
41+
if __name__ == '__main__':
42+
unittest.main()

0 commit comments

Comments
 (0)