Skip to content

Commit 0783abf

Browse files
committed
Fix for --prof-mod
kernprof.py - Replaced `tempfile.NamedTemporaryFile` with `tempfile.TemporaryDirectory` (helps with cross-platform compatibility and performance in some edge cases) - Fixed bug where the tempfile name is split info chars for `--prof-mod` test/test_autoprofile.py test_autoprofile_from_stdin() Added subtests which test the interactions with the `-p` and `-v` flags test_autoprofile_from_inlined_script() Cleaned up test body
1 parent 2988e13 commit 0783abf

File tree

2 files changed

+52
-49
lines changed

2 files changed

+52
-49
lines changed

kernprof.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,8 @@ def positive_float(value):
433433
import tempfile
434434

435435
source, content = tempfile_source_and_content
436-
file_prefix = f'kernprof-{source}-'
437-
with tempfile.NamedTemporaryFile(mode='w',
438-
prefix=file_prefix,
439-
suffix='.py') as fobj:
436+
file_prefix = f'kernprof-{source}'
437+
with tempfile.TemporaryDirectory() as tmpdir:
440438
# Set up the script to be run
441439
try:
442440
content = ast.unparse(ast.parse(content))
@@ -448,19 +446,21 @@ def positive_float(value):
448446
# stdin), which can't be all that complicated
449447
RecursionError):
450448
pass
451-
print(content, file=fobj, flush=True)
452-
options.script = fobj.name
449+
fname = os.path.join(tmpdir, file_prefix + '.py')
450+
with open(fname, mode='w') as fobj:
451+
print(content, file=fobj)
452+
options.script = fname
453453
# Add the tempfile to `--prof-mod`
454454
if options.prof_mod:
455-
options.prof_mod += ',' + fobj.name
455+
options.prof_mod.append(fname)
456456
else:
457-
options.prof_mod = fobj.name
457+
options.prof_mod = [fname]
458458
# Set the output file to somewhere nicer (also take care of
459459
# possible filename clash)
460460
if not options.outfile:
461461
extension = 'lprof' if options.line_by_line else 'prof'
462462
_, options.outfile = tempfile.mkstemp(dir=os.curdir,
463-
prefix=file_prefix,
463+
prefix=file_prefix + '-',
464464
suffix='.' + extension)
465465
return _main(options, module)
466466

tests/test_autoprofile.py

+43-40
Original file line numberDiff line numberDiff line change
@@ -529,28 +529,31 @@ def test_autoprofile_exec_module(
529529
assert ('Function: _main' in raw_output) == main
530530

531531

532+
@pytest.mark.parametrize('view', [True, False])
533+
@pytest.mark.parametrize('prof_mod', [True, False])
532534
@pytest.mark.parametrize(
533535
('outfile', 'expected_outfile'),
534536
[(None, 'kernprof-stdin-*.lprof'),
535537
('test-stdin.lprof', 'test-stdin.lprof')])
536538
def test_autoprofile_from_stdin(
537-
outfile, expected_outfile,
538-
) -> None:
539+
outfile, expected_outfile, prof_mod, view) -> None:
539540
"""
540541
Test the profiling of a script read from stdin.
541542
"""
542543
with tempfile.TemporaryDirectory() as tmpdir:
543544
temp_dpath = ub.Path(tmpdir)
544545

