1+ import os
2+ import sys
3+ import tempfile
14import unittest
25
36import mprof
47
8+
59class Test_function_labels (unittest .TestCase ):
610 def test (self ):
711 expected = {
@@ -14,7 +18,57 @@ def test(self):
1418 "b.c" : "b.c" ,
1519 }
1620 result = mprof .function_labels (expected .keys ())
17- self .assertEqual (expected ,result )
21+ self .assertEqual (expected , result )
22+
23+
24+ class TestMprofMainArgs (unittest .TestCase ):
25+ """Tests for CLI argument handling in mprof.main() (Issue #388 / PR #390).
26+
27+ Background (Issue #388):
28+ Subcommands like `mprof plot -1` or `mprof rm -1` allow selecting a profile
29+ file by negative index (-1 = most recent). To prevent argparse from treating
30+ `-1` as an unknown flag, `mprof.main()` inserts `"--"` before the first
31+ negative integer in `sys.argv`.
32+
33+ However, when running `mprof run script.py -1`, inserting `"--"` into
34+ `sys.argv` causes `"--"` to be forwarded as an extra argument to `script.py`
35+ (so the script receives `['--', '-1']` instead of `['-1']`).
36+ """
37+
38+ def test_run_preserves_negative_int_args (self ):
39+ # Verify that `mprof run` does NOT inject "--" before negative integer
40+ # arguments meant for the target program. The temporary script checks
41+ # that its sys.argv[1:] is exactly ['-1'] and exits non-zero otherwise.
42+ script = (
43+ "import sys\n "
44+ "assert sys.argv[1:] == ['-1'], 'Unexpected argv: %r' % (sys.argv[1:],)\n "
45+ )
46+ with tempfile .NamedTemporaryFile ('w' , suffix = '.py' ) as tmp_script , \
47+ tempfile .NamedTemporaryFile ('w' , suffix = '.dat' ) as tmp_dat :
48+ tmp_script .write (script )
49+ tmp_script .flush ()
50+ sys .argv = [
51+ 'mprof' , 'run' , '--exit-code' , '-o' , tmp_dat .name ,
52+ tmp_script .name , '-1'
53+ ]
54+ with self .assertRaises (SystemExit ) as cm :
55+ mprof .main ()
56+ self .assertEqual (cm .exception .code , 0 )
57+
58+ def test_non_run_action_accepts_negative_index (self ):
59+ # Verify that non-`run` subcommands (such as `mprof rm --dry-run -1`)
60+ # still have "--" inserted before `-1` so negative profile indices
61+ # are accepted by argparse without raising an unrecognized argument error.
62+ tmp_prof = "mprofile_20990101000000.dat"
63+ with open (tmp_prof , "w" ) as f :
64+ f .write ("" )
65+ try :
66+ sys .argv = ['mprof' , 'rm' , '--dry-run' , '-1' ]
67+ mprof .main ()
68+ finally :
69+ if os .path .exists (tmp_prof ):
70+ os .remove (tmp_prof )
71+
1872
1973if __name__ == "__main__" :
2074 unittest .main ()
0 commit comments