|
1 | | -""" |
2 | | -PluginManager, basic initialization and tracing. |
3 | | -
|
4 | | -pluggy is the cristallized core of plugin management as used |
5 | | -by some 150 plugins for pytest. |
6 | | -
|
7 | | -Pluggy uses semantic versioning. Breaking changes are only foreseen for |
8 | | -Major releases (incremented X in "X.Y.Z"). If you want to use pluggy in |
9 | | -your project you should thus use a dependency restriction like |
10 | | -"pluggy>=0.1.0,<1.0" to avoid surprises. |
11 | | -
|
12 | | -pluggy is concerned with hook specification, hook implementations and hook |
13 | | -calling. For any given hook specification a hook call invokes up to N implementations. |
14 | | -A hook implementation can influence its position and type of execution: |
15 | | -if attributed "tryfirst" or "trylast" it will be tried to execute |
16 | | -first or last. However, if attributed "hookwrapper" an implementation |
17 | | -can wrap all calls to non-hookwrapper implementations. A hookwrapper |
18 | | -can thus execute some code ahead and after the execution of other hooks. |
19 | | -
|
20 | | -Hook specification is done by way of a regular python function where |
21 | | -both the function name and the names of all its arguments are significant. |
22 | | -Each hook implementation function is verified against the original specification |
23 | | -function, including the names of all its arguments. To allow for hook specifications |
24 | | -to evolve over the livetime of a project, hook implementations can |
25 | | -accept less arguments. One can thus add new arguments and semantics to |
26 | | -a hook specification by adding another argument typically without breaking |
27 | | -existing hook implementations. |
28 | | -
|
29 | | -The chosen approach is meant to let a hook designer think carefuly about |
30 | | -which objects are needed by an extension writer. By contrast, subclass-based |
31 | | -extension mechanisms often expose a lot more state and behaviour than needed, |
32 | | -thus restricting future developments. |
33 | | -
|
34 | | -Pluggy currently consists of functionality for: |
35 | | -
|
36 | | -- a way to register new hook specifications. Without a hook |
37 | | - specification no hook calling can be performed. |
38 | | -
|
39 | | -- a registry of plugins which contain hook implementation functions. It |
40 | | - is possible to register plugins for which a hook specification is not yet |
41 | | - known and validate all hooks when the system is in a more referentially |
42 | | - consistent state. Setting an "optionalhook" attribution to a hook |
43 | | - implementation will avoid PluginValidationError's if a specification |
44 | | - is missing. This allows to have optional integration between plugins. |
45 | | -
|
46 | | -- a "hook" relay object from which you can launch 1:N calls to |
47 | | - registered hook implementation functions |
48 | | -
|
49 | | -- a mechanism for ordering hook implementation functions |
50 | | -
|
51 | | -- mechanisms for two different type of 1:N calls: "firstresult" for when |
52 | | - the call should stop when the first implementation returns a non-None result. |
53 | | - And the other (default) way of guaranteeing that all hook implementations |
54 | | - will be called and their non-None result collected. |
55 | | -
|
56 | | -- mechanisms for "historic" extension points such that all newly |
57 | | - registered functions will receive all hook calls that happened |
58 | | - before their registration. |
59 | | -
|
60 | | -- a mechanism for discovering plugin objects which are based on |
61 | | - setuptools based entry points. |
62 | | -
|
63 | | -- a simple tracing mechanism, including tracing of plugin calls and |
64 | | - their arguments. |
65 | | -
|
66 | | -""" |
67 | 1 | import sys |
68 | 2 | import inspect |
69 | 3 |
|
|
0 commit comments