Skip to content

Docs: clarify when hooks stop after the first non-None result #2497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 44 additions & 15 deletions _pytest/hookspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,19 @@ def pytest_configure(config):

@hookspec(firstresult=True)
def pytest_cmdline_parse(pluginmanager, args):
"""return initialized config object, parsing the specified args. """
"""return initialized config object, parsing the specified args.

Stops at first non-None result, see :ref:`firstresult` """

def pytest_cmdline_preparse(config, args):
"""(deprecated) modify command line arguments before option parsing. """

@hookspec(firstresult=True)
def pytest_cmdline_main(config):
""" called for performing the main command line action. The default
implementation will invoke the configure hooks and runtest_mainloop. """
implementation will invoke the configure hooks and runtest_mainloop.

Stops at first non-None result, see :ref:`firstresult` """

def pytest_load_initial_conftests(early_config, parser, args):
""" implements the loading of initial conftest files ahead
Expand All @@ -94,7 +98,9 @@ def pytest_load_initial_conftests(early_config, parser, args):

@hookspec(firstresult=True)
def pytest_collection(session):
""" perform the collection protocol for the given session. """
""" perform the collection protocol for the given session.

Stops at first non-None result, see :ref:`firstresult` """

def pytest_collection_modifyitems(session, config, items):
""" called after collection has been performed, may filter or re-order
Expand All @@ -108,11 +114,15 @@ def pytest_ignore_collect(path, config):
""" return True to prevent considering this path for collection.
This hook is consulted for all files and directories prior to calling
more specific hooks.

Stops at first non-None result, see :ref:`firstresult`
"""

@hookspec(firstresult=True)
def pytest_collect_directory(path, parent):
""" called before traversing a directory for collection files. """
""" called before traversing a directory for collection files.

Stops at first non-None result, see :ref:`firstresult` """

def pytest_collect_file(path, parent):
""" return collection Node or None for the given path. Any new node
Expand All @@ -133,7 +143,9 @@ def pytest_deselected(items):

@hookspec(firstresult=True)
def pytest_make_collect_report(collector):
""" perform ``collector.collect()`` and return a CollectReport. """
""" perform ``collector.collect()`` and return a CollectReport.

Stops at first non-None result, see :ref:`firstresult` """

# -------------------------------------------------------------------------
# Python test function related hooks
Expand All @@ -145,15 +157,20 @@ def pytest_pycollect_makemodule(path, parent):
This hook will be called for each matching test module path.
The pytest_collect_file hook needs to be used if you want to
create test modules for files that do not match as a test module.
"""

Stops at first non-None result, see :ref:`firstresult` """

@hookspec(firstresult=True)
def pytest_pycollect_makeitem(collector, name, obj):
""" return custom item/collector for a python object in a module, or None. """
""" return custom item/collector for a python object in a module, or None.

Stops at first non-None result, see :ref:`firstresult` """

@hookspec(firstresult=True)
def pytest_pyfunc_call(pyfuncitem):
""" call underlying test function. """
""" call underlying test function.

Stops at first non-None result, see :ref:`firstresult` """

def pytest_generate_tests(metafunc):
""" generate (multiple) parametrized calls to a test function."""
Expand All @@ -163,7 +180,8 @@ def pytest_make_parametrize_id(config, val, argname):
"""Return a user-friendly string representation of the given ``val`` that will be used
by @pytest.mark.parametrize calls. Return None if the hook doesn't know about ``val``.
The parameter name is available as ``argname``, if required.
"""

Stops at first non-None result, see :ref:`firstresult` """

# -------------------------------------------------------------------------
# generic runtest related hooks
Expand All @@ -172,7 +190,9 @@ def pytest_make_parametrize_id(config, val, argname):
@hookspec(firstresult=True)
def pytest_runtestloop(session):
""" called for performing the main runtest loop
(after collection finished). """
(after collection finished).

Stops at first non-None result, see :ref:`firstresult` """

def pytest_itemstart(item, node):
""" (deprecated, use pytest_runtest_logstart). """
Expand All @@ -190,7 +210,9 @@ def pytest_runtest_protocol(item, nextitem):
:py:func:`pytest_runtest_teardown`.

:return boolean: True if no further hook implementations should be invoked.
"""


Stops at first non-None result, see :ref:`firstresult` """

def pytest_runtest_logstart(nodeid, location):
""" signal the start of running a single test item. """
Expand All @@ -215,7 +237,8 @@ def pytest_runtest_makereport(item, call):
""" return a :py:class:`_pytest.runner.TestReport` object
for the given :py:class:`pytest.Item <_pytest.main.Item>` and
:py:class:`_pytest.runner.CallInfo`.
"""

Stops at first non-None result, see :ref:`firstresult` """

def pytest_runtest_logreport(report):
""" process a test setup/call/teardown report relating to
Expand All @@ -227,7 +250,9 @@ def pytest_runtest_logreport(report):

@hookspec(firstresult=True)
def pytest_fixture_setup(fixturedef, request):
""" performs fixture setup execution. """
""" performs fixture setup execution.

Stops at first non-None result, see :ref:`firstresult` """

def pytest_fixture_post_finalizer(fixturedef):
""" called after fixture teardown, but before the cache is cleared so
Expand Down Expand Up @@ -277,7 +302,9 @@ def pytest_report_header(config, startdir):

@hookspec(firstresult=True)
def pytest_report_teststatus(report):
""" return result-category, shortletter and verbose word for reporting."""
""" return result-category, shortletter and verbose word for reporting.

Stops at first non-None result, see :ref:`firstresult` """

def pytest_terminal_summary(terminalreporter, exitstatus):
""" add additional section in terminal summary reporting. """
Expand All @@ -295,7 +322,9 @@ def pytest_logwarning(message, code, nodeid, fslocation):

@hookspec(firstresult=True)
def pytest_doctest_prepare_content(content):
""" return processed content for a given doctest"""
""" return processed content for a given doctest

Stops at first non-None result, see :ref:`firstresult` """

# -------------------------------------------------------------------------
# error handling and internal debugging hooks
Expand Down
1 change: 1 addition & 0 deletions changelog/2493.doc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Explicitly state for which hooks the calls stop after the first non-None result.
6 changes: 4 additions & 2 deletions doc/en/writing_plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,11 @@ if ``myapp.testsupport.myplugin`` also declares ``pytest_plugins``, the contents
of the variable will also be loaded as plugins, and so on.

This mechanism makes it easy to share fixtures within applications or even
external applications without the need to create external plugins using
external applications without the need to create external plugins using
the ``setuptools``'s entry point technique.

Plugins imported by ``pytest_plugins`` will also automatically be marked
for assertion rewriting (see :func:`pytest.register_assert_rewrite`).
for assertion rewriting (see :func:`pytest.register_assert_rewrite`).
However for this to have any effect the module must not be
imported already; if it was already imported at the time the
``pytest_plugins`` statement is processed, a warning will result and
Expand Down Expand Up @@ -357,6 +357,8 @@ allowed to raise exceptions. Doing so will break the pytest run.



.. _firstresult:

firstresult: stop at first non-None result
-------------------------------------------

Expand Down