From bddc88f09e26051784712a9948af938517ef0546 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Wed, 6 May 2015 10:08:08 +0200 Subject: [PATCH] adapt to pluggy naming, rename pytest.hookspec_opts to pytest.hookspec,s ame with hookimpl_opts --HG-- branch : pluggy1 --- CHANGELOG | 4 ++-- _pytest/capture.py | 14 ++++++------ _pytest/config.py | 14 ++++++------ _pytest/helpconfig.py | 2 +- _pytest/hookspec.py | 44 +++++++++++++++++++------------------- _pytest/main.py | 4 ++-- _pytest/nose.py | 2 +- _pytest/pastebin.py | 2 +- _pytest/pytester.py | 2 +- _pytest/python.py | 6 +++--- _pytest/skipping.py | 4 ++-- _pytest/terminal.py | 4 ++-- _pytest/unittest.py | 4 ++-- doc/en/example/markers.txt | 8 +++---- doc/en/example/simple.txt | 4 ++-- doc/en/writing_plugins.txt | 30 +++++++++++++++----------- pytest.py | 2 +- testing/python/collect.py | 2 +- testing/test_helpconfig.py | 2 +- testing/test_mark.py | 2 +- 20 files changed, 81 insertions(+), 75 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a2d0b6fa9..04f79487e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -27,8 +27,8 @@ details like especially the pluginmanager.add_shutdown() API. Thanks Holger Krekel. -- pluginmanagement: introduce ``pytest.hookimpl_opts`` and - ``pytest.hookspec_opts`` decorators for setting impl/spec +- pluginmanagement: introduce ``pytest.hookimpl`` and + ``pytest.hookspec`` decorators for setting impl/spec specific parameters. This substitutes the previous now deprecated use of ``pytest.mark`` which is meant to contain markers for test functions only. diff --git a/_pytest/capture.py b/_pytest/capture.py index 613289e2a..855b99bde 100644 --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -29,7 +29,7 @@ def pytest_addoption(parser): help="shortcut for --capture=no.") -@pytest.hookimpl_opts(hookwrapper=True) +@pytest.hookimpl(hookwrapper=True) def pytest_load_initial_conftests(early_config, parser, args): ns = early_config.known_args_namespace pluginmanager = early_config.pluginmanager @@ -101,7 +101,7 @@ class CaptureManager: if capfuncarg is not None: capfuncarg.close() - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_make_collect_report(self, collector): if isinstance(collector, pytest.File): self.resumecapture() @@ -115,13 +115,13 @@ class CaptureManager: else: yield - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_runtest_setup(self, item): self.resumecapture() yield self.suspendcapture_item(item, "setup") - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_runtest_call(self, item): self.resumecapture() self.activate_funcargs(item) @@ -129,17 +129,17 @@ class CaptureManager: #self.deactivate_funcargs() called from suspendcapture() self.suspendcapture_item(item, "call") - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_runtest_teardown(self, item): self.resumecapture() yield self.suspendcapture_item(item, "teardown") - @pytest.hookimpl_opts(tryfirst=True) + @pytest.hookimpl(tryfirst=True) def pytest_keyboard_interrupt(self, excinfo): self.reset_capturings() - @pytest.hookimpl_opts(tryfirst=True) + @pytest.hookimpl(tryfirst=True) def pytest_internalerror(self, excinfo): self.reset_capturings() diff --git a/_pytest/config.py b/_pytest/config.py index 1f68742eb..ccab94747 100644 --- a/_pytest/config.py +++ b/_pytest/config.py @@ -8,11 +8,11 @@ import warnings import py # DON't import pytest here because it causes import cycle troubles import sys, os -from _pytest import hookspec # the extension point definitions -from pluggy import PluginManager, HookimplDecorator, HookspecDecorator +import _pytest.hookspec # the extension point definitions +from pluggy import PluginManager, HookimplMarker, HookspecMarker -hookimpl_opts = HookimplDecorator("pytest") -hookspec_opts = HookspecDecorator("pytest") +hookimpl = HookimplMarker("pytest") +hookspec = HookspecMarker("pytest") # pytest startup # @@ -121,7 +121,7 @@ class PytestPluginManager(PluginManager): self._conftestpath2mod = {} self._confcutdir = None - self.add_hookspecs(hookspec) + self.add_hookspecs(_pytest.hookspec) self.register(self) if os.environ.get('PYTEST_DEBUG'): err = sys.stderr @@ -184,7 +184,7 @@ class PytestPluginManager(PluginManager): return self.get_plugin(name) def pytest_configure(self, config): - # XXX now that the pluginmanager exposes hookimpl_opts(tryfirst...) + # XXX now that the pluginmanager exposes hookimpl(tryfirst...) # we should remove tryfirst/trylast as markers config.addinivalue_line("markers", "tryfirst: mark a hook implementation function such that the " @@ -827,7 +827,7 @@ class Config(object): if not hasattr(self.option, opt.dest): setattr(self.option, opt.dest, opt.default) - @hookimpl_opts(trylast=True) + @hookimpl(trylast=True) def pytest_load_initial_conftests(self, early_config): self.pluginmanager._set_initial_conftests(early_config.known_args_namespace) diff --git a/_pytest/helpconfig.py b/_pytest/helpconfig.py index edbb9159b..d410c6270 100644 --- a/_pytest/helpconfig.py +++ b/_pytest/helpconfig.py @@ -22,7 +22,7 @@ def pytest_addoption(parser): help="store internal tracing debug information in 'pytestdebug.log'.") -@pytest.hookimpl_opts(hookwrapper=True) +@pytest.hookimpl(hookwrapper=True) def pytest_cmdline_parse(): outcome = yield config = outcome.get_result() diff --git a/_pytest/hookspec.py b/_pytest/hookspec.py index 606ff3108..c75f563f4 100644 --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -1,32 +1,32 @@ """ hook specifications for pytest plugins, invoked from main.py and builtin plugins. """ -from pluggy import HookspecDecorator +from pluggy import HookspecMarker -hookspec_opts = HookspecDecorator("pytest") +hookspec = HookspecMarker("pytest") # ------------------------------------------------------------------------- # Initialization hooks called for every plugin # ------------------------------------------------------------------------- -@hookspec_opts(historic=True) +@hookspec(historic=True) def pytest_addhooks(pluginmanager): """called at plugin registration time to allow adding new hooks via a call to - pluginmanager.addhooks(module_or_class, prefix).""" + pluginmanager.add_hookspecs(module_or_class, prefix).""" -@hookspec_opts(historic=True) +@hookspec(historic=True) def pytest_namespace(): """return dict of name->object to be made globally available in the pytest namespace. This hook is called at plugin registration time. """ -@hookspec_opts(historic=True) +@hookspec(historic=True) def pytest_plugin_registered(plugin, manager): """ a new pytest plugin got registered. """ -@hookspec_opts(historic=True) +@hookspec(historic=True) def pytest_addoption(parser): """register argparse-style options and ini-style config values. @@ -52,7 +52,7 @@ def pytest_addoption(parser): via (deprecated) ``pytest.config``. """ -@hookspec_opts(historic=True) +@hookspec(historic=True) def pytest_configure(config): """ called after command line options have been parsed and all plugins and initial conftest files been loaded. @@ -65,14 +65,14 @@ def pytest_configure(config): # discoverable conftest.py local plugins. # ------------------------------------------------------------------------- -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_cmdline_parse(pluginmanager, args): """return initialized config object, parsing the specified args. """ def pytest_cmdline_preparse(config, args): """(deprecated) modify command line arguments before option parsing. """ -@hookspec_opts(firstresult=True) +@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. """ @@ -86,7 +86,7 @@ def pytest_load_initial_conftests(args, early_config, parser): # collection hooks # ------------------------------------------------------------------------- -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_collection(session): """ perform the collection protocol for the given session. """ @@ -97,14 +97,14 @@ def pytest_collection_modifyitems(session, config, items): def pytest_collection_finish(session): """ called after collection has been performed and modified. """ -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) 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. """ -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_collect_directory(path, parent): """ called before traversing a directory for collection files. """ @@ -125,7 +125,7 @@ def pytest_collectreport(report): def pytest_deselected(items): """ called for test items deselected by keyword. """ -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_make_collect_report(collector): """ perform ``collector.collect()`` and return a CollectReport. """ @@ -133,7 +133,7 @@ def pytest_make_collect_report(collector): # Python test function related hooks # ------------------------------------------------------------------------- -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_pycollect_makemodule(path, parent): """ return a Module collector or None for the given path. This hook will be called for each matching test module path. @@ -141,11 +141,11 @@ def pytest_pycollect_makemodule(path, parent): create test modules for files that do not match as a test module. """ -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_pycollect_makeitem(collector, name, obj): """ return custom item/collector for a python object in a module, or None. """ -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_pyfunc_call(pyfuncitem): """ call underlying test function. """ @@ -156,7 +156,7 @@ def pytest_generate_tests(metafunc): # generic runtest related hooks # ------------------------------------------------------------------------- -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_runtestloop(session): """ called for performing the main runtest loop (after collection finished). """ @@ -164,7 +164,7 @@ def pytest_runtestloop(session): def pytest_itemstart(item, node): """ (deprecated, use pytest_runtest_logstart). """ -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_runtest_protocol(item, nextitem): """ implements the runtest_setup/call/teardown protocol for the given test item, including capturing exceptions and calling @@ -197,7 +197,7 @@ def pytest_runtest_teardown(item, nextitem): so that nextitem only needs to call setup-functions. """ -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_runtest_makereport(item, call): """ return a :py:class:`_pytest.runner.TestReport` object for the given :py:class:`pytest.Item` and @@ -242,7 +242,7 @@ def pytest_assertrepr_compare(config, op, left, right): def pytest_report_header(config, startdir): """ return a string to be displayed as header info for terminal reporting.""" -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_report_teststatus(report): """ return result-category, shortletter and verbose word for reporting.""" @@ -258,7 +258,7 @@ def pytest_logwarning(message, code, nodeid, fslocation): # doctest hooks # ------------------------------------------------------------------------- -@hookspec_opts(firstresult=True) +@hookspec(firstresult=True) def pytest_doctest_prepare_content(content): """ return processed content for a given doctest""" diff --git a/_pytest/main.py b/_pytest/main.py index 55ba78b5f..f9566712e 100644 --- a/_pytest/main.py +++ b/_pytest/main.py @@ -512,12 +512,12 @@ class Session(FSCollector): def _makeid(self): return "" - @pytest.hookimpl_opts(tryfirst=True) + @pytest.hookimpl(tryfirst=True) def pytest_collectstart(self): if self.shouldstop: raise self.Interrupted(self.shouldstop) - @pytest.hookimpl_opts(tryfirst=True) + @pytest.hookimpl(tryfirst=True) def pytest_runtest_logreport(self, report): if report.failed and not hasattr(report, 'wasxfail'): self._testsfailed += 1 diff --git a/_pytest/nose.py b/_pytest/nose.py index feb6b8b90..038746868 100644 --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -24,7 +24,7 @@ def pytest_runtest_makereport(item, call): call.excinfo = call2.excinfo -@pytest.hookimpl_opts(trylast=True) +@pytest.hookimpl(trylast=True) def pytest_runtest_setup(item): if is_potential_nosetest(item): if isinstance(item.parent, pytest.Generator): diff --git a/_pytest/pastebin.py b/_pytest/pastebin.py index b1d973c2e..f76d14a2f 100644 --- a/_pytest/pastebin.py +++ b/_pytest/pastebin.py @@ -11,7 +11,7 @@ def pytest_addoption(parser): choices=['failed', 'all'], help="send failed|all info to bpaste.net pastebin service.") -@pytest.hookimpl_opts(trylast=True) +@pytest.hookimpl(trylast=True) def pytest_configure(config): if config.option.pastebin == "all": tr = config.pluginmanager.getplugin('terminalreporter') diff --git a/_pytest/pytester.py b/_pytest/pytester.py index ee83bee20..baddc913c 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -80,7 +80,7 @@ class LsofFdLeakChecker(object): else: return True - @pytest.hookimpl_opts(hookwrapper=True, tryfirst=True) + @pytest.hookimpl(hookwrapper=True, tryfirst=True) def pytest_runtest_item(self, item): lines1 = self.get_open_files() yield diff --git a/_pytest/python.py b/_pytest/python.py index 73cce4b32..e0fb292c7 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -181,7 +181,7 @@ def pytest_configure(config): def pytest_sessionstart(session): session._fixturemanager = FixtureManager(session) -@pytest.hookimpl_opts(trylast=True) +@pytest.hookimpl(trylast=True) def pytest_namespace(): raises.Exception = pytest.fail.Exception return { @@ -200,7 +200,7 @@ def pytestconfig(request): return request.config -@pytest.hookimpl_opts(trylast=True) +@pytest.hookimpl(trylast=True) def pytest_pyfunc_call(pyfuncitem): testfunction = pyfuncitem.obj if pyfuncitem._isyieldedfunction(): @@ -228,7 +228,7 @@ def pytest_collect_file(path, parent): def pytest_pycollect_makemodule(path, parent): return Module(path, parent) -@pytest.hookimpl_opts(hookwrapper=True) +@pytest.hookimpl(hookwrapper=True) def pytest_pycollect_makeitem(collector, name, obj): outcome = yield res = outcome.get_result() diff --git a/_pytest/skipping.py b/_pytest/skipping.py index db320349c..31f807503 100644 --- a/_pytest/skipping.py +++ b/_pytest/skipping.py @@ -133,7 +133,7 @@ class MarkEvaluator: return expl -@pytest.hookimpl_opts(tryfirst=True) +@pytest.hookimpl(tryfirst=True) def pytest_runtest_setup(item): evalskip = MarkEvaluator(item, 'skipif') if evalskip.istrue(): @@ -151,7 +151,7 @@ def check_xfail_no_run(item): if not evalxfail.get('run', True): pytest.xfail("[NOTRUN] " + evalxfail.getexplanation()) -@pytest.hookimpl_opts(hookwrapper=True) +@pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): outcome = yield rep = outcome.get_result() diff --git a/_pytest/terminal.py b/_pytest/terminal.py index cca947bb7..1eebfd48c 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -268,7 +268,7 @@ class TerminalReporter: def pytest_collection_modifyitems(self): self.report_collect(True) - @pytest.hookimpl_opts(trylast=True) + @pytest.hookimpl(trylast=True) def pytest_sessionstart(self, session): self._sessionstarttime = time.time() if not self.showheader: @@ -355,7 +355,7 @@ class TerminalReporter: indent = (len(stack) - 1) * " " self._tw.line("%s%s" % (indent, col)) - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_sessionfinish(self, exitstatus): outcome = yield outcome.get_result() diff --git a/_pytest/unittest.py b/_pytest/unittest.py index f082d7195..064cec85b 100644 --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -140,7 +140,7 @@ class TestCaseFunction(pytest.Function): if traceback: excinfo.traceback = traceback -@pytest.hookimpl_opts(tryfirst=True) +@pytest.hookimpl(tryfirst=True) def pytest_runtest_makereport(item, call): if isinstance(item, TestCaseFunction): if item._excinfo: @@ -152,7 +152,7 @@ def pytest_runtest_makereport(item, call): # twisted trial support -@pytest.hookimpl_opts(hookwrapper=True) +@pytest.hookimpl(hookwrapper=True) def pytest_runtest_protocol(item): if isinstance(item, TestCaseFunction) and \ 'twisted.trial.unittest' in sys.modules: diff --git a/doc/en/example/markers.txt b/doc/en/example/markers.txt index cb92390b3..e90c86393 100644 --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -201,9 +201,9 @@ You can ask which markers exist for your test suite - the list includes our just @pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures - @pytest.hookimpl_opts(tryfirst=True): mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. + @pytest.hookimpl(tryfirst=True): mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. - @pytest.hookimpl_opts(trylast=True): mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. + @pytest.hookimpl(trylast=True): mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. For an example on how to add and work with markers from a plugin, see @@ -375,9 +375,9 @@ The ``--markers`` option always gives you a list of available markers:: @pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures - @pytest.hookimpl_opts(tryfirst=True): mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. + @pytest.hookimpl(tryfirst=True): mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible. - @pytest.hookimpl_opts(trylast=True): mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. + @pytest.hookimpl(trylast=True): mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible. Reading markers which were set from multiple places diff --git a/doc/en/example/simple.txt b/doc/en/example/simple.txt index f7a3b7eab..2e1a5b24f 100644 --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -534,7 +534,7 @@ case we just write some informations out to a ``failures`` file:: import pytest import os.path - @pytest.hookimpl_opts(tryfirst=True) + @pytest.hookimpl(tryfirst=True) def pytest_runtest_makereport(item, call, __multicall__): # execute all other hooks to obtain the report object rep = __multicall__.execute() @@ -607,7 +607,7 @@ here is a little example implemented via a local plugin:: import pytest - @pytest.hookimpl_opts(tryfirst=True) + @pytest.hookimpl(tryfirst=True) def pytest_runtest_makereport(item, call, __multicall__): # execute all other hooks to obtain the report object rep = __multicall__.execute() diff --git a/doc/en/writing_plugins.txt b/doc/en/writing_plugins.txt index 9f09fea9a..9f201931f 100644 --- a/doc/en/writing_plugins.txt +++ b/doc/en/writing_plugins.txt @@ -292,7 +292,7 @@ Here is an example definition of a hook wrapper:: import pytest - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_pyfunc_call(pyfuncitem): # do whatever you want before the next hook executes @@ -305,8 +305,7 @@ Here is an example definition of a hook wrapper:: Note that hook wrappers don't return results themselves, they merely perform tracing or other side effects around the actual hook implementations. If the result of the underlying hook is a mutable object, they may modify -that result, however. - +that result but it's probably better to avoid it. Hook function ordering / call example @@ -338,16 +337,24 @@ after others, i.e. the position in the ``N``-sized list of functions:: Here is the order of execution: 1. Plugin3's pytest_collection_modifyitems called until the yield point -2. Plugin1's pytest_collection_modifyitems is called -3. Plugin2's pytest_collection_modifyitems is called -4. Plugin3's pytest_collection_modifyitems called for executing after the yield - The yield receives a :py:class:`CallOutcome` instance which encapsulates - the result from calling the non-wrappers. Wrappers cannot modify the result. + because it is a hook wrapper. + +2. Plugin1's pytest_collection_modifyitems is called because it is marked + with ``tryfirst=True``. + +3. Plugin2's pytest_collection_modifyitems is called because it is marked + with ``trylast=True`` (but even without this mark it would come after + Plugin1). + +4. Plugin3's pytest_collection_modifyitems then executing the code after the yield + point. The yield receives a :py:class:`CallOutcome` instance which encapsulates + the result from calling the non-wrappers. Wrappers shall not modify the result. It's possible to use ``tryfirst`` and ``trylast`` also in conjunction with ``hookwrapper=True`` in which case it will influence the ordering of hookwrappers among each other. + Declaring new hooks ------------------------ @@ -368,11 +375,11 @@ For an example, see `newhooks.py`_ from :ref:`xdist`. .. _`newhooks.py`: https://bitbucket.org/pytest-dev/pytest-xdist/src/52082f70e7dd04b00361091b8af906c60fd6700f/xdist/newhooks.py?at=default -Using hooks from 3rd party plugins -------------------------------------- +Optionally using hooks from 3rd party plugins +--------------------------------------------- Using new hooks from plugins as explained above might be a little tricky -because the standard :ref:`validation mechanism `: +because of the standard :ref:`validation mechanism `: if you depend on a plugin that is not installed, validation will fail and the error message will not make much sense to your users. @@ -395,7 +402,6 @@ declaring the hook functions directly in your plugin module, for example:: This has the added benefit of allowing you to conditionally install hooks depending on which plugins are installed. - .. _`well specified hooks`: .. currentmodule:: _pytest.hookspec diff --git a/pytest.py b/pytest.py index b72563dfb..8549ba781 100644 --- a/pytest.py +++ b/pytest.py @@ -13,7 +13,7 @@ if __name__ == '__main__': # if run as a script or by 'python -m pytest' from _pytest.config import ( main, UsageError, _preloadplugins, cmdline, - hookspec_opts, hookimpl_opts + hookspec, hookimpl ) from _pytest import __version__ diff --git a/testing/python/collect.py b/testing/python/collect.py index 15b7c2db3..67dc99c8b 100644 --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -559,7 +559,7 @@ class TestConftestCustomization: b = testdir.mkdir("a").mkdir("b") b.join("conftest.py").write(py.code.Source(""" import pytest - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_pycollect_makeitem(): outcome = yield if outcome.excinfo is None: diff --git a/testing/test_helpconfig.py b/testing/test_helpconfig.py index 10041aa78..d9cb52bcb 100644 --- a/testing/test_helpconfig.py +++ b/testing/test_helpconfig.py @@ -38,7 +38,7 @@ def test_hookvalidation_unknown(testdir): def test_hookvalidation_optional(testdir): testdir.makeconftest(""" import pytest - @pytest.hookimpl_opts(optionalhook=True) + @pytest.hookimpl(optionalhook=True) def pytest_hello(xyz): pass """) diff --git a/testing/test_mark.py b/testing/test_mark.py index ed3bebcae..eb2e10f3d 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -510,7 +510,7 @@ class TestKeywordSelection: """) testdir.makepyfile(conftest=""" import pytest - @pytest.hookimpl_opts(hookwrapper=True) + @pytest.hookimpl(hookwrapper=True) def pytest_pycollect_makeitem(name): outcome = yield if name == "TestClass":