diff --git a/changelog/3078.removal.rst b/changelog/3078.removal.rst new file mode 100644 index 000000000..8f90811c3 --- /dev/null +++ b/changelog/3078.removal.rst @@ -0,0 +1,3 @@ +Remove legacy internal warnings system: ``config.warn``, ``Node.warn``. The ``pytest_logwarning`` now issues a warning when implemented. + +See our `docs `__ on information on how to update your code. diff --git a/doc/en/deprecations.rst b/doc/en/deprecations.rst index a2f16d974..f36423ad6 100644 --- a/doc/en/deprecations.rst +++ b/doc/en/deprecations.rst @@ -74,34 +74,6 @@ Becomes: -``Config.warn`` and ``Node.warn`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. deprecated:: 3.8 - -Those methods were part of the internal pytest warnings system, but since ``3.8`` pytest is using the builtin warning -system for its own warnings, so those two functions are now deprecated. - -``Config.warn`` should be replaced by calls to the standard ``warnings.warn``, example: - -.. code-block:: python - - config.warn("C1", "some warning") - -Becomes: - -.. code-block:: python - - warnings.warn(pytest.PytestWarning("some warning")) - -``Node.warn`` now supports two signatures: - -* ``node.warn(PytestWarning("some message"))``: is now the **recommended** way to call this function. - The warning instance must be a PytestWarning or subclass. - -* ``node.warn("CI", "some message")``: this code/message form is now **deprecated** and should be converted to the warning instance form above. - - Calling fixtures directly ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -350,7 +322,33 @@ This should be updated to make use of standard fixture mechanisms: You can consult `funcarg comparison section in the docs `_ for more information. -This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings. + +``Config.warn`` and ``Node.warn`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*Removed in version 4.0.* + +Those methods were part of the internal pytest warnings system, but since ``3.8`` pytest is using the builtin warning +system for its own warnings, so those two functions are now deprecated. + +``Config.warn`` should be replaced by calls to the standard ``warnings.warn``, example: + +.. code-block:: python + + config.warn("C1", "some warning") + +Becomes: + +.. code-block:: python + + warnings.warn(pytest.PytestWarning("some warning")) + +``Node.warn`` now supports two signatures: + +* ``node.warn(PytestWarning("some message"))``: is now the **recommended** way to call this function. + The warning instance must be a PytestWarning or subclass. + +* ``node.warn("CI", "some message")``: this code/message form has been **removed** and should be converted to the warning instance form above. ``yield`` tests ~~~~~~~~~~~~~~~ diff --git a/doc/en/reference.rst b/doc/en/reference.rst index da53e7fea..754035d16 100644 --- a/doc/en/reference.rst +++ b/doc/en/reference.rst @@ -618,7 +618,6 @@ Session related reporting hooks: .. autofunction:: pytest_terminal_summary .. autofunction:: pytest_fixture_setup .. autofunction:: pytest_fixture_post_finalizer -.. autofunction:: pytest_logwarning .. autofunction:: pytest_warning_captured And here is the central hook for reporting about diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index 78b8edcd8..1d2c27ed1 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -278,11 +278,11 @@ class AssertionRewritingHook(object): def _warn_already_imported(self, name): from _pytest.warning_types import PytestWarning - from _pytest.warnings import _issue_config_warning + from _pytest.warnings import _issue_warning_captured - _issue_config_warning( + _issue_warning_captured( PytestWarning("Module already imported so cannot be rewritten: %s" % name), - self.config, + self.config.hook, stacklevel=5, ) diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 59265ad85..87b2e5426 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -59,12 +59,12 @@ class Cache(object): return resolve_from_str(config.getini("cache_dir"), config.rootdir) def warn(self, fmt, **args): - from _pytest.warnings import _issue_config_warning + from _pytest.warnings import _issue_warning_captured from _pytest.warning_types import PytestWarning - _issue_config_warning( + _issue_warning_captured( PytestWarning(fmt.format(**args) if args else fmt), - self._config, + self._config.hook, stacklevel=3, ) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index fafd8c930..248ed5857 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -26,11 +26,13 @@ from .exceptions import PrintHelp from .exceptions import UsageError from .findpaths import determine_setup from .findpaths import exists +from _pytest import deprecated from _pytest._code import ExceptionInfo from _pytest._code import filter_traceback from _pytest.compat import lru_cache from _pytest.compat import safe_str from _pytest.outcomes import Skipped +from _pytest.warning_types import PytestWarning hookimpl = HookimplMarker("pytest") hookspec = HookspecMarker("pytest") @@ -189,9 +191,9 @@ def _prepareconfig(args=None, plugins=None): else: pluginmanager.register(plugin) if warning: - from _pytest.warnings import _issue_config_warning + from _pytest.warnings import _issue_warning_captured - _issue_config_warning(warning, config=config, stacklevel=4) + _issue_warning_captured(warning, hook=config.hook, stacklevel=4) return pluginmanager.hook.pytest_cmdline_parse( pluginmanager=pluginmanager, args=args ) @@ -245,14 +247,7 @@ class PytestPluginManager(PluginManager): Use :py:meth:`pluggy.PluginManager.add_hookspecs ` instead. """ - warning = dict( - code="I2", - fslocation=_pytest._code.getfslineno(sys._getframe(1)), - nodeid=None, - message="use pluginmanager.add_hookspecs instead of " - "deprecated addhooks() method.", - ) - self._warn(warning) + warnings.warn(deprecated.PLUGIN_MANAGER_ADDHOOKS, stacklevel=2) return self.add_hookspecs(module_or_class) def parse_hookimpl_opts(self, plugin, name): @@ -296,10 +291,12 @@ class PytestPluginManager(PluginManager): def register(self, plugin, name=None): if name in ["pytest_catchlog", "pytest_capturelog"]: - self._warn( - "{} plugin has been merged into the core, " - "please remove it from your requirements.".format( - name.replace("_", "-") + warnings.warn( + PytestWarning( + "{} plugin has been merged into the core, " + "please remove it from your requirements.".format( + name.replace("_", "-") + ) ) ) return @@ -336,14 +333,6 @@ class PytestPluginManager(PluginManager): ) self._configured = True - def _warn(self, message): - kwargs = ( - message - if isinstance(message, dict) - else {"code": "I1", "message": message, "fslocation": None, "nodeid": None} - ) - self.hook.pytest_logwarning.call_historic(kwargs=kwargs) - # # internal API for local conftest plugin handling # @@ -542,7 +531,13 @@ class PytestPluginManager(PluginManager): six.reraise(new_exc_type, new_exc, sys.exc_info()[2]) except Skipped as e: - self._warn("skipped plugin %r: %s" % ((modname, e.msg))) + from _pytest.warnings import _issue_warning_captured + + _issue_warning_captured( + PytestWarning("skipped plugin %r: %s" % (modname, e.msg)), + self.hook, + stacklevel=1, + ) else: mod = sys.modules[importspec] self.register(mod, modname) @@ -617,7 +612,6 @@ class Config(object): self._override_ini = () self._opt2dest = {} self._cleanup = [] - self._warn = self.pluginmanager._warn self.pluginmanager.register(self, "pytestconfig") self._configured = False self.invocation_dir = py.path.local() @@ -642,36 +636,6 @@ class Config(object): fin = self._cleanup.pop() fin() - def warn(self, code, message, fslocation=None, nodeid=None): - """ - .. deprecated:: 3.8 - - Use :py:func:`warnings.warn` or :py:func:`warnings.warn_explicit` directly instead. - - Generate a warning for this test session. - """ - from _pytest.warning_types import RemovedInPytest4Warning - - if isinstance(fslocation, (tuple, list)) and len(fslocation) > 2: - filename, lineno = fslocation[:2] - else: - filename = "unknown file" - lineno = 0 - msg = "config.warn has been deprecated, use warnings.warn instead" - if nodeid: - msg = "{}: {}".format(nodeid, msg) - warnings.warn_explicit( - RemovedInPytest4Warning(msg), - category=None, - filename=filename, - lineno=lineno, - ) - self.hook.pytest_logwarning.call_historic( - kwargs=dict( - code=code, message=message, fslocation=fslocation, nodeid=nodeid - ) - ) - def get_terminal_writer(self): return self.pluginmanager.get_plugin("terminalreporter")._tw @@ -826,7 +790,15 @@ class Config(object): if ns.help or ns.version: # we don't want to prevent --help/--version to work # so just let is pass and print a warning at the end - self._warn("could not load initial conftests (%s)\n" % e.path) + from _pytest.warnings import _issue_warning_captured + + _issue_warning_captured( + PytestWarning( + "could not load initial conftests: {}".format(e.path) + ), + self.hook, + stacklevel=2, + ) else: raise diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index 169b8ddfc..eecc92606 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -34,14 +34,14 @@ def getcfg(args, config=None): iniconfig = py.iniconfig.IniConfig(p) if "pytest" in iniconfig.sections: if inibasename == "setup.cfg" and config is not None: - from _pytest.warnings import _issue_config_warning + from _pytest.warnings import _issue_warning_captured from _pytest.warning_types import RemovedInPytest4Warning - _issue_config_warning( + _issue_warning_captured( RemovedInPytest4Warning( CFG_PYTEST_SECTION.format(filename=inibasename) ), - config=config, + hook=config.hook, stacklevel=2, ) return base, p, iniconfig["pytest"] @@ -112,13 +112,13 @@ def determine_setup(inifile, args, rootdir_cmd_arg=None, config=None): inicfg = iniconfig[section] if is_cfg_file and section == "pytest" and config is not None: from _pytest.deprecated import CFG_PYTEST_SECTION - from _pytest.warnings import _issue_config_warning + from _pytest.warnings import _issue_warning_captured # TODO: [pytest] section in *.cfg files is deprecated. Need refactoring once # the deprecation expires. - _issue_config_warning( + _issue_warning_captured( CFG_PYTEST_SECTION.format(filename=str(inifile)), - config, + config.hook, stacklevel=2, ) break diff --git a/src/_pytest/deprecated.py b/src/_pytest/deprecated.py index 426533a0c..4136328e1 100644 --- a/src/_pytest/deprecated.py +++ b/src/_pytest/deprecated.py @@ -75,10 +75,6 @@ MARK_PARAMETERSET_UNPACKING = RemovedInPytest4Warning( "For more details, see: https://docs.pytest.org/en/latest/parametrize.html" ) -NODE_WARN = RemovedInPytest4Warning( - "Node.warn(code, message) form has been deprecated, use Node.warn(warning_instance) instead." -) - RAISES_EXEC = PytestDeprecationWarning( "raises(..., 'code(as_a_string)') is deprecated, use the context manager form or use `exec()` directly\n\n" "See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec" @@ -94,6 +90,13 @@ RECORD_XML_PROPERTY = RemovedInPytest4Warning( '"record_xml_property" is now deprecated.' ) +PLUGIN_MANAGER_ADDHOOKS = PytestDeprecationWarning( + "use pluginmanager.add_hookspecs instead of deprecated addhooks() method." +) + +COLLECTOR_MAKEITEM = RemovedInPytest4Warning( + "pycollector makeitem was removed as it is an accidentially leaked internal api" +) PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = RemovedInPytest4Warning( "Defining pytest_plugins in a non-top-level conftest is deprecated, " @@ -110,3 +113,8 @@ PYTEST_ENSURETEMP = RemovedInPytest4Warning( "pytest/tmpdir_factory.ensuretemp is deprecated, \n" "please use the tmp_path fixture or tmp_path_factory.mktemp" ) + +PYTEST_LOGWARNING = PytestDeprecationWarning( + "pytest_logwarning is deprecated, no longer being called, and will be removed soon\n" + "please use pytest_warning_captured instead" +) diff --git a/src/_pytest/hookspec.py b/src/_pytest/hookspec.py index 0d9f039a1..2dfbfd0c9 100644 --- a/src/_pytest/hookspec.py +++ b/src/_pytest/hookspec.py @@ -1,6 +1,8 @@ """ hook specifications for pytest plugins, invoked from main.py and builtin plugins. """ from pluggy import HookspecMarker +from _pytest.deprecated import PYTEST_LOGWARNING + hookspec = HookspecMarker("pytest") @@ -496,7 +498,7 @@ def pytest_terminal_summary(terminalreporter, exitstatus): """ -@hookspec(historic=True) +@hookspec(historic=True, warn_on_impl=PYTEST_LOGWARNING) def pytest_logwarning(message, code, nodeid, fslocation): """ .. deprecated:: 3.8 diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 1b41898c4..b324b1f68 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -105,74 +105,7 @@ class Node(object): def __repr__(self): return "<%s %s>" % (self.__class__.__name__, getattr(self, "name", None)) - def warn(self, _code_or_warning=None, message=None, code=None): - """Issue a warning for this item. - - Warnings will be displayed after the test session, unless explicitly suppressed. - - This can be called in two forms: - - **Warning instance** - - This was introduced in pytest 3.8 and uses the standard warning mechanism to issue warnings. - - .. code-block:: python - - node.warn(PytestWarning("some message")) - - The warning instance must be a subclass of :class:`pytest.PytestWarning`. - - **code/message (deprecated)** - - This form was used in pytest prior to 3.8 and is considered deprecated. Using this form will emit another - warning about the deprecation: - - .. code-block:: python - - node.warn("CI", "some message") - - :param Union[Warning,str] _code_or_warning: - warning instance or warning code (legacy). This parameter receives an underscore for backward - compatibility with the legacy code/message form, and will be replaced for something - more usual when the legacy form is removed. - - :param Union[str,None] message: message to display when called in the legacy form. - :param str code: code for the warning, in legacy form when using keyword arguments. - :return: - """ - if message is None: - if _code_or_warning is None: - raise ValueError("code_or_warning must be given") - self._std_warn(_code_or_warning) - else: - if _code_or_warning and code: - raise ValueError( - "code_or_warning and code cannot both be passed to this function" - ) - code = _code_or_warning or code - self._legacy_warn(code, message) - - def _legacy_warn(self, code, message): - """ - .. deprecated:: 3.8 - - Use :meth:`Node.std_warn <_pytest.nodes.Node.std_warn>` instead. - - Generate a warning with the given code and message for this item. - """ - from _pytest.deprecated import NODE_WARN - - self._std_warn(NODE_WARN) - - assert isinstance(code, str) - fslocation = get_fslocation_from_item(self) - self.ihook.pytest_logwarning.call_historic( - kwargs=dict( - code=code, message=message, nodeid=self.nodeid, fslocation=fslocation - ) - ) - - def _std_warn(self, warning): + def warn(self, warning): """Issue a warning for this item. Warnings will be displayed after the test session, unless explicitly suppressed @@ -180,6 +113,12 @@ class Node(object): :param Warning warning: the warning instance to issue. Must be a subclass of PytestWarning. :raise ValueError: if ``warning`` instance is not a subclass of PytestWarning. + + Example usage:: + + .. code-block:: python + + node.warn(PytestWarning("some message")) """ from _pytest.warning_types import PytestWarning diff --git a/src/_pytest/resultlog.py b/src/_pytest/resultlog.py index ab2d0f98b..bdf8130fd 100644 --- a/src/_pytest/resultlog.py +++ b/src/_pytest/resultlog.py @@ -34,9 +34,9 @@ def pytest_configure(config): config.pluginmanager.register(config._resultlog) from _pytest.deprecated import RESULT_LOG - from _pytest.warnings import _issue_config_warning + from _pytest.warnings import _issue_warning_captured - _issue_config_warning(RESULT_LOG, config, stacklevel=2) + _issue_warning_captured(RESULT_LOG, config.hook, stacklevel=2) def pytest_unconfigure(config): diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 1137d52b8..82719b5d4 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -186,20 +186,17 @@ def pytest_report_teststatus(report): @attr.s class WarningReport(object): """ - Simple structure to hold warnings information captured by ``pytest_logwarning`` and ``pytest_warning_captured``. + Simple structure to hold warnings information captured by ``pytest_warning_captured``. :ivar str message: user friendly message about the warning :ivar str|None nodeid: node id that generated the warning (see ``get_location``). :ivar tuple|py.path.local fslocation: file system location of the source of the warning (see ``get_location``). - - :ivar bool legacy: if this warning report was generated from the deprecated ``pytest_logwarning`` hook. """ message = attr.ib() nodeid = attr.ib(default=None) fslocation = attr.ib(default=None) - legacy = attr.ib(default=False) def get_location(self, config): """ @@ -329,13 +326,6 @@ class TerminalReporter(object): self.write_line("INTERNALERROR> " + line) return 1 - def pytest_logwarning(self, fslocation, message, nodeid): - warnings = self.stats.setdefault("warnings", []) - warning = WarningReport( - fslocation=fslocation, message=message, nodeid=nodeid, legacy=True - ) - warnings.append(warning) - def pytest_warning_captured(self, warning_message, item): # from _pytest.nodes import get_fslocation_from_item from _pytest.warnings import warning_record_to_str diff --git a/src/_pytest/warnings.py b/src/_pytest/warnings.py index e3e206933..764985736 100644 --- a/src/_pytest/warnings.py +++ b/src/_pytest/warnings.py @@ -160,19 +160,19 @@ def pytest_terminal_summary(terminalreporter): yield -def _issue_config_warning(warning, config, stacklevel): +def _issue_warning_captured(warning, hook, stacklevel): """ This function should be used instead of calling ``warnings.warn`` directly when we are in the "configure" stage: at this point the actual options might not have been set, so we manually trigger the pytest_warning_captured hook so we can display this warnings in the terminal. This is a hack until we can sort out #2891. :param warning: the warning instance. - :param config: + :param hook: the hook caller :param stacklevel: stacklevel forwarded to warnings.warn """ with warnings.catch_warnings(record=True) as records: warnings.simplefilter("always", type(warning)) warnings.warn(warning, stacklevel=stacklevel) - config.hook.pytest_warning_captured.call_historic( + hook.pytest_warning_captured.call_historic( kwargs=dict(warning_message=records[0], when="config", item=None) ) diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 0b7af5338..f81680d0d 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -146,6 +146,7 @@ class TestGeneralUsage(object): assert result.ret result.stderr.fnmatch_lines(["*ERROR: not found:*{}".format(p2.basename)]) + @pytest.mark.filterwarnings("default") def test_better_reporting_on_conftest_load_failure(self, testdir, request): """Show a user-friendly traceback on conftest import failures (#486, #3332)""" testdir.makepyfile("") diff --git a/testing/deprecated_test.py b/testing/deprecated_test.py index 4353ec2be..c7515d2cb 100644 --- a/testing/deprecated_test.py +++ b/testing/deprecated_test.py @@ -120,6 +120,7 @@ def test_terminal_reporter_writer_attr(pytestconfig): @pytest.mark.parametrize("plugin", ["catchlog", "capturelog"]) +@pytest.mark.filterwarnings("default") def test_pytest_catchlog_deprecated(testdir, plugin): testdir.makepyfile( """ diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index a02433cd6..4187e365b 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -823,7 +823,9 @@ def test_rewritten(): testdir.makepyfile(test_remember_rewritten_modules="") warnings = [] hook = AssertionRewritingHook(pytestconfig) - monkeypatch.setattr(hook.config, "warn", lambda code, msg: warnings.append(msg)) + monkeypatch.setattr( + hook, "_warn_already_imported", lambda code, msg: warnings.append(msg) + ) hook.find_module("test_remember_rewritten_modules") hook.load_module("test_remember_rewritten_modules") hook.mark_rewrite("test_remember_rewritten_modules") diff --git a/testing/test_config.py b/testing/test_config.py index 012b8936c..f757bb018 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -12,7 +12,6 @@ from _pytest.config.findpaths import determine_setup from _pytest.config.findpaths import get_common_ancestor from _pytest.config.findpaths import getcfg from _pytest.main import EXIT_NOTESTSCOLLECTED -from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG class TestParseIni(object): @@ -790,66 +789,6 @@ def test_collect_pytest_prefix_bug(pytestconfig): assert pm.parse_hookimpl_opts(Dummy(), "pytest_something") is None -class TestLegacyWarning(object): - @pytest.mark.filterwarnings("default") - def test_warn_config(self, testdir): - testdir.makeconftest( - """ - values = [] - def pytest_runtest_setup(item): - item.config.warn("C1", "hello") - def pytest_logwarning(code, message): - if message == "hello" and code == "C1": - values.append(1) - """ - ) - testdir.makepyfile( - """ - def test_proper(pytestconfig): - import conftest - assert conftest.values == [1] - """ - ) - result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines( - ["*hello", "*config.warn has been deprecated*", "*1 passed*"] - ) - - @pytest.mark.filterwarnings("default") - @pytest.mark.parametrize("use_kw", [True, False]) - def test_warn_on_test_item_from_request(self, testdir, use_kw): - code_kw = "code=" if use_kw else "" - message_kw = "message=" if use_kw else "" - testdir.makepyfile( - """ - import pytest - - @pytest.fixture - def fix(request): - request.node.warn({code_kw}"T1", {message_kw}"hello") - - def test_hello(fix): - pass - """.format( - code_kw=code_kw, message_kw=message_kw - ) - ) - result = testdir.runpytest( - "--disable-pytest-warnings", SHOW_PYTEST_WARNINGS_ARG - ) - assert "hello" not in result.stdout.str() - - result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG) - result.stdout.fnmatch_lines( - """ - ===*warnings summary*=== - *test_warn_on_test_item_from_request.py::test_hello* - *hello* - *test_warn_on_test_item_from_request.py:7:*Node.warn(code, message) form has been deprecated* - """ - ) - - class TestRootdir(object): def test_simple_noini(self, tmpdir): assert get_common_ancestor([tmpdir]) == tmpdir diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 80ef3db02..80817932e 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -32,7 +32,7 @@ class TestPytestPluginInteractions(object): """ import newhooks def pytest_addhooks(pluginmanager): - pluginmanager.addhooks(newhooks) + pluginmanager.add_hookspecs(newhooks) def pytest_myhook(xyz): return xyz + 1 """ @@ -52,7 +52,7 @@ class TestPytestPluginInteractions(object): """ import sys def pytest_addhooks(pluginmanager): - pluginmanager.addhooks(sys) + pluginmanager.add_hookspecs(sys) """ ) res = testdir.runpytest() @@ -141,23 +141,6 @@ class TestPytestPluginInteractions(object): ihook_b = session.gethookproxy(testdir.tmpdir.join("tests")) assert ihook_a is not ihook_b - def test_warn_on_deprecated_addhooks(self, pytestpm): - warnings = [] - - class get_warnings(object): - def pytest_logwarning(self, code, fslocation, message, nodeid): - warnings.append(message) - - class Plugin(object): - def pytest_testhook(): - pass - - pytestpm.register(get_warnings()) - before = list(warnings) - pytestpm.addhooks(Plugin()) - assert len(warnings) == len(before) + 1 - assert "deprecated" in warnings[-1] - def test_default_markers(testdir): result = testdir.runpytest("--markers") @@ -240,11 +223,12 @@ class TestPytestPluginManager(object): with pytest.raises(ImportError): pytestpm.consider_env() + @pytest.mark.filterwarnings("always") def test_plugin_skip(self, testdir, monkeypatch): p = testdir.makepyfile( skipping1=""" import pytest - pytest.skip("hello") + pytest.skip("hello", allow_module_level=True) """ ) p.copy(p.dirpath("skipping2.py")) diff --git a/testing/test_pytester.py b/testing/test_pytester.py index 0b66acbf2..d14fbd18e 100644 --- a/testing/test_pytester.py +++ b/testing/test_pytester.py @@ -168,7 +168,7 @@ def make_holder(): @pytest.mark.parametrize("holder", make_holder()) def test_hookrecorder_basic(holder): pm = PytestPluginManager() - pm.addhooks(holder) + pm.add_hookspecs(holder) rec = HookRecorder(pm) pm.hook.pytest_xyz(arg=123) call = rec.popcall("pytest_xyz") diff --git a/testing/test_warnings.py b/testing/test_warnings.py index 655c89f4c..3bac9a545 100644 --- a/testing/test_warnings.py +++ b/testing/test_warnings.py @@ -308,9 +308,9 @@ def test_filterwarnings_mark_registration(testdir): def test_warning_captured_hook(testdir): testdir.makeconftest( """ - from _pytest.warnings import _issue_config_warning + from _pytest.warnings import _issue_warning_captured def pytest_configure(config): - _issue_config_warning(UserWarning("config warning"), config, stacklevel=2) + _issue_warning_captured(UserWarning("config warning"), config.hook, stacklevel=2) """ ) testdir.makepyfile(