546+
kp_cmd = [sys.executable, '-m', 'kernprof', '-l']
547+
if prof_mod:
548+
kp_cmd += ['-p' 'test_mod.submod1,test_mod.subpkg.submod3']
549+
if outfile:
550+
kp_cmd += ['-o', outfile]
551+
if view:
552+
kp_cmd += ['-v']
553+
kp_cmd += ['-']
545554
with ub.ChDir(temp_dpath):
546555
script_fpath = _write_demo_module(ub.Path())
547-
548-
args = [sys.executable, '-m', 'kernprof',
549-
'-p', 'test_mod.submod1,test_mod.subpkg.submod3', '-l']
550-
if outfile:
551-
args += ['-o', outfile]
552-
args += ['-']
553-
proc = subprocess.run(args,
556+
proc = subprocess.run(kp_cmd,
554557
input=script_fpath.read_text(),
555558
text=True,
556559
capture_output=True)
@@ -559,25 +562,28 @@ def test_autoprofile_from_stdin(
559562
proc.check_returncode()
560563

561564
outfile, = temp_dpath.glob(expected_outfile)
562-
args = [sys.executable, '-m', 'line_profiler', str(outfile)]
563-
proc = ub.cmd(args)
564-
raw_output = proc.stdout
565-
print(raw_output)
566-
proc.check_returncode()
565+
if view:
566+
raw_output = proc.stdout
567+
else:
568+
lp_cmd = [sys.executable, '-m', 'line_profiler', str(outfile)]
569+
proc = ub.cmd(lp_cmd)
570+
raw_output = proc.stdout
571+
print(raw_output)
572+
proc.check_returncode()
567573

568-
assert 'Function: add_one' in raw_output
574+
assert ('Function: add_one' in raw_output) == prof_mod
569575
assert 'Function: add_two' not in raw_output
570-
assert 'Function: add_three' in raw_output
571-
assert 'Function: main' not in raw_output
576+
assert ('Function: add_three' in raw_output) == prof_mod
577+
# If we're calling a separate process to view the results, the
578+
# script file will already have been deleted
579+
assert ('Function: main' in raw_output) == view
572580

573581

574582
@pytest.mark.parametrize(
575583
('outfile', 'expected_outfile'),
576584
[(None, 'kernprof-command-*.lprof'),
577585
('test-command.lprof', 'test-command.lprof')])
578-
def test_autoprofile_from_inlined_script(
579-
outfile, expected_outfile,
580-
) -> None:
586+
def test_autoprofile_from_inlined_script(outfile, expected_outfile) -> None:
581587
"""
582588
Test the profiling of an inlined script (supplied with the `-c`
583589
flag).
@@ -587,32 +593,29 @@ def test_autoprofile_from_inlined_script(
587593

588594
_write_demo_module(temp_dpath)
589595

590-
inlined_script = (
591-
'from test_mod import submod1, submod2; '
592-
'from test_mod.subpkg import submod3; '
593-
'import statistics; '
594-
'data = [1, 2, 3]; '
595-
'val = submod1.add_one(data); '
596-
'val = submod2.add_two(val); '
597-
'val = submod3.add_three(val); '
598-
'result = statistics.harmonic_mean(val); '
599-
'print(result); '
600-
)
601-
prof_file = 'test-command.lprof'
602-
603-
args = [sys.executable, '-m', 'kernprof',
604-
'-p', 'test_mod.submod1,test_mod.subpkg.submod3', '-l']
596+
inlined_script = ('from test_mod import submod1, submod2; '
597+
'from test_mod.subpkg import submod3; '
598+
'import statistics; '
599+
'data = [1, 2, 3]; '
600+
'val = submod1.add_one(data); '
601+
'val = submod2.add_two(val); '
602+
'val = submod3.add_three(val); '
603+
'result = statistics.harmonic_mean(val); '
604+
'print(result);')
605+
606+
kp_cmd = [sys.executable, '-m', 'kernprof',
607+
'-p', 'test_mod.submod1,test_mod.subpkg.submod3', '-l']
605608
if outfile:
606-
args += ['-o', outfile]
607-
args += ['-c', inlined_script]
608-
proc = ub.cmd(args, cwd=temp_dpath, verbose=2)
609+
kp_cmd += ['-o', outfile]
610+
kp_cmd += ['-c', inlined_script]
611+
proc = ub.cmd(kp_cmd, cwd=temp_dpath, verbose=2)
609612
print(proc.stdout)
610613
print(proc.stderr)
611614
proc.check_returncode()
612615

613616
outfile, = temp_dpath.glob(expected_outfile)
614-
args = [sys.executable, '-m', 'line_profiler', str(outfile)]
615-
proc = ub.cmd(args)
617+
lp_cmd = [sys.executable, '-m', 'line_profiler', str(outfile)]
618+
proc = ub.cmd(lp_cmd)
616619
raw_output = proc.stdout
617620
print(raw_output)
618621
proc.check_returncode()

0 commit comments

Comments
 (0)