Skip to content

Commit

Permalink
Merge pull request #4566 from nicoddemus/remove-setup-cfg-non-top-lev…
Browse files Browse the repository at this point in the history
…el-pytest-plugins

Remove support for [pytest] in setup.cfg files and pytest_plugins in non-top-level conftests
  • Loading branch information
RonnyPfannschmidt authored Dec 20, 2018
2 parents c400d8b + a93f412 commit b2d3ae2
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 75 deletions.
4 changes: 4 additions & 0 deletions changelog/3086.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
``[pytest]`` section in **setup.cfg** files is not longer supported, use ``[tool:pytest]`` instead. ``setup.cfg`` files
are meant for use with ``distutils``, and a section named ``pytest`` has notoriously been a source of conflicts and bugs.

Note that for **pytest.ini** and **tox.ini** files the section remains ``[pytest]``.
3 changes: 3 additions & 0 deletions changelog/4548.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
An error is now raised if the ``pytest_plugins`` variable is defined in a non-top-level ``conftest.py`` file (i.e., not residing in the ``rootdir``).

See our `docs <https://docs.pytest.org/en/latest/deprecations.html#pytest-plugins-in-non-top-level-conftest-files>`__ for more information.
39 changes: 20 additions & 19 deletions doc/en/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,6 @@ As part of a large :ref:`marker-revamp`, :meth:`_pytest.nodes.Node.get_marker` i
:ref:`the documentation <update marker code>` on tips on how to update your code.


pytest_plugins in non-top-level conftest files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 3.5

Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py
files because they will activate referenced plugins *globally*, which is surprising because for all other pytest
features ``conftest.py`` files are only *active* for tests at or below it.


marks in ``pytest.mark.parametrize``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -125,15 +115,6 @@ To update the code, use ``pytest.param``:
[pytest] section in setup.cfg files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. deprecated:: 3.0

``[pytest]`` sections in ``setup.cfg`` files should now be named ``[tool:pytest]``
to avoid conflicts with other distutils commands.

Result log (``--result-log``)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -185,6 +166,16 @@ Switch over to the ``@pytest.fixture`` decorator:
return SomeData()
[pytest] section in setup.cfg files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*Removed in version 4.0.*

``[pytest]`` sections in ``setup.cfg`` files should now be named ``[tool:pytest]``
to avoid conflicts with other distutils commands.


