Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/source/auto/kernprof.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ kernprof module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.__main__.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.\_\_main\_\_ module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler._line_profiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.\_line\_profiler module
:members:
:undoc-members:
:show-inheritance:
:private-members:
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.ast\_profle\_transformer module
:members:
:undoc-members:
:show-inheritance:
:private-members:
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.ast\_tree\_profiler module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.autoprofile.autoprofile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.autoprofile module
:members:
:undoc-members:
:show-inheritance:
:private-members:
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.eager\_preimports module
:members:
:undoc-members:
:show-inheritance:
:private-members:
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.line\_profiler\_utils module
:members:
:undoc-members:
:show-inheritance:
:private-members:
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.profmod\_extractor module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.autoprofile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,3 @@ Module contents
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.autoprofile.run_module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.run\_module module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.autoprofile.util_static.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.autoprofile.util\_static module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.explicit_profiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.explicit\_profiler module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.ipython_extension.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.ipython\_extension module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.line_profiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.line\_profiler module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.profiler_mixin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.profiler\_mixin module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,3 @@ Module contents
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.scoping_policy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.scoping\_policy module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.timers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.timers module
:members:
:undoc-members:
:show-inheritance:
:private-members:
1 change: 0 additions & 1 deletion docs/source/auto/line_profiler.unset_trace.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ line\_profiler.unset\_trace module
:members:
:undoc-members:
:show-inheritance:
:private-members:
69 changes: 35 additions & 34 deletions kernprof.py
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ def main(args=None):
diagnostics.log.debug(
f'Profiling script read from: {tempfile_source_and_content[0]}')
else:
diagnostics.log.debug(f'Profiling script: {options.script}')
diagnostics.log.debug(f'Profiling script: {options.script!r}')

with contextlib.ExitStack() as stack:
enter = stack.enter_context
Expand Down Expand Up @@ -869,8 +869,7 @@ def _write_preimports(prof, options, exclude):
with temp_file as fobj:
print(code, file=fobj)
diagnostics.log.debug(
'Wrote temporary module for pre-imports '
f'to {temp_mod_path!r}:')
f'Wrote temporary module for pre-imports to {temp_mod_path!r}')
else:
with temp_file as fobj:
write_eager_import_module(stream=fobj, **write_module_kwargs)
Expand Down Expand Up @@ -904,7 +903,12 @@ def _dump_filtered_stats(tmpdir, prof, filename):
for fname in fnames
]

if not tempfile_paths:
if not tempfile_paths or isinstance(prof, ContextualProfile):
# - No tempfiles written -> no function lives in tempfiles
# -> no need to filter anything
# - Not using `line_profiler`
# -> doesn't matter if the source lines can't be retrieved
# -> no need to filter anything
prof.dump_stats(filename)
return

