Skip to content

Commit fdf104d

Browse files
committed
Preserve readable cmd_line quoting while escaping newlines and add test (Closes #210)
1 parent dca916e commit fdf104d

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

‎mprof.py‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import glob
22
import os
33
import os.path as osp
4-
import shlex
54
import sys
65
import re
76
import copy
@@ -176,7 +175,10 @@ def clean_action():
176175

177176
def get_cmd_line(args):
178177
"""Given a set or arguments, compute command-line."""
179-
args = [shlex.quote(s).replace('\n', '\\n') for s in args]
178+
# Escape newlines so the CMDLINE record in the .dat file remains on a
179+
# single line and does not break read_mprofile_file() (#210).
180+
blanks = set(' \t\n')
181+
args = [s.replace('\n', '\\n') if blanks.isdisjoint(s) else "'" + s.replace('\n', '\\n') + "'" for s in args]
180182
return ' '.join(args)
181183

182184
def find_first_process(name):

‎test/test_mprof.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,26 @@ class Options:
101101
finally:
102102
pl.close(fig)
103103

104+
def test_multiline_cmdline_arg_roundtrip(self):
105+
# Verify that multiline CLI arguments passed to `mprof run` do not
106+
# write raw newlines into the CMDLINE header of the .dat file, which
107+
# previously caused read_mprofile_file() to crash with ValueError
108+
# on blank or single-token continuation lines (Issue #210 / PR #363).
109+
multiline_arg = "hello\n\nworld"
110+
cmd_line = mprof.get_cmd_line(["python", "script.py", multiline_arg])
111+
self.assertNotIn("\n", cmd_line)
112+
113+
content = (
114+
"CMDLINE %s\n"
115+
"MEM 10.0 100.0\n"
116+
) % cmd_line
117+
with tempfile.NamedTemporaryFile('w', suffix='.dat') as tmp_dat:
118+
tmp_dat.write(content)
119+
tmp_dat.flush()
120+
parsed = mprof.read_mprofile_file(tmp_dat.name)
121+
self.assertEqual(parsed["mem_usage"], [10.0])
122+
self.assertIn("hello\\n\\nworld", parsed["cmd_line"])
123+
104124

105125
if __name__ == "__main__":
106126
unittest.main()

0 commit comments

Comments
 (0)