@@ -221,36 +221,21 @@ be "future-compatible": we can introduce new hook named parameters without
221221breaking the signatures of existing hook implementations. It is one of
222222the reasons for the general long-lived compatibility of pytest plugins.
223223
224- Hook function results
225- ---------------------
226-
227- Most calls to ``pytest`` hooks result in a **list of results** which contains
228- all non-None results of the called hook functions.
229-
230- Some hooks are specified so that the hook call only executes until the
231- first function returned a non-None value which is then also the
232- result of the overall hook call. The remaining hook functions will
233- not be called in this case.
234-
235224Note that hook functions other than ``pytest_runtest_*`` are not
236225allowed to raise exceptions. Doing so will break the pytest run.
237226
238- Hook function ordering
239- ----------------------
240227
241- For any given hook there may be more than one implementation and we thus
242- generally view ``hook`` execution as a ``1:N`` function call where ``N``
243- is the number of registered functions. There are ways to
244- influence if a hook implementation comes before or after others, i.e.
245- the position in the ``N``-sized list of functions::
246228
247- @pytest.hookimpl_spec(tryfirst=True)
248- def pytest_collection_modifyitems(items):
249- # will execute as early as possible
229+ firstresult: stop at first non-None result
230+ -------------------------------------------
250231
251- @pytest.hookimpl_spec(trylast=True)
252- def pytest_collection_modifyitems(items):
253- # will execute as late as possible
232+ Most calls to ``pytest`` hooks result in a **list of results** which contains
233+ all non-None results of the called hook functions.
234+
235+ Some hook specifications use the ``firstresult=True`` option so that the hook
236+ call only executes until the first of N registered functions returns a
237+ non-None result which is then taken as result of the overall hook call.
238+ The remaining hook functions will not be called in this case.
254239
255240
256241hookwrapper: executing around other hooks
@@ -290,6 +275,47 @@ perform tracing or other side effects around the actual hook implementations.
290275If the result of the underlying hook is a mutable object, they may modify
291276that result, however.
292277
278+
279+
280+ Hook function ordering / call example
281+ -------------------------------------
282+
283+ For any given hook specification there may be more than one
284+ implementation and we thus generally view ``hook`` execution as a
285+ ``1:N`` function call where ``N`` is the number of registered functions.
286+ There are ways to influence if a hook implementation comes before or
287+ after others, i.e. the position in the ``N``-sized list of functions::
288+
289+ # Plugin 1
290+ @pytest.hookimpl_spec(tryfirst=True)
291+ def pytest_collection_modifyitems(items):
292+ # will execute as early as possible
293+
294+ # Plugin 2
295+ @pytest.hookimpl_spec(trylast=True)
296+ def pytest_collection_modifyitems(items):
297+ # will execute as late as possible
298+
299+ # Plugin 3
300+ @pytest.hookimpl_spec(hookwrapper=True)
301+ def pytest_collection_modifyitems(items):
302+ # will execute even before the tryfirst one above!
303+ outcome = yield
304+ # will execute after all non-hookwrappers executed
305+
306+ Here is the order of execution:
307+
308+ 1. Plugin3's pytest_collection_modifyitems called until the yield point
309+ 2. Plugin1's pytest_collection_modifyitems is called
310+ 3. Plugin2's pytest_collection_modifyitems is called
311+ 4. Plugin3's pytest_collection_modifyitems called for executing after the yield
312+ The yield receives a :py:class:`CallOutcome` instance which encapsulates
313+ the result from calling the non-wrappers. Wrappers cannot modify the result.
314+
315+ It's possible to use ``tryfirst`` and ``trylast`` also in conjunction with
316+ ``hookwrapper=True`` in which case it will influence the ordering of hookwrappers
317+ among each other.
318+
293319Declaring new hooks
294320------------------------
295321
0 commit comments