-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add hooks for calling arbitrary code around each benchmark (#193)
* Add hooks for calling arbitrary code around each benchmark * Add setuptools as a dependency * Use importlib.metadata instead * Add testing * Add next version * Support older Python versions * Support older Pythons * Support newer Pythons * Fix arg parsing * Fix hook check * Add active hooks to metadata * Only load hooks actually in use * Fix tests
- Loading branch information
Showing
8 changed files
with
153 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Hooks are installable context managers defined as entry points so that | ||
# arbitrary code can by run right before and after the actual internal | ||
# benchmarking code is run. | ||
|
||
|
||
import abc | ||
import importlib.metadata | ||
import sys | ||
|
||
|
||
def get_hooks(): | ||
hook_prefix = "pyperf.hook" | ||
entry_points = importlib.metadata.entry_points() | ||
if sys.version_info[:2] < (3, 10): | ||
group = entry_points[hook_prefix] | ||
else: | ||
group = entry_points.select(group=hook_prefix) | ||
return group | ||
|
||
|
||
def get_hook_names(): | ||
return (x.name for x in get_hooks()) | ||
|
||
|
||
def get_selected_hooks(hook_names): | ||
if hook_names is None: | ||
return | ||
|
||
hook_mapping = {hook.name: hook for hook in get_hooks()} | ||
for hook_name in hook_names: | ||
yield hook_mapping[hook_name] | ||
|
||
|
||
class HookError(Exception): | ||
pass | ||
|
||
|
||
class HookBase(abc.ABC): | ||
def __init__(self): | ||
""" | ||
Create a new instance of the hook. | ||
""" | ||
pass | ||
|
||
def teardown(self, _metadata): | ||
""" | ||
Called when the hook is completed for a process. May add any information | ||
collected to the passed-in `metadata` dictionary. | ||
""" | ||
pass | ||
|
||
def __enter__(self): | ||
""" | ||
Called immediately before running benchmark code. | ||
May be called multiple times per instance. | ||
""" | ||
pass | ||
|
||
def __exit__(self, _exc_type, _exc_value, _traceback): | ||
""" | ||
Called immediately after running benchmark code. | ||
""" | ||
pass | ||
|
||
|
||
class _test_hook(HookBase): | ||
def __init__(self): | ||
self._count = 0 | ||
|
||
def teardown(self, metadata): | ||
metadata["_test_hook"] = self._count | ||
|
||
def __enter__(self): | ||
self._count += 1 | ||
|
||
def __exit__(self, _exc_type, _exc_value, _traceback): | ||
pass | ||
|
||
|
||
class pystats(HookBase): | ||
def __init__(self): | ||
if not hasattr(sys, "_stats_on"): | ||
raise HookError( | ||
"Can not collect pystats because python was not built with --enable-pystats" | ||
) | ||
sys._stats_off() | ||
sys._stats_clear() | ||
|
||
def teardown(self, metadata): | ||
metadata["pystats"] = "enabled" | ||
|
||
def __enter__(self): | ||
sys._stats_on() | ||
|
||
def __exit__(self, _exc_type, _exc_value, _traceback): | ||
sys._stats_off() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters