1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
"""
Benchmarking and performance tests.
"""
import pytest
from pluggy import HookimplMarker
from pluggy import HookspecMarker
from pluggy import PluginManager
from pluggy._callers import _multicall
from pluggy._hooks import HookImpl
hookspec = HookspecMarker("example")
hookimpl = HookimplMarker("example")
@hookimpl
def hook(arg1, arg2, arg3):
return arg1, arg2, arg3
@hookimpl(wrapper=True)
def wrapper(arg1, arg2, arg3):
return (yield)
@pytest.fixture(params=[10, 100], ids="hooks={}".format)
def hooks(request):
return [hook for i in range(request.param)]
@pytest.fixture(params=[10, 100], ids="wrappers={}".format)
def wrappers(request):
return [wrapper for i in range(request.param)]
def test_hook_and_wrappers_speed(benchmark, hooks, wrappers):
def setup():
hook_name = "foo"
hook_impls = []
for method in hooks + wrappers:
f = HookImpl(None, "<temp>", method, method.example_impl)
hook_impls.append(f)
caller_kwargs = {"arg1": 1, "arg2": 2, "arg3": 3}
firstresult = False
return (hook_name, hook_impls, caller_kwargs, firstresult), {}
benchmark.pedantic(_multicall, setup=setup, rounds=10)
@pytest.mark.parametrize(
("plugins, wrappers, nesting"),
[
(1, 1, 0),
(1, 1, 1),
(1, 1, 5),
(1, 5, 1),
(1, 5, 5),
(5, 1, 1),
(5, 1, 5),
(5, 5, 1),
(5, 5, 5),
(20, 20, 0),
(100, 100, 0),
],
)
def test_call_hook(benchmark, plugins, wrappers, nesting):
pm = PluginManager("example")
class HookSpec:
@hookspec
def fun(self, hooks, nesting: int):
pass
class Plugin:
def __init__(self, num: int) -> None:
self.num = num
def __repr__(self) -> str:
return f"<Plugin {self.num}>"
@hookimpl
def fun(self, hooks, nesting: int) -> None:
if nesting:
hooks.fun(hooks=hooks, nesting=nesting - 1)
class PluginWrap:
def __init__(self, num: int) -> None:
self.num = num
def __repr__(self) -> str:
return f"<PluginWrap {self.num}>"
@hookimpl(wrapper=True)
def fun(self):
return (yield)
pm.add_hookspecs(HookSpec)
for i in range(plugins):
pm.register(Plugin(i), name=f"plug_{i}")
for i in range(wrappers):
pm.register(PluginWrap(i), name=f"wrap_plug_{i}")
benchmark(pm.hook.fun, hooks=pm.hook, nesting=nesting)
|