Skip to content

Commit

Permalink
Change pytest deprecation warnings into errors for 6.0 release (#7362)
Browse files Browse the repository at this point in the history
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
  • Loading branch information
nicoddemus and hugovk committed Jul 23, 2020
1 parent a9799f0 commit 7ec6401
Show file tree
Hide file tree
Showing 19 changed files with 122 additions and 84 deletions.
23 changes: 23 additions & 0 deletions changelog/5584.breaking.rst
@@ -0,0 +1,23 @@
**PytestDeprecationWarning are now errors by default.**

Following our plan to remove deprecated features with as little disruption as
possible, all warnings of type ``PytestDeprecationWarning`` now generate errors
instead of warning messages.

**The affected features will be effectively removed in pytest 6.1**, so please consult the
`Deprecations and Removals <https://docs.pytest.org/en/latest/deprecations.html>`__
section in the docs for directions on how to update existing code.

In the pytest ``6.0.X`` series, it is possible to change the errors back into warnings as a
stopgap measure by adding this to your ``pytest.ini`` file:

.. code-block:: ini
[pytest]
filterwarnings =
ignore::pytest.PytestDeprecationWarning
But this will stop working when pytest ``6.1`` is released.

**If you have concerns** about the removal of a specific feature, please add a
comment to `#5584 <https://github.com/pytest-dev/pytest/issues/5584>`__.
41 changes: 38 additions & 3 deletions doc/en/reference.rst
Expand Up @@ -1024,10 +1024,45 @@ When set (regardless of value), pytest will use color in terminal output.
Exceptions
----------

UsageError
~~~~~~~~~~

.. autoclass:: _pytest.config.UsageError()
:show-inheritance:

.. _`warnings ref`:

Warnings
--------

Custom warnings generated in some situations such as improper usage or deprecated features.

.. autoclass:: pytest.PytestWarning
:show-inheritance:

.. autoclass:: pytest.PytestAssertRewriteWarning
:show-inheritance:

.. autoclass:: pytest.PytestCacheWarning
:show-inheritance:

.. autoclass:: pytest.PytestCollectionWarning
:show-inheritance:

.. autoclass:: pytest.PytestConfigWarning
:show-inheritance:

.. autoclass:: pytest.PytestDeprecationWarning
:show-inheritance:

.. autoclass:: pytest.PytestExperimentalApiWarning
:show-inheritance:

.. autoclass:: pytest.PytestUnhandledCoroutineWarning
:show-inheritance:

.. autoclass:: pytest.PytestUnknownMarkWarning
:show-inheritance:


Consult the :ref:`internal-warnings` section in the documentation for more information.


.. _`ini options ref`:
Expand Down
31 changes: 1 addition & 30 deletions doc/en/warnings.rst
Expand Up @@ -381,8 +381,6 @@ custom error message.
Internal pytest warnings
------------------------



pytest may generate its own warnings in some situations, such as improper usage or deprecated features.

For example, pytest will emit a warning if it encounters a class that matches :confval:`python_classes` but also
Expand Down Expand Up @@ -415,31 +413,4 @@ These warnings might be filtered using the same builtin mechanisms used to filte
Please read our :ref:`backwards-compatibility` to learn how we proceed about deprecating and eventually removing
features.

The following warning types are used by pytest and are part of the public API:

.. autoclass:: pytest.PytestWarning
:show-inheritance:

.. autoclass:: pytest.PytestAssertRewriteWarning
:show-inheritance:

.. autoclass:: pytest.PytestCacheWarning
:show-inheritance:

.. autoclass:: pytest.PytestCollectionWarning
:show-inheritance:

.. autoclass:: pytest.PytestConfigWarning
:show-inheritance:

.. autoclass:: pytest.PytestDeprecationWarning
:show-inheritance:

.. autoclass:: pytest.PytestExperimentalApiWarning
:show-inheritance:

.. autoclass:: pytest.PytestUnhandledCoroutineWarning
:show-inheritance:

.. autoclass:: pytest.PytestUnknownMarkWarning
:show-inheritance:
The full list of warnings is listed in :ref:`the reference documentation <warnings ref>`.
4 changes: 2 additions & 2 deletions src/_pytest/fixtures.py
Expand Up @@ -46,7 +46,6 @@
from _pytest.config import _PluggyPlugin
from _pytest.config import Config
from _pytest.config.argparsing import Parser
from _pytest.deprecated import FILLFUNCARGS
from _pytest.deprecated import FIXTURE_POSITIONAL_ARGUMENTS
from _pytest.deprecated import FUNCARGNAMES
from _pytest.mark import ParameterSet
Expand Down Expand Up @@ -361,7 +360,8 @@ def reorder_items_atscope(

def fillfixtures(function: "Function") -> None:
""" fill missing funcargs for a test function. """
warnings.warn(FILLFUNCARGS, stacklevel=2)
# Uncomment this after 6.0 release (#7361)
# warnings.warn(FILLFUNCARGS, stacklevel=2)
try:
request = function._request
except AttributeError:
Expand Down
5 changes: 3 additions & 2 deletions src/_pytest/hookspec.py
Expand Up @@ -12,7 +12,6 @@
from pluggy import HookspecMarker

from .deprecated import COLLECT_DIRECTORY_HOOK
from .deprecated import WARNING_CAPTURED_HOOK
from _pytest.compat import TYPE_CHECKING

if TYPE_CHECKING:
Expand Down Expand Up @@ -737,7 +736,9 @@ def pytest_terminal_summary(
"""


@hookspec(historic=True, warn_on_impl=WARNING_CAPTURED_HOOK)
# Uncomment this after 6.0 release (#7361)
# @hookspec(historic=True, warn_on_impl=WARNING_CAPTURED_HOOK)
@hookspec(historic=True)
def pytest_warning_captured(
warning_message: "warnings.WarningMessage",
when: "Literal['config', 'collect', 'runtest']",
Expand Down
9 changes: 4 additions & 5 deletions src/_pytest/mark/__init__.py
@@ -1,6 +1,5 @@
""" generic mechanism for marking and selecting python functions. """
import typing
import warnings
from typing import AbstractSet
from typing import List
from typing import Optional
Expand All @@ -23,8 +22,6 @@
from _pytest.config import hookimpl
from _pytest.config import UsageError
from _pytest.config.argparsing import Parser
from _pytest.deprecated import MINUS_K_COLON
from _pytest.deprecated import MINUS_K_DASH
from _pytest.store import StoreKey

if TYPE_CHECKING:
Expand Down Expand Up @@ -181,12 +178,14 @@ def deselect_by_keyword(items: "List[Item]", config: Config) -> None:

if keywordexpr.startswith("-"):
# To be removed in pytest 7.0.0.
warnings.warn(MINUS_K_DASH, stacklevel=2)
# Uncomment this after 6.0 release (#7361)
# warnings.warn(MINUS_K_DASH, stacklevel=2)
keywordexpr = "not " + keywordexpr[1:]
selectuntil = False
if keywordexpr[-1:] == ":":
# To be removed in pytest 7.0.0.
warnings.warn(MINUS_K_COLON, stacklevel=2)
# Uncomment this after 6.0 release (#7361)
# warnings.warn(MINUS_K_COLON, stacklevel=2)
selectuntil = True
keywordexpr = keywordexpr[:-1]

Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/warning_types.py
Expand Up @@ -78,7 +78,7 @@ class PytestUnhandledCoroutineWarning(PytestWarning):
class PytestUnknownMarkWarning(PytestWarning):
"""Warning emitted on use of unknown markers.
See https://docs.pytest.org/en/stable/mark.html for details.
See :ref:`mark` for details.
"""

__module__ = "pytest"
Expand Down
2 changes: 2 additions & 0 deletions src/_pytest/warnings.py
Expand Up @@ -105,6 +105,8 @@ def catch_warnings_for_item(
warnings.filterwarnings("always", category=DeprecationWarning)
warnings.filterwarnings("always", category=PendingDeprecationWarning)

warnings.filterwarnings("error", category=pytest.PytestDeprecationWarning)

# filters should have this precedence: mark, cmdline options, ini
# filters should be applied in the inverse order of precedence
for arg in inifilters:
Expand Down
5 changes: 2 additions & 3 deletions src/pytest/collect.py
@@ -1,11 +1,9 @@
import sys
import warnings
from types import ModuleType
from typing import Any
from typing import List

import pytest
from _pytest.deprecated import PYTEST_COLLECT_MODULE


COLLECT_FAKEMODULE_ATTRIBUTES = [
Expand Down Expand Up @@ -33,7 +31,8 @@ def __dir__(self) -> List[str]:
def __getattr__(self, name: str) -> Any:
if name not in self.__all__:
raise AttributeError(name)
warnings.warn(PYTEST_COLLECT_MODULE.format(name=name), stacklevel=2)
# Uncomment this after 6.0 release (#7361)

This comment has been minimized.

Copy link
@BrentWilkins

BrentWilkins Aug 15, 2020

I'm running the 6.0.1 release, why is this still here? Something I could help with?

This comment has been minimized.

Copy link
@nicoddemus

nicoddemus Aug 16, 2020

Author Member

Hi @BrentWilkins, what do you mean, the collect module?

We plan to deprecate it in 6.1.0 and eventually remove it in 7.0.

This comment has been minimized.

Copy link
@The-Compiler

The-Compiler Aug 16, 2020

Member

@BrentWilkins Also see #7637

# warnings.warn(PYTEST_COLLECT_MODULE.format(name=name), stacklevel=2)
return getattr(pytest, name)


Expand Down
4 changes: 2 additions & 2 deletions testing/acceptance_test.py
Expand Up @@ -302,10 +302,10 @@ def runtest(self):
pass
class MyCollector(pytest.File):
def collect(self):
return [MyItem(name="xyz", parent=self)]
return [MyItem.from_parent(name="xyz", parent=self)]
def pytest_collect_file(path, parent):
if path.basename.startswith("conftest"):
return MyCollector(path, parent)
return MyCollector.from_parent(fspath=path, parent=parent)
"""
)
result = testdir.runpytest(c.basename + "::" + "xyz")
Expand Down
4 changes: 2 additions & 2 deletions testing/conftest.py
Expand Up @@ -116,11 +116,11 @@ def dummy_yaml_custom_test(testdir):
def pytest_collect_file(parent, path):
if path.ext == ".yaml" and path.basename.startswith("test"):
return YamlFile(path, parent)
return YamlFile.from_parent(fspath=path, parent=parent)
class YamlFile(pytest.File):
def collect(self):
yield YamlItem(self.fspath.basename, self)
yield YamlItem.from_parent(name=self.fspath.basename, parent=self)
class YamlItem(pytest.Item):
def runtest(self):
Expand Down
6 changes: 5 additions & 1 deletion testing/deprecated_test.py
Expand Up @@ -28,6 +28,7 @@ def test():
)


@pytest.mark.skip(reason="should be reintroduced in 6.1: #7361")
@pytest.mark.parametrize("attribute", pytest.collect.__all__) # type: ignore
# false positive due to dynamic attribute
def test_pytest_collect_module_deprecated(attribute):
Expand Down Expand Up @@ -117,14 +118,16 @@ class MockConfig:
assert w[0].filename == __file__


def test__fillfuncargs_is_deprecated() -> None:
@pytest.mark.skip(reason="should be reintroduced in 6.1: #7361")
def test_fillfuncargs_is_deprecated() -> None:
with pytest.warns(
pytest.PytestDeprecationWarning,
match="The `_fillfuncargs` function is deprecated",
):
pytest._fillfuncargs(mock.Mock())


@pytest.mark.skip(reason="should be reintroduced in 6.1: #7361")
def test_minus_k_dash_is_deprecated(testdir) -> None:
threepass = testdir.makepyfile(
test_threepass="""
Expand All @@ -137,6 +140,7 @@ def test_three(): assert 1
result.stdout.fnmatch_lines(["*The `-k '-expr'` syntax*deprecated*"])


@pytest.mark.skip(reason="should be reintroduced in 6.1: #7361")
def test_minus_k_colon_is_deprecated(testdir) -> None:
threepass = testdir.makepyfile(
test_threepass="""
Expand Down
9 changes: 7 additions & 2 deletions testing/example_scripts/fixtures/custom_item/conftest.py
@@ -1,10 +1,15 @@
import pytest


class CustomItem(pytest.Item, pytest.File):
class CustomItem(pytest.Item):
def runtest(self):
pass


class CustomFile(pytest.File):
def collect(self):
yield CustomItem.from_parent(name="foo", parent=self)


def pytest_collect_file(path, parent):
return CustomItem(path, parent)
return CustomFile.from_parent(fspath=path, parent=parent)
Expand Up @@ -3,11 +3,11 @@

class MyFile(pytest.File):
def collect(self):
return [MyItem("hello", parent=self)]
return [MyItem.from_parent(name="hello", parent=self)]


def pytest_collect_file(path, parent):
return MyFile(path, parent)
return MyFile.from_parent(fspath=path, parent=parent)


class MyItem(pytest.Item):
Expand Down
6 changes: 3 additions & 3 deletions testing/python/collect.py
Expand Up @@ -762,7 +762,7 @@ class MyModule(pytest.Module):
pass
def pytest_pycollect_makemodule(path, parent):
if path.basename == "test_xyz.py":
return MyModule(path, parent)
return MyModule.from_parent(fspath=path, parent=parent)
"""
)
testdir.makepyfile("def test_some(): pass")
Expand Down Expand Up @@ -836,7 +836,7 @@ class MyFunction(pytest.Function):
pass
def pytest_pycollect_makeitem(collector, name, obj):
if name == "some":
return MyFunction(name, collector)
return MyFunction.from_parent(name=name, parent=collector)
"""
)
testdir.makepyfile("def some(): pass")
Expand Down Expand Up @@ -873,7 +873,7 @@ def find_module(self, name, path=None):
def pytest_collect_file(path, parent):
if path.ext == ".narf":
return Module(path, parent)"""
return Module.from_parent(fspath=path, parent=parent)"""
)
testdir.makefile(
".narf",
Expand Down

0 comments on commit 7ec6401

Please sign in to comment.