Browse Source

Update profilehooks module 1.11.2 (d72cc2b) → 1.12.0 (3ee1f60).

tags/release_0.25.1
JackDandy 5 years ago
parent
commit
725fae11d5
  1. 1
      CHANGES.md
  2. 39
      lib/profilehooks.py

1
CHANGES.md

@ -1,6 +1,7 @@
### 0.23.0 (2019-xx-xx xx:xx:xx UTC) ### 0.23.0 (2019-xx-xx xx:xx:xx UTC)
* Update attr 20.1.0.dev0 (4bd6827) to 20.2.0 (4f74fba) * Update attr 20.1.0.dev0 (4bd6827) to 20.2.0 (4f74fba)
* Update profilehooks module 1.11.2 (d72cc2b) to 1.12.0 (3ee1f60)
[develop changelog] [develop changelog]

39
lib/profilehooks.py

@ -91,10 +91,11 @@ from __future__ import print_function
__author__ = "Marius Gedminas <marius@gedmin.as>" __author__ = "Marius Gedminas <marius@gedmin.as>"
__copyright__ = "Copyright 2004-2020 Marius Gedminas and contributors" __copyright__ = "Copyright 2004-2020 Marius Gedminas and contributors"
__license__ = "MIT" __license__ = "MIT"
__version__ = '1.11.2' __version__ = '1.12.0'
__date__ = "2020-03-03" __date__ = "2020-08-20"
import atexit import atexit
import functools import functools
import inspect import inspect
import logging import logging
@ -133,7 +134,6 @@ try:
except ImportError: except ImportError:
cProfile = None cProfile = None
# registry of available profilers # registry of available profilers
AVAILABLE_PROFILERS = {} AVAILABLE_PROFILERS = {}
@ -162,6 +162,10 @@ def _identify(fn):
return (funcname, filename, lineno) return (funcname, filename, lineno)
def _is_file_like(o):
return hasattr(o, 'write')
def profile(fn=None, skip=0, filename=None, immediate=False, dirs=False, def profile(fn=None, skip=0, filename=None, immediate=False, dirs=False,
sort=None, entries=40, sort=None, entries=40,
profiler=('cProfile', 'profile', 'hotshot'), profiler=('cProfile', 'profile', 'hotshot'),
@ -170,8 +174,13 @@ def profile(fn=None, skip=0, filename=None, immediate=False, dirs=False,
If `skip` is > 0, first `skip` calls to `fn` will not be profiled. If `skip` is > 0, first `skip` calls to `fn` will not be profiled.
If `stdout` is not file-like and truthy, output will be printed to
sys.stdout. If it is a file-like object, output will be printed to it
instead. `stdout` must be writable in text mode (as opposed to binary)
if it is file-like.
If `immediate` is False, profiling results will be printed to If `immediate` is False, profiling results will be printed to
sys.stdout on program termination. Otherwise results will be printed self.stdout on program termination. Otherwise results will be printed
after each call. (If you don't want this, set stdout=False and specify a after each call. (If you don't want this, set stdout=False and specify a
`filename` to store profile data.) `filename` to store profile data.)
@ -322,6 +331,7 @@ class FuncProfile(object):
self.filename = filename self.filename = filename
self._immediate = immediate self._immediate = immediate
self.stdout = stdout self.stdout = stdout
self._stdout_is_fp = self.stdout and _is_file_like(self.stdout)
self.dirs = dirs self.dirs = dirs
self.sort = sort or ('cumulative', 'time', 'calls') self.sort = sort or ('cumulative', 'time', 'calls')
if isinstance(self.sort, str): if isinstance(self.sort, str):
@ -365,15 +375,19 @@ class FuncProfile(object):
stats.dump_stats(self.filename) stats.dump_stats(self.filename)
if self.stdout: if self.stdout:
funcname, filename, lineno = _identify(self.fn) funcname, filename, lineno = _identify(self.fn)
print("") print_f = print
print("*** PROFILER RESULTS ***") if self._stdout_is_fp:
print("%s (%s:%s)" % (funcname, filename, lineno)) print_f = functools.partial(print, file=self.stdout)
print_f("")
print_f("*** PROFILER RESULTS ***")
print_f("%s (%s:%s)" % (funcname, filename, lineno))
if self.skipped: if self.skipped:
skipped = " (%d calls not profiled)" % self.skipped skipped = " (%d calls not profiled)" % self.skipped
else: else:
skipped = "" skipped = ""
print("function called %d times%s" % (self.ncalls, skipped)) print_f("function called %d times%s" % (self.ncalls, skipped))
print("") print_f("")
if not self.dirs: if not self.dirs:
stats.strip_dirs() stats.strip_dirs()
stats.sort_stats(*self.sort) stats.sort_stats(*self.sort)
@ -381,13 +395,16 @@ class FuncProfile(object):
def reset_stats(self): def reset_stats(self):
"""Reset accumulated profiler statistics.""" """Reset accumulated profiler statistics."""
# send stats printing to specified stdout if it's file-like
stream = self.stdout if self._stdout_is_fp else sys.stdout
# Note: not using self.Profile, since pstats.Stats() fails then # Note: not using self.Profile, since pstats.Stats() fails then
self.stats = pstats.Stats(Profile()) self.stats = pstats.Stats(Profile(), stream=stream)
self.ncalls = 0 self.ncalls = 0
self.skipped = 0 self.skipped = 0
def atexit(self): def atexit(self):
"""Stop profiling and print profile information to sys.stdout. """Stop profiling and print profile information to sys.stdout or self.stdout.
This function is registered as an atexit hook. This function is registered as an atexit hook.
""" """

Loading…
Cancel
Save