Expand Down Expand Up @@ -1060,36 +1064,33 @@ def _main_profile(options, module=False):
"""
script_file, prof = _pre_profile(options, module)
try:
try:
rmod = functools.partial(run_module,
run_name='__main__', alter_sys=True)
ns = {'__file__': script_file, '__name__': '__main__',
'execfile': execfile, 'rmod': rmod,
'prof': prof}
if options.prof_mod and options.line_by_line:
from line_profiler.autoprofile import autoprofile
_call_with_diagnostics(
options,
autoprofile.run, script_file, ns,
prof_mod=options.prof_mod,
profile_imports=options.prof_imports,
as_module=module is not None)
elif module and options.builtin:
_call_with_diagnostics(options, rmod, options.script, ns)
elif options.builtin:
_call_with_diagnostics(options, execfile, script_file, ns, ns)
elif module:
_call_with_diagnostics(
options,
prof.runctx, f'rmod({options.script!r}, globals())',
ns, ns)
else:
_call_with_diagnostics(
options,
prof.runctx, f'execfile({script_file!r}, globals())',
ns, ns)
except (KeyboardInterrupt, SystemExit):
pass
rmod = functools.partial(run_module,
run_name='__main__', alter_sys=True)
ns = {'__file__': script_file, '__name__': '__main__',
'execfile': execfile, 'rmod': rmod,
'prof': prof}
if options.prof_mod and options.line_by_line:
from line_profiler.autoprofile import autoprofile
_call_with_diagnostics(
options,
autoprofile.run, script_file, ns,
prof_mod=options.prof_mod,
profile_imports=options.prof_imports,
as_module=module is not None)
elif module and options.builtin:
_call_with_diagnostics(options, rmod, options.script, ns)
elif options.builtin:
_call_with_diagnostics(options, execfile, script_file, ns, ns)
elif module:
_call_with_diagnostics(
options,
prof.runctx, f'rmod({options.script!r}, globals())',
ns, ns)
else:
_call_with_diagnostics(
options,
prof.runctx, f'execfile({script_file!r}, globals())',
ns, ns)
finally:
_post_profile(options, prof)

Expand Down
81 changes: 49 additions & 32 deletions line_profiler/profiler_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,43 +126,22 @@
def _get_underlying_functions(cls, func, seen=None, stop_at_classes=False):
if seen is None:
seen = set()
get_underlying = functools.partial(
cls._get_underlying_functions,
seen=seen, stop_at_classes=stop_at_classes)
kwargs = {'seen': seen, 'stop_at_classes': stop_at_classes}
# Extract inner functions
if any(check(func)
for check in (is_boundmethod, is_classmethod, is_staticmethod)):
return get_underlying(func.__func__)
return cls._get_underlying_functions(func.__func__, **kwargs)
if any(check(func)
for check in (is_partial, is_partialmethod, is_cached_property)):
return get_underlying(func.func)
return cls._get_underlying_functions(func.func, **kwargs)
# Dispatch to specific handlers
if is_property(func):
result = []
for impl in func.fget, func.fset, func.fdel:
if impl is not None:
result.extend(get_underlying(impl))
return result
return cls._get_underlying_functions_from_property(func, **kwargs)
if isinstance(func, type):
if stop_at_classes:
return [func]
result = []
get_filter = cls._class_scoping_policy.get_filter
func_check = get_filter(func, 'func')
cls_check = get_filter(func, 'class')
for member in vars(func).values():
try:
member_funcs = get_underlying(member, stop_at_classes=True)
except TypeError:
continue
for impl in member_funcs:
is_type = isinstance(impl, type)
check = cls_check if is_type else func_check
if not check(impl):
continue
if is_type:
result.extend(get_underlying(impl))
else:
result.append(impl)
return result
return cls._get_underlying_functions_from_type(func, **kwargs)

Check warning on line 143 in line_profiler/profiler_mixin.py

View check run for this annotation

Codecov / codecov/patch

line_profiler/profiler_mixin.py#L143

Added line #L143 was not covered by tests
# Otherwise, the object should either be a function...
if not callable(func):
raise TypeError(f'func = {func!r}: '
f'cannot get functions from {type(func)} objects')
Expand All @@ -173,11 +152,50 @@
return [func]
if is_c_level_callable(func):
return []
# ... or a generic callable
func = type(func).__call__
if is_c_level_callable(func): # Can happen with builtin types
return []
return [func]

@classmethod
def _get_underlying_functions_from_property(
cls, prop, seen, stop_at_classes):
result = []
for impl in prop.fget, prop.fset, prop.fdel:
if impl is not None:
result.extend(
cls._get_underlying_functions(impl, seen, stop_at_classes))
return result

@classmethod
def _get_underlying_functions_from_type(cls, kls, seen, stop_at_classes):
result = []
get_filter = cls._class_scoping_policy.get_filter
func_check = get_filter(kls, 'func')
cls_check = get_filter(kls, 'class')

Check warning on line 176 in line_profiler/profiler_mixin.py

View check run for this annotation

Codecov / codecov/patch

line_profiler/profiler_mixin.py#L173-L176

Added lines #L173 - L176 were not covered by tests
for member in vars(kls).values():
try: # Stop at class boundaries to enforce scoping behavior
member_funcs = cls._get_underlying_functions(

Check warning on line 179 in line_profiler/profiler_mixin.py

View check run for this annotation

Codecov / codecov/patch

line_profiler/profiler_mixin.py#L178-L179

Added lines #L178 - L179 were not covered by tests
member, seen, stop_at_classes=True)
except TypeError:
continue

Check warning on line 182 in line_profiler/profiler_mixin.py

View check run for this annotation

Codecov / codecov/patch

line_profiler/profiler_mixin.py#L181-L182

Added lines #L181 - L182 were not covered by tests
for impl in member_funcs:
if isinstance(impl, type):
# Only descend into nested classes if the policy
# says so
if cls_check(impl):
result.extend(cls._get_underlying_functions(

Check warning on line 188 in line_profiler/profiler_mixin.py

View check run for this annotation

Codecov / codecov/patch

line_profiler/profiler_mixin.py#L188

Added line #L188 was not covered by tests
impl, seen, stop_at_classes))
else:
# For non-class callables, they are already filtered
# (and added to `seen`) by the above call to
# `.get_underlying_functions()`, so just add them
# here
if func_check(impl):
result.append(impl)
return result

Check warning on line 197 in line_profiler/profiler_mixin.py

View check run for this annotation

Codecov / codecov/patch

line_profiler/profiler_mixin.py#L196-L197

Added lines #L196 - L197 were not covered by tests

def _wrap_callable_wrapper(self, wrapper, impl_attrs, *,
args=None, kwargs=None, name_attr=None):
"""
Expand Down Expand Up @@ -410,12 +428,11 @@
get_filter = self._class_scoping_policy.get_filter
func_check = get_filter(func, 'func')
cls_check = get_filter(func, 'class')
get_underlying = functools.partial(
self._get_underlying_functions, stop_at_classes=True)
members_to_wrap = {}
for name, member in vars(func).items():
try:
impls = get_underlying(member)
impls = self._get_underlying_functions(

Check warning on line 434 in line_profiler/profiler_mixin.py

View check run for this annotation

Codecov / codecov/patch

line_profiler/profiler_mixin.py#L434

Added line #L434 was not covered by tests
member, stop_at_classes=True)
except TypeError: # Not a callable (wrapper)
continue
if any((cls_check(impl)
Expand Down
2 changes: 0 additions & 2 deletions tests/test_kernprof.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,8 @@ def main():
[('', # Neutral verbosity level
{'^Output to stdout': True,
r"^Wrote .* '.*script\.py\.lprof'": True,
r'Parser output:''(?:\n)+'r'.*namespace\((?:.+,\n)*.*\)': False,
r'^Inspect results with:''\n'
r'python -m line_profiler .*script\.py\.lprof': True,
'^ *[0-9]+ *import zipfile': False,
r'line_profiler\.autoprofile\.autoprofile'
r'\.run\(\n(?:.+,\n)*.*\)': False,
r'^\[kernprof .*\]': False,
Expand Down
Loading