Skip to content

Commit adec060

Browse files
committed
Profiling-target-adding tests
tests/test_explicit_profile.py test_profiler_add_methods() New test for the `wrap` argument of the `add_imported_function_or_module()`, `.add_class()`, and `.add_module()` methods
1 parent 22cff50 commit adec060

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

tests/test_explicit_profile.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import contextlib
12
import os
23
import re
34
import sys
@@ -407,6 +408,96 @@ def func4(a):
407408
temp_dpath.delete()
408409

409410

411+
@pytest.mark.parametrize('reset_enable_count', [True, False])
412+
@pytest.mark.parametrize('wrap_class, wrap_module',
413+
[(None, None), (False, True),
414+
(True, False), (True, True)])
415+
def test_profiler_add_methods(wrap_class, wrap_module, reset_enable_count):
416+
"""
417+
Test the `wrap` argument for the
418+
`line_profiler.autoprofile.autoprofile.
419+
_extend_line_profiler_for_profiling_imports()`,
420+
`LineProfiler.add_class()` and `.add_module()` methods.
421+
"""
422+
def write(path, code):
423+
path.write_text(ub.codeblock(code))
424+
425+
script = ub.codeblock('''
426+
from line_profiler import LineProfiler
427+
from line_profiler.autoprofile.autoprofile import (
428+
_extend_line_profiler_for_profiling_imports as upgrade_profiler)
429+
430+
import my_module_1
431+
from my_module_2 import Class
432+
from my_module_3 import func3
433+
434+
435+
profiler = LineProfiler()
436+
upgrade_profiler(profiler)
437+
profiler.add_imported_function_or_module(my_module_1{})
438+
profiler.add_imported_function_or_module(Class{})
439+
profiler.add_imported_function_or_module(func3)
440+
441+
if {}:
442+
for _ in range(profiler.enable_count):
443+
profiler.disable_by_count()
444+
445+
# `func1()` should only have timing info if `wrap_module`
446+
my_module_1.func1()
447+
# `method2()` should only have timing info if `wrap_class`
448+
Class.method2()
449+
# `func3()` is profiled but don't see any timing info because it
450+
# isn't wrapped and doesn't auto-`.enable()` before being called
451+
func3()
452+
profiler.print_stats(details=True, summarize=True)
453+
'''.format(
454+
'' if wrap_module is None else f', wrap={wrap_module}',
455+
'' if wrap_class is None else f', wrap={wrap_class}',
456+
reset_enable_count))
457+
458+
with contextlib.ExitStack() as stack:
459+
enter = stack.enter_context
460+
enter(ub.ChDir(enter(tempfile.TemporaryDirectory())))
461+
curdir = ub.Path.cwd()
462+
write(curdir / 'script.py', script)
463+
write(curdir / 'my_module_1.py',
464+
'''
465+
def func1():
466+
pass # Marker: func1
467+
''')
468+
write(curdir / 'my_module_2.py',
469+
'''
470+
class Class:
471+
@classmethod
472+
def method2(cls):
473+
pass # Marker: method2
474+
''')
475+
write(curdir / 'my_module_3.py',
476+
'''
477+
def func3():
478+
pass # Marker: func3
479+
''')
480+
proc = ub.cmd([sys.executable, str(curdir / 'script.py')])
481+
482+
# Check that the profiler has seen each of the methods
483+
raw_output = proc.stdout
484+
print(script)
485+
print(raw_output)
486+
print(proc.stderr)
487+
proc.check_returncode()
488+
assert '# Marker: func1' in raw_output
489+
assert '# Marker: method2' in raw_output
490+
assert '# Marker: func3' in raw_output
491+
492+
# Check that the timing info (of the lack thereof) are correct
493+
for func, has_timing in [('func1', wrap_module), ('method2', wrap_class),
494+
('func3', False)]:
495+
line, = (line for line in raw_output.splitlines()
496+
if line.endswith('Marker: ' + func))
497+
has_timing = has_timing or not reset_enable_count
498+
assert line.split()[1] == ('1' if has_timing else 'pass')
499+
500+
410501
if __name__ == '__main__':
411502
...
412503
test_simple_explicit_nonglobal_usage()

0 commit comments

Comments
 (0)