Metafunc.addcall
~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -241,6 +232,16 @@ You can consult `funcarg comparison section in the docs <https://docs.pytest.org
more information.


pytest_plugins in non-top-level conftest files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*Removed in version 4.0.*

Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py
files because they will activate referenced plugins *globally*, which is surprising because for all other pytest
features ``conftest.py`` files are only *active* for tests at or below it.


``Config.warn`` and ``Node.warn``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
11 changes: 6 additions & 5 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from _pytest._code import filter_traceback
from _pytest.compat import lru_cache
from _pytest.compat import safe_str
from _pytest.outcomes import fail
from _pytest.outcomes import Skipped
from _pytest.warning_types import PytestWarning

Expand Down Expand Up @@ -429,11 +430,11 @@ def _importconftest(self, conftestpath):
PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
)

warnings.warn_explicit(
PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST,
category=None,
filename=str(conftestpath),
lineno=0,
fail(
PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST.format(
conftestpath, self._confcutdir
),
pytrace=False,
)
except Exception:
raise ConftestImportFailure(conftestpath, sys.exc_info())
Expand Down
25 changes: 8 additions & 17 deletions src/_pytest/config/findpaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import py

from .exceptions import UsageError
from _pytest.outcomes import fail


def exists(path, ignore=EnvironmentError):
Expand Down Expand Up @@ -34,15 +35,10 @@ 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_warning_captured
from _pytest.warning_types import RemovedInPytest4Warning

_issue_warning_captured(
RemovedInPytest4Warning(
CFG_PYTEST_SECTION.format(filename=inibasename)
),
hook=config.hook,
stacklevel=2,

fail(
CFG_PYTEST_SECTION.format(filename=inibasename),
pytrace=False,
)
return base, p, iniconfig["pytest"]
if (
Expand Down Expand Up @@ -112,14 +108,9 @@ 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_warning_captured

# TODO: [pytest] section in *.cfg files is deprecated. Need refactoring once
# the deprecation expires.
_issue_warning_captured(
CFG_PYTEST_SECTION.format(filename=str(inifile)),
config.hook,
stacklevel=2,

fail(
CFG_PYTEST_SECTION.format(filename=str(inifile)), pytrace=False
)
break
except KeyError:
Expand Down
16 changes: 8 additions & 8 deletions src/_pytest/deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

from _pytest.warning_types import PytestDeprecationWarning
from _pytest.warning_types import RemovedInPytest4Warning
from _pytest.warning_types import UnformattedWarning


YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored"
Expand All @@ -31,10 +30,7 @@
"'request' is a reserved name for fixtures and will raise an error in future versions"
)

CFG_PYTEST_SECTION = UnformattedWarning(
RemovedInPytest4Warning,
"[pytest] section in {filename} files is deprecated, use [tool:pytest] instead.",
)
CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supported, change to [tool:pytest] instead."

GETFUNCARGVALUE = RemovedInPytest4Warning(
"getfuncargvalue is deprecated, use getfixturevalue"
Expand Down Expand Up @@ -73,10 +69,14 @@
"See https://docs.pytest.org/en/latest/deprecations.html#raises-warns-exec"
)

PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = RemovedInPytest4Warning(
"Defining pytest_plugins in a non-top-level conftest is deprecated, "
PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST = (
"Defining 'pytest_plugins' in a non-top-level conftest is no longer supported "
"because it affects the entire directory tree in a non-explicit way.\n"
"Please move it to the top level conftest file instead."
" {}\n"
"Please move it to a top level conftest file at the rootdir:\n"
" {}\n"
"For more information, visit:\n"
" https://docs.pytest.org/en/latest/deprecations.html#pytest-plugins-in-non-top-level-conftest-files"
)

PYTEST_CONFIG_GLOBAL = PytestDeprecationWarning(
Expand Down
40 changes: 14 additions & 26 deletions testing/deprecated_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,28 @@
pytestmark = pytest.mark.pytester_example_path("deprecated")


@pytest.mark.filterwarnings("default")
def test_pytest_setup_cfg_deprecated(testdir):
def test_pytest_setup_cfg_unsupported(testdir):
testdir.makefile(
".cfg",
setup="""
[pytest]
addopts = --verbose
""",
)
result = testdir.runpytest()
result.stdout.fnmatch_lines(
["*pytest*section in setup.cfg files is deprecated*use*tool:pytest*instead*"]
)
with pytest.raises(pytest.fail.Exception):
testdir.runpytest()


@pytest.mark.filterwarnings("default")
def test_pytest_custom_cfg_deprecated(testdir):
def test_pytest_custom_cfg_unsupported(testdir):
testdir.makefile(
".cfg",
custom="""
[pytest]
addopts = --verbose
""",
)
result = testdir.runpytest("-c", "custom.cfg")
result.stdout.fnmatch_lines(
["*pytest*section in custom.cfg files is deprecated*use*tool:pytest*instead*"]
)
with pytest.raises(pytest.fail.Exception):
testdir.runpytest("-c", "custom.cfg")


def test_getfuncargvalue_is_deprecated(request):
Expand Down Expand Up @@ -119,17 +113,15 @@ def test_func():
"""
)
res = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
assert res.ret == 0
assert res.ret == 2
msg = str(PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST).splitlines()[0]
res.stdout.fnmatch_lines(
"*subdirectory{sep}conftest.py:0: RemovedInPytest4Warning: {msg}*".format(
sep=os.sep, msg=msg
)
["*{msg}*".format(msg=msg), "*subdirectory{sep}conftest.py*".format(sep=os.sep)]
)


@pytest.mark.parametrize("use_pyargs", [True, False])
def test_pytest_plugins_in_non_top_level_conftest_deprecated_pyargs(
def test_pytest_plugins_in_non_top_level_conftest_unsupported_pyargs(
testdir, use_pyargs
):
"""When using --pyargs, do not emit the warning about non-top-level conftest warnings (#4039, #4044)"""
Expand All @@ -149,15 +141,15 @@ def test_pytest_plugins_in_non_top_level_conftest_deprecated_pyargs(
args = ("--pyargs", "pkg") if use_pyargs else ()
args += (SHOW_PYTEST_WARNINGS_ARG,)
res = testdir.runpytest(*args)
assert res.ret == 0
assert res.ret == (0 if use_pyargs else 2)
msg = str(PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST).splitlines()[0]
if use_pyargs:
assert msg not in res.stdout.str()
else:
res.stdout.fnmatch_lines("*{msg}*".format(msg=msg))


def test_pytest_plugins_in_non_top_level_conftest_deprecated_no_top_level_conftest(
def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_top_level_conftest(
testdir
):
from _pytest.deprecated import PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
Expand All @@ -166,8 +158,6 @@ def test_pytest_plugins_in_non_top_level_conftest_deprecated_no_top_level_confte
subdirectory.mkdir()
testdir.makeconftest(
"""
import warnings
warnings.filterwarnings('always', category=DeprecationWarning)
pytest_plugins=['capture']
"""
)
Expand All @@ -181,16 +171,14 @@ def test_func():
)

res = testdir.runpytest_subprocess()
assert res.ret == 0
assert res.ret == 2
msg = str(PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST).splitlines()[0]
res.stdout.fnmatch_lines(
"*subdirectory{sep}conftest.py:0: RemovedInPytest4Warning: {msg}*".format(
sep=os.sep, msg=msg
)
["*{msg}*".format(msg=msg), "*subdirectory{sep}conftest.py*".format(sep=os.sep)]
)


def test_pytest_plugins_in_non_top_level_conftest_deprecated_no_false_positives(
def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_false_positives(
testdir
):
from _pytest.deprecated import PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
Expand Down

0 comments on commit b2d3ae2

Please sign in to comment.