commit
31738155b5
|
@ -0,0 +1,26 @@
|
||||||
|
As per our policy, the following features have been deprecated in the 4.X series and are now
|
||||||
|
removed:
|
||||||
|
|
||||||
|
* ``Request.getfuncargvalue``: use ``Request.getfixturevalue`` instead.
|
||||||
|
|
||||||
|
* ``pytest.raises`` and ``pytest.warns`` no longer support strings as the second argument.
|
||||||
|
|
||||||
|
* ``message`` parameter of ``pytest.raises``.
|
||||||
|
|
||||||
|
* ``pytest.raises``, ``pytest.warns`` and ``ParameterSet.param`` now use native keyword-only
|
||||||
|
syntax. This might change the exception message from previous versions, but they still raise
|
||||||
|
``TypeError`` on unknown keyword arguments as before.
|
||||||
|
|
||||||
|
* ``pytest.config`` global variable.
|
||||||
|
|
||||||
|
* ``tmpdir_factory.ensuretemp`` method.
|
||||||
|
|
||||||
|
* ``pytest_logwarning`` hook.
|
||||||
|
|
||||||
|
* ``RemovedInPytest4Warning`` warning type.
|
||||||
|
|
||||||
|
* ``request`` is now a reserved name for fixtures.
|
||||||
|
|
||||||
|
|
||||||
|
For more information consult
|
||||||
|
`Deprecations and Removals <https://docs.pytest.org/en/latest/deprecations.html>`__ in the docs.
|
|
@ -20,8 +20,8 @@ Below is a complete list of all pytest features which are considered deprecated.
|
||||||
:ref:`standard warning filters <warnings>`.
|
:ref:`standard warning filters <warnings>`.
|
||||||
|
|
||||||
|
|
||||||
Removal of ``funcargnames`` alias for ``fixturenames``
|
``funcargnames`` alias for ``fixturenames``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. deprecated:: 5.0
|
.. deprecated:: 5.0
|
||||||
|
|
||||||
|
@ -34,12 +34,47 @@ in places where we or plugin authors must distinguish between fixture names and
|
||||||
names supplied by non-fixture things such as ``pytest.mark.parametrize``.
|
names supplied by non-fixture things such as ``pytest.mark.parametrize``.
|
||||||
|
|
||||||
|
|
||||||
|
Result log (``--result-log``)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. deprecated:: 4.0
|
||||||
|
|
||||||
|
The ``--result-log`` option produces a stream of test reports which can be
|
||||||
|
analysed at runtime. It uses a custom format which requires users to implement their own
|
||||||
|
parser, but the team believes using a line-based format that can be parsed using standard
|
||||||
|
tools would provide a suitable and better alternative.
|
||||||
|
|
||||||
|
The current plan is to provide an alternative in the pytest 5.0 series and remove the ``--result-log``
|
||||||
|
option in pytest 6.0 after the new implementation proves satisfactory to all users and is deemed
|
||||||
|
stable.
|
||||||
|
|
||||||
|
The actual alternative is still being discussed in issue `#4488 <https://github.com/pytest-dev/pytest/issues/4488>`__.
|
||||||
|
|
||||||
|
|
||||||
|
Removed Features
|
||||||
|
----------------
|
||||||
|
|
||||||
|
As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after
|
||||||
|
an appropriate period of deprecation has passed.
|
||||||
|
|
||||||
|
|
||||||
|
``pytest.config`` global
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. versionremoved:: 5.0
|
||||||
|
|
||||||
|
The ``pytest.config`` global object is deprecated. Instead use
|
||||||
|
``request.config`` (via the ``request`` fixture) or if you are a plugin author
|
||||||
|
use the ``pytest_configure(config)`` hook. Note that many hooks can also access
|
||||||
|
the ``config`` object indirectly, through ``session.config`` or ``item.config`` for example.
|
||||||
|
|
||||||
|
|
||||||
.. _`raises message deprecated`:
|
.. _`raises message deprecated`:
|
||||||
|
|
||||||
``"message"`` parameter of ``pytest.raises``
|
``"message"`` parameter of ``pytest.raises``
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. deprecated:: 4.1
|
.. versionremoved:: 5.0
|
||||||
|
|
||||||
It is a common mistake to think this parameter will match the exception message, while in fact
|
It is a common mistake to think this parameter will match the exception message, while in fact
|
||||||
it only serves to provide a custom message in case the ``pytest.raises`` check fails. To prevent
|
it only serves to provide a custom message in case the ``pytest.raises`` check fails. To prevent
|
||||||
|
@ -70,22 +105,12 @@ If you still have concerns about this deprecation and future removal, please com
|
||||||
`issue #3974 <https://github.com/pytest-dev/pytest/issues/3974>`__.
|
`issue #3974 <https://github.com/pytest-dev/pytest/issues/3974>`__.
|
||||||
|
|
||||||
|
|
||||||
``pytest.config`` global
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. deprecated:: 4.1
|
|
||||||
|
|
||||||
The ``pytest.config`` global object is deprecated. Instead use
|
|
||||||
``request.config`` (via the ``request`` fixture) or if you are a plugin author
|
|
||||||
use the ``pytest_configure(config)`` hook. Note that many hooks can also access
|
|
||||||
the ``config`` object indirectly, through ``session.config`` or ``item.config`` for example.
|
|
||||||
|
|
||||||
.. _raises-warns-exec:
|
.. _raises-warns-exec:
|
||||||
|
|
||||||
``raises`` / ``warns`` with a string as the second argument
|
``raises`` / ``warns`` with a string as the second argument
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
.. deprecated:: 4.1
|
.. versionremoved:: 5.0
|
||||||
|
|
||||||
Use the context manager form of these instead. When necessary, invoke ``exec``
|
Use the context manager form of these instead. When necessary, invoke ``exec``
|
||||||
directly.
|
directly.
|
||||||
|
@ -116,27 +141,6 @@ Becomes:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Result log (``--result-log``)
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. deprecated:: 4.0
|
|
||||||
|
|
||||||
The ``--result-log`` option produces a stream of test reports which can be
|
|
||||||
analysed at runtime. It uses a custom format which requires users to implement their own
|
|
||||||
parser, but the team believes using a line-based format that can be parsed using standard
|
|
||||||
tools would provide a suitable and better alternative.
|
|
||||||
|
|
||||||
The current plan is to provide an alternative in the pytest 5.0 series and remove the ``--result-log``
|
|
||||||
option in pytest 6.0 after the new implementation proves satisfactory to all users and is deemed
|
|
||||||
stable.
|
|
||||||
|
|
||||||
The actual alternative is still being discussed in issue `#4488 <https://github.com/pytest-dev/pytest/issues/4488>`__.
|
|
||||||
|
|
||||||
Removed Features
|
|
||||||
----------------
|
|
||||||
|
|
||||||
As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after
|
|
||||||
an appropriate period of deprecation has passed.
|
|
||||||
|
|
||||||
Using ``Class`` in custom Collectors
|
Using ``Class`` in custom Collectors
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -430,5 +430,3 @@ The following warning types ares used by pytest and are part of the public API:
|
||||||
.. autoclass:: pytest.PytestUnhandledCoroutineWarning
|
.. autoclass:: pytest.PytestUnhandledCoroutineWarning
|
||||||
|
|
||||||
.. autoclass:: pytest.PytestUnknownMarkWarning
|
.. autoclass:: pytest.PytestUnknownMarkWarning
|
||||||
|
|
||||||
.. autoclass:: pytest.RemovedInPytest4Warning
|
|
||||||
|
|
|
@ -56,11 +56,11 @@ def iscoroutinefunction(func):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def getlocation(function, curdir):
|
def getlocation(function, curdir=None):
|
||||||
function = get_real_func(function)
|
function = get_real_func(function)
|
||||||
fn = py.path.local(inspect.getfile(function))
|
fn = py.path.local(inspect.getfile(function))
|
||||||
lineno = function.__code__.co_firstlineno
|
lineno = function.__code__.co_firstlineno
|
||||||
if fn.relto(curdir):
|
if curdir is not None and fn.relto(curdir):
|
||||||
fn = fn.relto(curdir)
|
fn = fn.relto(curdir)
|
||||||
return "%s:%d" % (fn, lineno + 1)
|
return "%s:%d" % (fn, lineno + 1)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from pluggy import PluginManager
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
import _pytest.assertion
|
import _pytest.assertion
|
||||||
|
import _pytest.deprecated
|
||||||
import _pytest.hookspec # the extension point definitions
|
import _pytest.hookspec # the extension point definitions
|
||||||
from .exceptions import PrintHelp
|
from .exceptions import PrintHelp
|
||||||
from .exceptions import UsageError
|
from .exceptions import UsageError
|
||||||
|
@ -204,6 +205,19 @@ def _prepareconfig(args=None, plugins=None):
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def _fail_on_non_top_pytest_plugins(conftestpath, confcutdir):
|
||||||
|
msg = (
|
||||||
|
"Defining 'pytest_plugins' in a non-top-level conftest is no longer supported:\n"
|
||||||
|
"It affects the entire test suite instead of just below the conftest as expected.\n"
|
||||||
|
" {}\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"
|
||||||
|
)
|
||||||
|
fail(msg.format(conftestpath, confcutdir), pytrace=False)
|
||||||
|
|
||||||
|
|
||||||
class PytestPluginManager(PluginManager):
|
class PytestPluginManager(PluginManager):
|
||||||
"""
|
"""
|
||||||
Overwrites :py:class:`pluggy.PluginManager <pluggy.PluginManager>` to add pytest-specific
|
Overwrites :py:class:`pluggy.PluginManager <pluggy.PluginManager>` to add pytest-specific
|
||||||
|
@ -424,16 +438,7 @@ class PytestPluginManager(PluginManager):
|
||||||
and self._configured
|
and self._configured
|
||||||
and not self._using_pyargs
|
and not self._using_pyargs
|
||||||
):
|
):
|
||||||
from _pytest.deprecated import (
|
_fail_on_non_top_pytest_plugins(conftestpath, self._confcutdir)
|
||||||
PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST,
|
|
||||||
)
|
|
||||||
|
|
||||||
fail(
|
|
||||||
PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST.format(
|
|
||||||
conftestpath, self._confcutdir
|
|
||||||
),
|
|
||||||
pytrace=False,
|
|
||||||
)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
raise ConftestImportFailure(conftestpath, sys.exc_info())
|
raise ConftestImportFailure(conftestpath, sys.exc_info())
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@ def getcfg(args, config=None):
|
||||||
|
|
||||||
note: config is optional and used only to issue warnings explicitly (#2891).
|
note: config is optional and used only to issue warnings explicitly (#2891).
|
||||||
"""
|
"""
|
||||||
from _pytest.deprecated import CFG_PYTEST_SECTION
|
|
||||||
|
|
||||||
inibasenames = ["pytest.ini", "tox.ini", "setup.cfg"]
|
inibasenames = ["pytest.ini", "tox.ini", "setup.cfg"]
|
||||||
args = [x for x in args if not str(x).startswith("-")]
|
args = [x for x in args if not str(x).startswith("-")]
|
||||||
if not args:
|
if not args:
|
||||||
|
@ -97,6 +95,9 @@ def get_dirs_from_args(args):
|
||||||
return [get_dir_from_path(path) for path in possible_paths if path.exists()]
|
return [get_dir_from_path(path) for path in possible_paths if path.exists()]
|
||||||
|
|
||||||
|
|
||||||
|
CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supported, change to [tool:pytest] instead."
|
||||||
|
|
||||||
|
|
||||||
def determine_setup(inifile, args, rootdir_cmd_arg=None, config=None):
|
def determine_setup(inifile, args, rootdir_cmd_arg=None, config=None):
|
||||||
dirs = get_dirs_from_args(args)
|
dirs = get_dirs_from_args(args)
|
||||||
if inifile:
|
if inifile:
|
||||||
|
@ -107,8 +108,6 @@ def determine_setup(inifile, args, rootdir_cmd_arg=None, config=None):
|
||||||
try:
|
try:
|
||||||
inicfg = iniconfig[section]
|
inicfg = iniconfig[section]
|
||||||
if is_cfg_file and section == "pytest" and config is not None:
|
if is_cfg_file and section == "pytest" and config is not None:
|
||||||
from _pytest.deprecated import CFG_PYTEST_SECTION
|
|
||||||
|
|
||||||
fail(
|
fail(
|
||||||
CFG_PYTEST_SECTION.format(filename=str(inifile)), pytrace=False
|
CFG_PYTEST_SECTION.format(filename=str(inifile)), pytrace=False
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,10 +9,6 @@ All constants defined in this module should be either PytestWarning instances or
|
||||||
in case of warnings which need to format their messages.
|
in case of warnings which need to format their messages.
|
||||||
"""
|
"""
|
||||||
from _pytest.warning_types import PytestDeprecationWarning
|
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"
|
|
||||||
|
|
||||||
# set of plugins which have been integrated into the core; we use this list to ignore
|
# set of plugins which have been integrated into the core; we use this list to ignore
|
||||||
# them during registration to avoid conflicts
|
# them during registration to avoid conflicts
|
||||||
|
@ -23,82 +19,13 @@ DEPRECATED_EXTERNAL_PLUGINS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FIXTURE_FUNCTION_CALL = (
|
|
||||||
'Fixture "{name}" called directly. Fixtures are not meant to be called directly,\n'
|
|
||||||
"but are created automatically when test functions request them as parameters.\n"
|
|
||||||
"See https://docs.pytest.org/en/latest/fixture.html for more information about fixtures, and\n"
|
|
||||||
"https://docs.pytest.org/en/latest/deprecations.html#calling-fixtures-directly about how to update your code."
|
|
||||||
)
|
|
||||||
|
|
||||||
FIXTURE_NAMED_REQUEST = PytestDeprecationWarning(
|
|
||||||
"'request' is a reserved name for fixtures and will raise an error in future versions"
|
|
||||||
)
|
|
||||||
|
|
||||||
CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supported, change to [tool:pytest] instead."
|
|
||||||
|
|
||||||
GETFUNCARGVALUE = RemovedInPytest4Warning(
|
|
||||||
"getfuncargvalue is deprecated, use getfixturevalue"
|
|
||||||
)
|
|
||||||
|
|
||||||
FUNCARGNAMES = PytestDeprecationWarning(
|
FUNCARGNAMES = PytestDeprecationWarning(
|
||||||
"The `funcargnames` attribute was an alias for `fixturenames`, "
|
"The `funcargnames` attribute was an alias for `fixturenames`, "
|
||||||
"since pytest 2.3 - use the newer attribute instead."
|
"since pytest 2.3 - use the newer attribute instead."
|
||||||
)
|
)
|
||||||
|
|
||||||
RAISES_MESSAGE_PARAMETER = PytestDeprecationWarning(
|
|
||||||
"The 'message' parameter is deprecated.\n"
|
|
||||||
"(did you mean to use `match='some regex'` to check the exception message?)\n"
|
|
||||||
"Please see:\n"
|
|
||||||
" https://docs.pytest.org/en/4.6-maintenance/deprecations.html#message-parameter-of-pytest-raises"
|
|
||||||
)
|
|
||||||
|
|
||||||
RESULT_LOG = PytestDeprecationWarning(
|
RESULT_LOG = PytestDeprecationWarning(
|
||||||
"--result-log is deprecated and scheduled for removal in pytest 6.0.\n"
|
"--result-log is deprecated and scheduled for removal in pytest 6.0.\n"
|
||||||
"See https://docs.pytest.org/en/latest/deprecations.html#result-log-result-log for more information."
|
"See https://docs.pytest.org/en/latest/deprecations.html#result-log-result-log for more information."
|
||||||
)
|
)
|
||||||
|
|
||||||
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"
|
|
||||||
)
|
|
||||||
WARNS_EXEC = PytestDeprecationWarning(
|
|
||||||
"warns(..., '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"
|
|
||||||
)
|
|
||||||
|
|
||||||
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"
|
|
||||||
" {}\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(
|
|
||||||
"the `pytest.config` global is deprecated. Please use `request.config` "
|
|
||||||
"or `pytest_configure` (if you're a pytest plugin) instead."
|
|
||||||
)
|
|
||||||
|
|
||||||
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"
|
|
||||||
)
|
|
||||||
|
|
||||||
PYTEST_WARNS_UNKNOWN_KWARGS = UnformattedWarning(
|
|
||||||
PytestDeprecationWarning,
|
|
||||||
"pytest.warns() got unexpected keyword arguments: {args!r}.\n"
|
|
||||||
"This will be an error in future versions.",
|
|
||||||
)
|
|
||||||
|
|
||||||
PYTEST_PARAM_UNKNOWN_KWARGS = UnformattedWarning(
|
|
||||||
PytestDeprecationWarning,
|
|
||||||
"pytest.param() got unexpected keyword arguments: {args!r}.\n"
|
|
||||||
"This will be an error in future versions.",
|
|
||||||
)
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import functools
|
||||||
import inspect
|
import inspect
|
||||||
import itertools
|
import itertools
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
@ -28,8 +27,6 @@ from _pytest.compat import getlocation
|
||||||
from _pytest.compat import is_generator
|
from _pytest.compat import is_generator
|
||||||
from _pytest.compat import NOTSET
|
from _pytest.compat import NOTSET
|
||||||
from _pytest.compat import safe_getattr
|
from _pytest.compat import safe_getattr
|
||||||
from _pytest.deprecated import FIXTURE_FUNCTION_CALL
|
|
||||||
from _pytest.deprecated import FIXTURE_NAMED_REQUEST
|
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
from _pytest.outcomes import TEST_OUTCOME
|
from _pytest.outcomes import TEST_OUTCOME
|
||||||
|
|
||||||
|
@ -475,13 +472,6 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
||||||
"""
|
"""
|
||||||
return self._get_active_fixturedef(argname).cached_result[0]
|
return self._get_active_fixturedef(argname).cached_result[0]
|
||||||
|
|
||||||
def getfuncargvalue(self, argname):
|
|
||||||
""" Deprecated, use getfixturevalue. """
|
|
||||||
from _pytest import deprecated
|
|
||||||
|
|
||||||
warnings.warn(deprecated.GETFUNCARGVALUE, stacklevel=2)
|
|
||||||
return self.getfixturevalue(argname)
|
|
||||||
|
|
||||||
def _get_active_fixturedef(self, argname):
|
def _get_active_fixturedef(self, argname):
|
||||||
try:
|
try:
|
||||||
return self._fixture_defs[argname]
|
return self._fixture_defs[argname]
|
||||||
|
@ -945,9 +935,12 @@ def wrap_function_to_error_out_if_called_directly(function, fixture_marker):
|
||||||
"""Wrap the given fixture function so we can raise an error about it being called directly,
|
"""Wrap the given fixture function so we can raise an error about it being called directly,
|
||||||
instead of used as an argument in a test function.
|
instead of used as an argument in a test function.
|
||||||
"""
|
"""
|
||||||
message = FIXTURE_FUNCTION_CALL.format(
|
message = (
|
||||||
name=fixture_marker.name or function.__name__
|
'Fixture "{name}" called directly. Fixtures are not meant to be called directly,\n'
|
||||||
)
|
"but are created automatically when test functions request them as parameters.\n"
|
||||||
|
"See https://docs.pytest.org/en/latest/fixture.html for more information about fixtures, and\n"
|
||||||
|
"https://docs.pytest.org/en/latest/deprecations.html#calling-fixtures-directly about how to update your code."
|
||||||
|
).format(name=fixture_marker.name or function.__name__)
|
||||||
|
|
||||||
@functools.wraps(function)
|
@functools.wraps(function)
|
||||||
def result(*args, **kwargs):
|
def result(*args, **kwargs):
|
||||||
|
@ -982,7 +975,13 @@ class FixtureFunctionMarker:
|
||||||
|
|
||||||
name = self.name or function.__name__
|
name = self.name or function.__name__
|
||||||
if name == "request":
|
if name == "request":
|
||||||
warnings.warn(FIXTURE_NAMED_REQUEST)
|
location = getlocation(function)
|
||||||
|
fail(
|
||||||
|
"'request' is a reserved word for fixtures, use another name:\n {}".format(
|
||||||
|
location
|
||||||
|
),
|
||||||
|
pytrace=False,
|
||||||
|
)
|
||||||
function._pytestfixturefunction = self
|
function._pytestfixturefunction = self
|
||||||
return function
|
return function
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
""" hook specifications for pytest plugins, invoked from main.py and builtin plugins. """
|
""" hook specifications for pytest plugins, invoked from main.py and builtin plugins. """
|
||||||
from pluggy import HookspecMarker
|
from pluggy import HookspecMarker
|
||||||
|
|
||||||
from _pytest.deprecated import PYTEST_LOGWARNING
|
|
||||||
|
|
||||||
hookspec = HookspecMarker("pytest")
|
hookspec = HookspecMarker("pytest")
|
||||||
|
|
||||||
|
@ -575,27 +574,6 @@ def pytest_terminal_summary(terminalreporter, exitstatus, config):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@hookspec(historic=True, warn_on_impl=PYTEST_LOGWARNING)
|
|
||||||
def pytest_logwarning(message, code, nodeid, fslocation):
|
|
||||||
"""
|
|
||||||
.. deprecated:: 3.8
|
|
||||||
|
|
||||||
This hook is will stop working in a future release.
|
|
||||||
|
|
||||||
pytest no longer triggers this hook, but the
|
|
||||||
terminal writer still implements it to display warnings issued by
|
|
||||||
:meth:`_pytest.config.Config.warn` and :meth:`_pytest.nodes.Node.warn`. Calling those functions will be
|
|
||||||
an error in future releases.
|
|
||||||
|
|
||||||
process a warning specified by a message, a code string,
|
|
||||||
a nodeid and fslocation (both of which may be None
|
|
||||||
if the warning is not tied to a particular node/location).
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
This hook is incompatible with ``hookwrapper=True``.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@hookspec(historic=True)
|
@hookspec(historic=True)
|
||||||
def pytest_warning_captured(warning_message, when, item):
|
def pytest_warning_captured(warning_message, when, item):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,6 @@ import functools
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
import py
|
import py
|
||||||
|
@ -15,7 +14,6 @@ from _pytest import nodes
|
||||||
from _pytest.config import directory_arg
|
from _pytest.config import directory_arg
|
||||||
from _pytest.config import hookimpl
|
from _pytest.config import hookimpl
|
||||||
from _pytest.config import UsageError
|
from _pytest.config import UsageError
|
||||||
from _pytest.deprecated import PYTEST_CONFIG_GLOBAL
|
|
||||||
from _pytest.outcomes import exit
|
from _pytest.outcomes import exit
|
||||||
from _pytest.runner import collect_one_node
|
from _pytest.runner import collect_one_node
|
||||||
|
|
||||||
|
@ -179,26 +177,6 @@ def pytest_addoption(parser):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class _ConfigDeprecated:
|
|
||||||
def __init__(self, config):
|
|
||||||
self.__dict__["_config"] = config
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
warnings.warn(PYTEST_CONFIG_GLOBAL, stacklevel=2)
|
|
||||||
return getattr(self._config, attr)
|
|
||||||
|
|
||||||
def __setattr__(self, attr, val):
|
|
||||||
warnings.warn(PYTEST_CONFIG_GLOBAL, stacklevel=2)
|
|
||||||
return setattr(self._config, attr, val)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "{}({!r})".format(type(self).__name__, self._config)
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_configure(config):
|
|
||||||
__import__("pytest").config = _ConfigDeprecated(config) # compatibility
|
|
||||||
|
|
||||||
|
|
||||||
def wrap_session(config, doit):
|
def wrap_session(config, doit):
|
||||||
"""Skeleton command line program"""
|
"""Skeleton command line program"""
|
||||||
session = Session(config)
|
session = Session(config)
|
||||||
|
|
|
@ -10,7 +10,6 @@ import attr
|
||||||
from ..compat import ascii_escaped
|
from ..compat import ascii_escaped
|
||||||
from ..compat import getfslineno
|
from ..compat import getfslineno
|
||||||
from ..compat import NOTSET
|
from ..compat import NOTSET
|
||||||
from _pytest.deprecated import PYTEST_PARAM_UNKNOWN_KWARGS
|
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
from _pytest.warning_types import PytestUnknownMarkWarning
|
from _pytest.warning_types import PytestUnknownMarkWarning
|
||||||
|
|
||||||
|
@ -62,26 +61,19 @@ def get_empty_parameterset_mark(config, argnames, func):
|
||||||
|
|
||||||
class ParameterSet(namedtuple("ParameterSet", "values, marks, id")):
|
class ParameterSet(namedtuple("ParameterSet", "values, marks, id")):
|
||||||
@classmethod
|
@classmethod
|
||||||
def param(cls, *values, **kwargs):
|
def param(cls, *values, marks=(), id=None):
|
||||||
marks = kwargs.pop("marks", ())
|
|
||||||
if isinstance(marks, MarkDecorator):
|
if isinstance(marks, MarkDecorator):
|
||||||
marks = (marks,)
|
marks = (marks,)
|
||||||
else:
|
else:
|
||||||
assert isinstance(marks, (tuple, list, set))
|
assert isinstance(marks, (tuple, list, set))
|
||||||
|
|
||||||
id_ = kwargs.pop("id", None)
|
if id is not None:
|
||||||
if id_ is not None:
|
if not isinstance(id, str):
|
||||||
if not isinstance(id_, str):
|
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Expected id to be a string, got {}: {!r}".format(type(id_), id_)
|
"Expected id to be a string, got {}: {!r}".format(type(id), id)
|
||||||
)
|
)
|
||||||
id_ = ascii_escaped(id_)
|
id = ascii_escaped(id)
|
||||||
|
return cls(values, marks, id)
|
||||||
if kwargs:
|
|
||||||
warnings.warn(
|
|
||||||
PYTEST_PARAM_UNKNOWN_KWARGS.format(args=sorted(kwargs)), stacklevel=3
|
|
||||||
)
|
|
||||||
return cls(values, marks, id_)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def extract_from(cls, parameterset, force_tuple=False):
|
def extract_from(cls, parameterset, force_tuple=False):
|
||||||
|
|
|
@ -12,7 +12,6 @@ from textwrap import dedent
|
||||||
import py
|
import py
|
||||||
|
|
||||||
import _pytest
|
import _pytest
|
||||||
from _pytest import deprecated
|
|
||||||
from _pytest import fixtures
|
from _pytest import fixtures
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
from _pytest._code import filter_traceback
|
from _pytest._code import filter_traceback
|
||||||
|
@ -218,7 +217,9 @@ def pytest_pycollect_makeitem(collector, name, obj):
|
||||||
elif getattr(obj, "__test__", True):
|
elif getattr(obj, "__test__", True):
|
||||||
if is_generator(obj):
|
if is_generator(obj):
|
||||||
res = Function(name, parent=collector)
|
res = Function(name, parent=collector)
|
||||||
reason = deprecated.YIELD_TESTS.format(name=name)
|
reason = "yield tests were removed in pytest 4.0 - {name} will be ignored".format(
|
||||||
|
name=name
|
||||||
|
)
|
||||||
res.add_marker(MARK_GEN.xfail(run=False, reason=reason))
|
res.add_marker(MARK_GEN.xfail(run=False, reason=reason))
|
||||||
res.warn(PytestCollectionWarning(reason))
|
res.warn(PytestCollectionWarning(reason))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import inspect
|
import inspect
|
||||||
import math
|
import math
|
||||||
import pprint
|
import pprint
|
||||||
import sys
|
|
||||||
import warnings
|
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
from collections.abc import Sized
|
from collections.abc import Sized
|
||||||
|
@ -14,7 +12,6 @@ from typing import Union
|
||||||
from more_itertools.more import always_iterable
|
from more_itertools.more import always_iterable
|
||||||
|
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
from _pytest import deprecated
|
|
||||||
from _pytest.compat import STRING_TYPES
|
from _pytest.compat import STRING_TYPES
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
|
|
||||||
|
@ -531,7 +528,7 @@ def _is_numpy_array(obj):
|
||||||
# builtin pytest.raises helper
|
# builtin pytest.raises helper
|
||||||
|
|
||||||
|
|
||||||
def raises(expected_exception, *args, **kwargs):
|
def raises(expected_exception, *args, match=None, **kwargs):
|
||||||
r"""
|
r"""
|
||||||
Assert that a code block/function call raises ``expected_exception``
|
Assert that a code block/function call raises ``expected_exception``
|
||||||
or raise a failure exception otherwise.
|
or raise a failure exception otherwise.
|
||||||
|
@ -544,8 +541,6 @@ def raises(expected_exception, *args, **kwargs):
|
||||||
|
|
||||||
__ https://docs.python.org/3/library/re.html#regular-expression-syntax
|
__ https://docs.python.org/3/library/re.html#regular-expression-syntax
|
||||||
|
|
||||||
:kwparam message: **(deprecated since 4.1)** if specified, provides a custom failure message
|
|
||||||
if the exception is not raised. See :ref:`the deprecation docs <raises message deprecated>` for a workaround.
|
|
||||||
|
|
||||||
.. currentmodule:: _pytest._code
|
.. currentmodule:: _pytest._code
|
||||||
|
|
||||||
|
@ -659,36 +654,17 @@ def raises(expected_exception, *args, **kwargs):
|
||||||
raise TypeError(msg % type(exc))
|
raise TypeError(msg % type(exc))
|
||||||
|
|
||||||
message = "DID NOT RAISE {}".format(expected_exception)
|
message = "DID NOT RAISE {}".format(expected_exception)
|
||||||
match_expr = None
|
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
if "message" in kwargs:
|
return RaisesContext(
|
||||||
message = kwargs.pop("message")
|
expected_exception, message=message, match_expr=match, **kwargs
|
||||||
warnings.warn(deprecated.RAISES_MESSAGE_PARAMETER, stacklevel=2)
|
)
|
||||||
if "match" in kwargs:
|
|
||||||
match_expr = kwargs.pop("match")
|
|
||||||
if kwargs:
|
|
||||||
msg = "Unexpected keyword arguments passed to pytest.raises: "
|
|
||||||
msg += ", ".join(sorted(kwargs))
|
|
||||||
raise TypeError(msg)
|
|
||||||
return RaisesContext(expected_exception, message, match_expr)
|
|
||||||
elif isinstance(args[0], str):
|
|
||||||
warnings.warn(deprecated.RAISES_EXEC, stacklevel=2)
|
|
||||||
code, = args
|
|
||||||
assert isinstance(code, str)
|
|
||||||
frame = sys._getframe(1)
|
|
||||||
loc = frame.f_locals.copy()
|
|
||||||
loc.update(kwargs)
|
|
||||||
# print "raises frame scope: %r" % frame.f_locals
|
|
||||||
try:
|
|
||||||
code = _pytest._code.Source(code).compile(_genframe=frame)
|
|
||||||
exec(code, frame.f_globals, loc)
|
|
||||||
# XXX didn't mean f_globals == f_locals something special?
|
|
||||||
# this is destroyed here ...
|
|
||||||
except expected_exception:
|
|
||||||
return _pytest._code.ExceptionInfo.from_current()
|
|
||||||
else:
|
else:
|
||||||
func = args[0]
|
func = args[0]
|
||||||
|
if not callable(func):
|
||||||
|
raise TypeError(
|
||||||
|
"{!r} object (type: {}) must be callable".format(func, type(func))
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
func(*args[1:], **kwargs)
|
func(*args[1:], **kwargs)
|
||||||
except expected_exception:
|
except expected_exception:
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
""" recording warnings during test function execution. """
|
""" recording warnings during test function execution. """
|
||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import _pytest._code
|
|
||||||
from _pytest.deprecated import PYTEST_WARNS_UNKNOWN_KWARGS
|
|
||||||
from _pytest.deprecated import WARNS_EXEC
|
|
||||||
from _pytest.fixtures import yield_fixture
|
from _pytest.fixtures import yield_fixture
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
|
|
||||||
|
@ -46,7 +42,7 @@ def deprecated_call(func=None, *args, **kwargs):
|
||||||
return warns((DeprecationWarning, PendingDeprecationWarning), *args, **kwargs)
|
return warns((DeprecationWarning, PendingDeprecationWarning), *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def warns(expected_warning, *args, **kwargs):
|
def warns(expected_warning, *args, match=None, **kwargs):
|
||||||
r"""Assert that code raises a particular class of warning.
|
r"""Assert that code raises a particular class of warning.
|
||||||
|
|
||||||
Specifically, the parameter ``expected_warning`` can be a warning class or
|
Specifically, the parameter ``expected_warning`` can be a warning class or
|
||||||
|
@ -80,25 +76,13 @@ def warns(expected_warning, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
if not args:
|
if not args:
|
||||||
match_expr = kwargs.pop("match", None)
|
return WarningsChecker(expected_warning, match_expr=match, **kwargs)
|
||||||
if kwargs:
|
|
||||||
warnings.warn(
|
|
||||||
PYTEST_WARNS_UNKNOWN_KWARGS.format(args=sorted(kwargs)), stacklevel=2
|
|
||||||
)
|
|
||||||
return WarningsChecker(expected_warning, match_expr=match_expr)
|
|
||||||
elif isinstance(args[0], str):
|
|
||||||
warnings.warn(WARNS_EXEC, stacklevel=2)
|
|
||||||
code, = args
|
|
||||||
assert isinstance(code, str)
|
|
||||||
frame = sys._getframe(1)
|
|
||||||
loc = frame.f_locals.copy()
|
|
||||||
loc.update(kwargs)
|
|
||||||
|
|
||||||
with WarningsChecker(expected_warning):
|
|
||||||
code = _pytest._code.Source(code).compile()
|
|
||||||
exec(code, frame.f_globals, loc)
|
|
||||||
else:
|
else:
|
||||||
func = args[0]
|
func = args[0]
|
||||||
|
if not callable(func):
|
||||||
|
raise TypeError(
|
||||||
|
"{!r} object (type: {}) must be callable".format(func, type(func))
|
||||||
|
)
|
||||||
with WarningsChecker(expected_warning):
|
with WarningsChecker(expected_warning):
|
||||||
return func(*args[1:], **kwargs)
|
return func(*args[1:], **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import tempfile
|
import tempfile
|
||||||
import warnings
|
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
import py
|
import py
|
||||||
|
@ -88,19 +87,6 @@ class TempdirFactory:
|
||||||
|
|
||||||
_tmppath_factory = attr.ib()
|
_tmppath_factory = attr.ib()
|
||||||
|
|
||||||
def ensuretemp(self, string, dir=1):
|
|
||||||
""" (deprecated) return temporary directory path with
|
|
||||||
the given string as the trailing part. It is usually
|
|
||||||
better to use the 'tmpdir' function argument which
|
|
||||||
provides an empty unique-per-test-invocation directory
|
|
||||||
and is guaranteed to be empty.
|
|
||||||
"""
|
|
||||||
# py.log._apiwarn(">1.1", "use tmpdir function argument")
|
|
||||||
from .deprecated import PYTEST_ENSURETEMP
|
|
||||||
|
|
||||||
warnings.warn(PYTEST_ENSURETEMP, stacklevel=2)
|
|
||||||
return self.getbasetemp().ensure(string, dir=dir)
|
|
||||||
|
|
||||||
def mktemp(self, basename, numbered=True):
|
def mktemp(self, basename, numbered=True):
|
||||||
"""Create a subdirectory of the base temporary directory and return it.
|
"""Create a subdirectory of the base temporary directory and return it.
|
||||||
If ``numbered``, ensure the directory is unique by adding a number
|
If ``numbered``, ensure the directory is unique by adding a number
|
||||||
|
@ -138,7 +124,6 @@ def pytest_configure(config):
|
||||||
config._cleanup.append(mp.undo)
|
config._cleanup.append(mp.undo)
|
||||||
mp.setattr(config, "_tmp_path_factory", tmppath_handler, raising=False)
|
mp.setattr(config, "_tmp_path_factory", tmppath_handler, raising=False)
|
||||||
mp.setattr(config, "_tmpdirhandler", t, raising=False)
|
mp.setattr(config, "_tmpdirhandler", t, raising=False)
|
||||||
mp.setattr(pytest, "ensuretemp", t.ensuretemp, raising=False)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
|
|
|
@ -103,16 +103,6 @@ class PytestUnknownMarkWarning(PytestWarning):
|
||||||
__module__ = "pytest"
|
__module__ = "pytest"
|
||||||
|
|
||||||
|
|
||||||
class RemovedInPytest4Warning(PytestDeprecationWarning):
|
|
||||||
"""
|
|
||||||
Bases: :class:`pytest.PytestDeprecationWarning`.
|
|
||||||
|
|
||||||
Warning class for features scheduled to be removed in pytest 4.0.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__module__ = "pytest"
|
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@attr.s
|
||||||
class UnformattedWarning:
|
class UnformattedWarning:
|
||||||
"""Used to hold warnings that need to format their message at runtime, as opposed to a direct message.
|
"""Used to hold warnings that need to format their message at runtime, as opposed to a direct message.
|
||||||
|
|
|
@ -4,8 +4,6 @@ from contextlib import contextmanager
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
SHOW_PYTEST_WARNINGS_ARG = "-Walways::pytest.RemovedInPytest4Warning"
|
|
||||||
|
|
||||||
|
|
||||||
def _setoption(wmod, arg):
|
def _setoption(wmod, arg):
|
||||||
"""
|
"""
|
||||||
|
@ -74,9 +72,6 @@ def catch_warnings_for_item(config, ihook, when, item):
|
||||||
warnings.filterwarnings("always", category=DeprecationWarning)
|
warnings.filterwarnings("always", category=DeprecationWarning)
|
||||||
warnings.filterwarnings("always", category=PendingDeprecationWarning)
|
warnings.filterwarnings("always", category=PendingDeprecationWarning)
|
||||||
|
|
||||||
warnings.filterwarnings("error", category=pytest.RemovedInPytest4Warning)
|
|
||||||
warnings.filterwarnings("error", category=pytest.PytestDeprecationWarning)
|
|
||||||
|
|
||||||
# filters should have this precedence: mark, cmdline options, ini
|
# filters should have this precedence: mark, cmdline options, ini
|
||||||
# filters should be applied in the inverse order of precedence
|
# filters should be applied in the inverse order of precedence
|
||||||
for arg in inifilters:
|
for arg in inifilters:
|
||||||
|
|
|
@ -44,7 +44,7 @@ from _pytest.warning_types import PytestExperimentalApiWarning
|
||||||
from _pytest.warning_types import PytestUnhandledCoroutineWarning
|
from _pytest.warning_types import PytestUnhandledCoroutineWarning
|
||||||
from _pytest.warning_types import PytestUnknownMarkWarning
|
from _pytest.warning_types import PytestUnknownMarkWarning
|
||||||
from _pytest.warning_types import PytestWarning
|
from _pytest.warning_types import PytestWarning
|
||||||
from _pytest.warning_types import RemovedInPytest4Warning
|
|
||||||
|
|
||||||
set_trace = __pytestPDB.set_trace
|
set_trace = __pytestPDB.set_trace
|
||||||
|
|
||||||
|
@ -84,7 +84,6 @@ __all__ = [
|
||||||
"PytestWarning",
|
"PytestWarning",
|
||||||
"raises",
|
"raises",
|
||||||
"register_assert_rewrite",
|
"register_assert_rewrite",
|
||||||
"RemovedInPytest4Warning",
|
|
||||||
"Session",
|
"Session",
|
||||||
"set_trace",
|
"set_trace",
|
||||||
"skip",
|
"skip",
|
||||||
|
|
|
@ -9,7 +9,6 @@ import py
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.compat import importlib_metadata
|
from _pytest.compat import importlib_metadata
|
||||||
from _pytest.main import ExitCode
|
from _pytest.main import ExitCode
|
||||||
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
|
||||||
|
|
||||||
|
|
||||||
def prepend_pythonpath(*dirs):
|
def prepend_pythonpath(*dirs):
|
||||||
|
@ -343,7 +342,7 @@ class TestGeneralUsage:
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
p = testdir.makepyfile("""def test_func(x): pass""")
|
p = testdir.makepyfile("""def test_func(x): pass""")
|
||||||
res = testdir.runpytest(p, SHOW_PYTEST_WARNINGS_ARG)
|
res = testdir.runpytest(p)
|
||||||
assert res.ret == 0
|
assert res.ret == 0
|
||||||
res.stdout.fnmatch_lines(["*1 skipped*"])
|
res.stdout.fnmatch_lines(["*1 skipped*"])
|
||||||
|
|
||||||
|
@ -356,9 +355,7 @@ class TestGeneralUsage:
|
||||||
pass
|
pass
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
res = testdir.runpytest(
|
res = testdir.runpytest(p.basename + "::" + "test_func[1]")
|
||||||
p.basename + "::" + "test_func[1]", SHOW_PYTEST_WARNINGS_ARG
|
|
||||||
)
|
|
||||||
assert res.ret == 0
|
assert res.ret == 0
|
||||||
res.stdout.fnmatch_lines(["*1 passed*"])
|
res.stdout.fnmatch_lines(["*1 passed*"])
|
||||||
|
|
||||||
|
|
|
@ -1,39 +1,5 @@
|
||||||
import os
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest import deprecated
|
from _pytest import deprecated
|
||||||
from _pytest.warning_types import PytestDeprecationWarning
|
|
||||||
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
|
||||||
|
|
||||||
pytestmark = pytest.mark.pytester_example_path("deprecated")
|
|
||||||
|
|
||||||
|
|
||||||
def test_pytest_setup_cfg_unsupported(testdir):
|
|
||||||
testdir.makefile(
|
|
||||||
".cfg",
|
|
||||||
setup="""
|
|
||||||
[pytest]
|
|
||||||
addopts = --verbose
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
with pytest.raises(pytest.fail.Exception):
|
|
||||||
testdir.runpytest()
|
|
||||||
|
|
||||||
|
|
||||||
def test_pytest_custom_cfg_unsupported(testdir):
|
|
||||||
testdir.makefile(
|
|
||||||
".cfg",
|
|
||||||
custom="""
|
|
||||||
[pytest]
|
|
||||||
addopts = --verbose
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
with pytest.raises(pytest.fail.Exception):
|
|
||||||
testdir.runpytest("-c", "custom.cfg")
|
|
||||||
|
|
||||||
|
|
||||||
def test_getfuncargvalue_is_deprecated(request):
|
|
||||||
pytest.deprecated_call(request.getfuncargvalue, "tmpdir")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.filterwarnings("default")
|
@pytest.mark.filterwarnings("default")
|
||||||
|
@ -78,142 +44,3 @@ def test_external_plugins_integrated(testdir, plugin):
|
||||||
|
|
||||||
with pytest.warns(pytest.PytestConfigWarning):
|
with pytest.warns(pytest.PytestConfigWarning):
|
||||||
testdir.parseconfig("-p", plugin)
|
testdir.parseconfig("-p", plugin)
|
||||||
|
|
||||||
|
|
||||||
def test_raises_message_argument_deprecated():
|
|
||||||
with pytest.warns(pytest.PytestDeprecationWarning):
|
|
||||||
with pytest.raises(RuntimeError, message="foobar"):
|
|
||||||
raise RuntimeError
|
|
||||||
|
|
||||||
|
|
||||||
def test_pytest_plugins_in_non_top_level_conftest_deprecated(testdir):
|
|
||||||
from _pytest.deprecated import PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
|
|
||||||
|
|
||||||
testdir.makepyfile(
|
|
||||||
**{
|
|
||||||
"subdirectory/conftest.py": """
|
|
||||||
pytest_plugins=['capture']
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
)
|
|
||||||
testdir.makepyfile(
|
|
||||||
"""
|
|
||||||
def test_func():
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
res = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
|
|
||||||
assert res.ret == 2
|
|
||||||
msg = str(PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST).splitlines()[0]
|
|
||||||
res.stdout.fnmatch_lines(
|
|
||||||
["*{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_unsupported_pyargs(
|
|
||||||
testdir, use_pyargs
|
|
||||||
):
|
|
||||||
"""When using --pyargs, do not emit the warning about non-top-level conftest warnings (#4039, #4044)"""
|
|
||||||
from _pytest.deprecated import PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
|
|
||||||
|
|
||||||
files = {
|
|
||||||
"src/pkg/__init__.py": "",
|
|
||||||
"src/pkg/conftest.py": "",
|
|
||||||
"src/pkg/test_root.py": "def test(): pass",
|
|
||||||
"src/pkg/sub/__init__.py": "",
|
|
||||||
"src/pkg/sub/conftest.py": "pytest_plugins=['capture']",
|
|
||||||
"src/pkg/sub/test_bar.py": "def test(): pass",
|
|
||||||
}
|
|
||||||
testdir.makepyfile(**files)
|
|
||||||
testdir.syspathinsert(testdir.tmpdir.join("src"))
|
|
||||||
|
|
||||||
args = ("--pyargs", "pkg") if use_pyargs else ()
|
|
||||||
args += (SHOW_PYTEST_WARNINGS_ARG,)
|
|
||||||
res = testdir.runpytest(*args)
|
|
||||||
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_unsupported_no_top_level_conftest(
|
|
||||||
testdir
|
|
||||||
):
|
|
||||||
from _pytest.deprecated import PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST
|
|
||||||
|
|
||||||
subdirectory = testdir.tmpdir.join("subdirectory")
|
|
||||||
subdirectory.mkdir()
|
|
||||||
testdir.makeconftest(
|
|
||||||
"""
|
|
||||||
pytest_plugins=['capture']
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
testdir.tmpdir.join("conftest.py").move(subdirectory.join("conftest.py"))
|
|
||||||
|
|
||||||
testdir.makepyfile(
|
|
||||||
"""
|
|
||||||
def test_func():
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
res = testdir.runpytest_subprocess()
|
|
||||||
assert res.ret == 2
|
|
||||||
msg = str(PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST).splitlines()[0]
|
|
||||||
res.stdout.fnmatch_lines(
|
|
||||||
["*{msg}*".format(msg=msg), "*subdirectory{sep}conftest.py*".format(sep=os.sep)]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
subdirectory = testdir.tmpdir.join("subdirectory")
|
|
||||||
subdirectory.mkdir()
|
|
||||||
testdir.makeconftest(
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
testdir.tmpdir.join("conftest.py").move(subdirectory.join("conftest.py"))
|
|
||||||
|
|
||||||
testdir.makeconftest(
|
|
||||||
"""
|
|
||||||
import warnings
|
|
||||||
warnings.filterwarnings('always', category=DeprecationWarning)
|
|
||||||
pytest_plugins=['capture']
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
testdir.makepyfile(
|
|
||||||
"""
|
|
||||||
def test_func():
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
res = testdir.runpytest_subprocess()
|
|
||||||
assert res.ret == 0
|
|
||||||
msg = str(PYTEST_PLUGINS_FROM_NON_TOP_LEVEL_CONFTEST).splitlines()[0]
|
|
||||||
assert msg not in res.stdout.str()
|
|
||||||
|
|
||||||
|
|
||||||
def test_fixture_named_request(testdir):
|
|
||||||
testdir.copy_example()
|
|
||||||
result = testdir.runpytest()
|
|
||||||
result.stdout.fnmatch_lines(
|
|
||||||
[
|
|
||||||
"*'request' is a reserved name for fixtures and will raise an error in future versions"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_pytest_warns_unknown_kwargs():
|
|
||||||
with pytest.warns(
|
|
||||||
PytestDeprecationWarning,
|
|
||||||
match=r"pytest.warns\(\) got unexpected keyword arguments: \['foo'\]",
|
|
||||||
):
|
|
||||||
pytest.warns(UserWarning, foo="hello")
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ from _pytest.fixtures import FixtureLookupError
|
||||||
from _pytest.fixtures import FixtureRequest
|
from _pytest.fixtures import FixtureRequest
|
||||||
from _pytest.pathlib import Path
|
from _pytest.pathlib import Path
|
||||||
from _pytest.pytester import get_public_names
|
from _pytest.pytester import get_public_names
|
||||||
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
|
||||||
|
|
||||||
|
|
||||||
def test_getfuncargnames():
|
def test_getfuncargnames():
|
||||||
|
@ -599,8 +598,7 @@ class TestRequestBasic:
|
||||||
result = testdir.runpytest()
|
result = testdir.runpytest()
|
||||||
result.stdout.fnmatch_lines(["* 2 passed in *"])
|
result.stdout.fnmatch_lines(["* 2 passed in *"])
|
||||||
|
|
||||||
@pytest.mark.parametrize("getfixmethod", ("getfixturevalue", "getfuncargvalue"))
|
def test_getfixturevalue(self, testdir):
|
||||||
def test_getfixturevalue(self, testdir, getfixmethod):
|
|
||||||
item = testdir.getitem(
|
item = testdir.getitem(
|
||||||
"""
|
"""
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -613,30 +611,17 @@ class TestRequestBasic:
|
||||||
def test_func(something): pass
|
def test_func(something): pass
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
import contextlib
|
|
||||||
|
|
||||||
if getfixmethod == "getfuncargvalue":
|
|
||||||
warning_expectation = pytest.warns(DeprecationWarning)
|
|
||||||
else:
|
|
||||||
# see #1830 for a cleaner way to accomplish this
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def expecting_no_warning():
|
|
||||||
yield
|
|
||||||
|
|
||||||
warning_expectation = expecting_no_warning()
|
|
||||||
|
|
||||||
req = item._request
|
req = item._request
|
||||||
with warning_expectation:
|
|
||||||
fixture_fetcher = getattr(req, getfixmethod)
|
|
||||||
with pytest.raises(FixtureLookupError):
|
with pytest.raises(FixtureLookupError):
|
||||||
fixture_fetcher("notexists")
|
req.getfixturevalue("notexists")
|
||||||
val = fixture_fetcher("something")
|
val = req.getfixturevalue("something")
|
||||||
assert val == 1
|
assert val == 1
|
||||||
val = fixture_fetcher("something")
|
val = req.getfixturevalue("something")
|
||||||
assert val == 1
|
assert val == 1
|
||||||
val2 = fixture_fetcher("other")
|
val2 = req.getfixturevalue("other")
|
||||||
assert val2 == 2
|
assert val2 == 2
|
||||||
val2 = fixture_fetcher("other") # see about caching
|
val2 = req.getfixturevalue("other") # see about caching
|
||||||
assert val2 == 2
|
assert val2 == 2
|
||||||
pytest._fillfuncargs(item)
|
pytest._fillfuncargs(item)
|
||||||
assert item.funcargs["something"] == 1
|
assert item.funcargs["something"] == 1
|
||||||
|
@ -1141,21 +1126,6 @@ class TestFixtureUsages:
|
||||||
values = reprec.getfailedcollections()
|
values = reprec.getfailedcollections()
|
||||||
assert len(values) == 1
|
assert len(values) == 1
|
||||||
|
|
||||||
def test_request_can_be_overridden(self, testdir):
|
|
||||||
testdir.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
@pytest.fixture()
|
|
||||||
def request(request):
|
|
||||||
request.a = 1
|
|
||||||
return request
|
|
||||||
def test_request(request):
|
|
||||||
assert request.a == 1
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
reprec = testdir.inline_run("-Wignore::pytest.PytestDeprecationWarning")
|
|
||||||
reprec.assertoutcome(passed=1)
|
|
||||||
|
|
||||||
def test_usefixtures_marker(self, testdir):
|
def test_usefixtures_marker(self, testdir):
|
||||||
testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
"""
|
"""
|
||||||
|
@ -2200,7 +2170,7 @@ class TestFixtureMarker:
|
||||||
pass
|
pass
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest()
|
||||||
assert result.ret != 0
|
assert result.ret != 0
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
["*ScopeMismatch*You tried*function*session*request*"]
|
["*ScopeMismatch*You tried*function*session*request*"]
|
||||||
|
@ -3988,3 +3958,14 @@ def test_fixture_param_shadowing(testdir):
|
||||||
result.stdout.fnmatch_lines(["*::test_normal_fixture[[]a[]]*"])
|
result.stdout.fnmatch_lines(["*::test_normal_fixture[[]a[]]*"])
|
||||||
result.stdout.fnmatch_lines(["*::test_normal_fixture[[]b[]]*"])
|
result.stdout.fnmatch_lines(["*::test_normal_fixture[[]b[]]*"])
|
||||||
result.stdout.fnmatch_lines(["*::test_indirect[[]1[]]*"])
|
result.stdout.fnmatch_lines(["*::test_indirect[[]1[]]*"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_fixture_named_request(testdir):
|
||||||
|
testdir.copy_example("fixtures/test_fixture_named_request.py")
|
||||||
|
result = testdir.runpytest()
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
[
|
||||||
|
"*'request' is a reserved word for fixtures, use another name:",
|
||||||
|
" *test_fixture_named_request.py:5",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
|
@ -9,7 +9,6 @@ from hypothesis import strategies
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest import fixtures
|
from _pytest import fixtures
|
||||||
from _pytest import python
|
from _pytest import python
|
||||||
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
|
||||||
|
|
||||||
|
|
||||||
class TestMetafunc:
|
class TestMetafunc:
|
||||||
|
@ -915,7 +914,7 @@ class TestMetafuncFunctional:
|
||||||
assert metafunc.cls == TestClass
|
assert metafunc.cls == TestClass
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest(p, "-v", SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest(p, "-v")
|
||||||
result.assert_outcomes(passed=2)
|
result.assert_outcomes(passed=2)
|
||||||
|
|
||||||
def test_two_functions(self, testdir):
|
def test_two_functions(self, testdir):
|
||||||
|
@ -931,7 +930,7 @@ class TestMetafuncFunctional:
|
||||||
assert arg1 in (10, 20)
|
assert arg1 in (10, 20)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest("-v", p, SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest("-v", p)
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
[
|
[
|
||||||
"*test_func1*0*PASS*",
|
"*test_func1*0*PASS*",
|
||||||
|
@ -967,7 +966,7 @@ class TestMetafuncFunctional:
|
||||||
assert hello == "world"
|
assert hello == "world"
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest("-v", p, SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest("-v", p)
|
||||||
result.stdout.fnmatch_lines(["*test_myfunc*hello*PASS*", "*1 passed*"])
|
result.stdout.fnmatch_lines(["*test_myfunc*hello*PASS*", "*1 passed*"])
|
||||||
|
|
||||||
def test_two_functions_not_same_instance(self, testdir):
|
def test_two_functions_not_same_instance(self, testdir):
|
||||||
|
@ -982,7 +981,7 @@ class TestMetafuncFunctional:
|
||||||
self.x = 1
|
self.x = 1
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest("-v", p, SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest("-v", p)
|
||||||
result.stdout.fnmatch_lines(
|
result.stdout.fnmatch_lines(
|
||||||
["*test_func*0*PASS*", "*test_func*1*PASS*", "*2 pass*"]
|
["*test_func*0*PASS*", "*test_func*1*PASS*", "*2 pass*"]
|
||||||
)
|
)
|
||||||
|
@ -1000,7 +999,7 @@ class TestMetafuncFunctional:
|
||||||
self.val = 1
|
self.val = 1
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest(p, SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest(p)
|
||||||
result.assert_outcomes(passed=1)
|
result.assert_outcomes(passed=1)
|
||||||
|
|
||||||
def test_parametrize_functional2(self, testdir):
|
def test_parametrize_functional2(self, testdir):
|
||||||
|
@ -1522,7 +1521,7 @@ class TestMarkersWithParametrization:
|
||||||
assert n + 1 == expected
|
assert n + 1 == expected
|
||||||
"""
|
"""
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
rec = testdir.inline_run("-m", "foo", SHOW_PYTEST_WARNINGS_ARG)
|
rec = testdir.inline_run("-m", "foo")
|
||||||
passed, skipped, fail = rec.listoutcomes()
|
passed, skipped, fail = rec.listoutcomes()
|
||||||
assert len(passed) == 1
|
assert len(passed) == 1
|
||||||
assert len(skipped) == 0
|
assert len(skipped) == 0
|
||||||
|
@ -1562,7 +1561,7 @@ class TestMarkersWithParametrization:
|
||||||
assert n + 1 == expected
|
assert n + 1 == expected
|
||||||
"""
|
"""
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
# xfail is skip??
|
# xfail is skip??
|
||||||
reprec.assertoutcome(passed=2, skipped=1)
|
reprec.assertoutcome(passed=2, skipped=1)
|
||||||
|
|
||||||
|
@ -1579,7 +1578,7 @@ class TestMarkersWithParametrization:
|
||||||
assert n % 2 == 0
|
assert n % 2 == 0
|
||||||
"""
|
"""
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=2, skipped=1)
|
reprec.assertoutcome(passed=2, skipped=1)
|
||||||
|
|
||||||
def test_xfail_with_arg(self, testdir):
|
def test_xfail_with_arg(self, testdir):
|
||||||
|
@ -1595,7 +1594,7 @@ class TestMarkersWithParametrization:
|
||||||
assert n + 1 == expected
|
assert n + 1 == expected
|
||||||
"""
|
"""
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=2, skipped=1)
|
reprec.assertoutcome(passed=2, skipped=1)
|
||||||
|
|
||||||
def test_xfail_with_kwarg(self, testdir):
|
def test_xfail_with_kwarg(self, testdir):
|
||||||
|
@ -1611,7 +1610,7 @@ class TestMarkersWithParametrization:
|
||||||
assert n + 1 == expected
|
assert n + 1 == expected
|
||||||
"""
|
"""
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=2, skipped=1)
|
reprec.assertoutcome(passed=2, skipped=1)
|
||||||
|
|
||||||
def test_xfail_with_arg_and_kwarg(self, testdir):
|
def test_xfail_with_arg_and_kwarg(self, testdir):
|
||||||
|
@ -1627,7 +1626,7 @@ class TestMarkersWithParametrization:
|
||||||
assert n + 1 == expected
|
assert n + 1 == expected
|
||||||
"""
|
"""
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=2, skipped=1)
|
reprec.assertoutcome(passed=2, skipped=1)
|
||||||
|
|
||||||
@pytest.mark.parametrize("strict", [True, False])
|
@pytest.mark.parametrize("strict", [True, False])
|
||||||
|
@ -1648,7 +1647,7 @@ class TestMarkersWithParametrization:
|
||||||
strict=strict
|
strict=strict
|
||||||
)
|
)
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
passed, failed = (2, 1) if strict else (3, 0)
|
passed, failed = (2, 1) if strict else (3, 0)
|
||||||
reprec.assertoutcome(passed=passed, failed=failed)
|
reprec.assertoutcome(passed=passed, failed=failed)
|
||||||
|
|
||||||
|
@ -1672,7 +1671,7 @@ class TestMarkersWithParametrization:
|
||||||
assert n + 1 == expected
|
assert n + 1 == expected
|
||||||
"""
|
"""
|
||||||
testdir.makepyfile(s)
|
testdir.makepyfile(s)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=2, skipped=2)
|
reprec.assertoutcome(passed=2, skipped=2)
|
||||||
|
|
||||||
def test_parametrize_ID_generation_string_int_works(self, testdir):
|
def test_parametrize_ID_generation_string_int_works(self, testdir):
|
||||||
|
|
|
@ -2,35 +2,20 @@ import sys
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.outcomes import Failed
|
from _pytest.outcomes import Failed
|
||||||
from _pytest.warning_types import PytestDeprecationWarning
|
|
||||||
|
|
||||||
|
|
||||||
class TestRaises:
|
class TestRaises:
|
||||||
|
def test_check_callable(self):
|
||||||
|
with pytest.raises(TypeError, match=r".* must be callable"):
|
||||||
|
pytest.raises(RuntimeError, "int('qwe')")
|
||||||
|
|
||||||
def test_raises(self):
|
def test_raises(self):
|
||||||
source = "int('qwe')"
|
excinfo = pytest.raises(ValueError, int, "qwe")
|
||||||
with pytest.warns(PytestDeprecationWarning):
|
assert "invalid literal" in str(excinfo.value)
|
||||||
excinfo = pytest.raises(ValueError, source)
|
|
||||||
code = excinfo.traceback[-1].frame.code
|
|
||||||
s = str(code.fullsource)
|
|
||||||
assert s == source
|
|
||||||
|
|
||||||
def test_raises_exec(self):
|
|
||||||
with pytest.warns(PytestDeprecationWarning) as warninfo:
|
|
||||||
pytest.raises(ValueError, "a,x = []")
|
|
||||||
assert warninfo[0].filename == __file__
|
|
||||||
|
|
||||||
def test_raises_exec_correct_filename(self):
|
|
||||||
with pytest.warns(PytestDeprecationWarning):
|
|
||||||
excinfo = pytest.raises(ValueError, 'int("s")')
|
|
||||||
assert __file__ in excinfo.traceback[-1].path
|
|
||||||
|
|
||||||
def test_raises_syntax_error(self):
|
|
||||||
with pytest.warns(PytestDeprecationWarning) as warninfo:
|
|
||||||
pytest.raises(SyntaxError, "qwe qwe qwe")
|
|
||||||
assert warninfo[0].filename == __file__
|
|
||||||
|
|
||||||
def test_raises_function(self):
|
def test_raises_function(self):
|
||||||
pytest.raises(ValueError, int, "hello")
|
excinfo = pytest.raises(ValueError, int, "hello")
|
||||||
|
assert "invalid literal" in str(excinfo.value)
|
||||||
|
|
||||||
def test_raises_callable_no_exception(self):
|
def test_raises_callable_no_exception(self):
|
||||||
class A:
|
class A:
|
||||||
|
@ -169,17 +154,6 @@ class TestRaises:
|
||||||
else:
|
else:
|
||||||
assert False, "Expected pytest.raises.Exception"
|
assert False, "Expected pytest.raises.Exception"
|
||||||
|
|
||||||
def test_custom_raise_message(self):
|
|
||||||
message = "TEST_MESSAGE"
|
|
||||||
try:
|
|
||||||
with pytest.warns(PytestDeprecationWarning):
|
|
||||||
with pytest.raises(ValueError, message=message):
|
|
||||||
pass
|
|
||||||
except pytest.raises.Exception as e:
|
|
||||||
assert e.msg == message
|
|
||||||
else:
|
|
||||||
assert False, "Expected pytest.raises.Exception"
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("method", ["function", "with"])
|
@pytest.mark.parametrize("method", ["function", "with"])
|
||||||
def test_raises_cyclic_reference(self, method):
|
def test_raises_cyclic_reference(self, method):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
|
@ -1241,3 +1242,140 @@ def test_config_blocked_default_plugins(testdir, plugin):
|
||||||
result.stdout.fnmatch_lines(["* 1 failed in *"])
|
result.stdout.fnmatch_lines(["* 1 failed in *"])
|
||||||
else:
|
else:
|
||||||
assert result.stdout.lines == [""]
|
assert result.stdout.lines == [""]
|
||||||
|
|
||||||
|
|
||||||
|
class TestSetupCfg:
|
||||||
|
def test_pytest_setup_cfg_unsupported(self, testdir):
|
||||||
|
testdir.makefile(
|
||||||
|
".cfg",
|
||||||
|
setup="""
|
||||||
|
[pytest]
|
||||||
|
addopts = --verbose
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
with pytest.raises(pytest.fail.Exception):
|
||||||
|
testdir.runpytest()
|
||||||
|
|
||||||
|
def test_pytest_custom_cfg_unsupported(self, testdir):
|
||||||
|
testdir.makefile(
|
||||||
|
".cfg",
|
||||||
|
custom="""
|
||||||
|
[pytest]
|
||||||
|
addopts = --verbose
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
with pytest.raises(pytest.fail.Exception):
|
||||||
|
testdir.runpytest("-c", "custom.cfg")
|
||||||
|
|
||||||
|
|
||||||
|
class TestPytestPluginsVariable:
|
||||||
|
def test_pytest_plugins_in_non_top_level_conftest_unsupported(self, testdir):
|
||||||
|
testdir.makepyfile(
|
||||||
|
**{
|
||||||
|
"subdirectory/conftest.py": """
|
||||||
|
pytest_plugins=['capture']
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
)
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
def test_func():
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
res = testdir.runpytest()
|
||||||
|
assert res.ret == 2
|
||||||
|
msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
|
||||||
|
res.stdout.fnmatch_lines(
|
||||||
|
[
|
||||||
|
"*{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_unsupported_pyargs(
|
||||||
|
self, testdir, use_pyargs
|
||||||
|
):
|
||||||
|
"""When using --pyargs, do not emit the warning about non-top-level conftest warnings (#4039, #4044)"""
|
||||||
|
|
||||||
|
files = {
|
||||||
|
"src/pkg/__init__.py": "",
|
||||||
|
"src/pkg/conftest.py": "",
|
||||||
|
"src/pkg/test_root.py": "def test(): pass",
|
||||||
|
"src/pkg/sub/__init__.py": "",
|
||||||
|
"src/pkg/sub/conftest.py": "pytest_plugins=['capture']",
|
||||||
|
"src/pkg/sub/test_bar.py": "def test(): pass",
|
||||||
|
}
|
||||||
|
testdir.makepyfile(**files)
|
||||||
|
testdir.syspathinsert(testdir.tmpdir.join("src"))
|
||||||
|
|
||||||
|
args = ("--pyargs", "pkg") if use_pyargs else ()
|
||||||
|
res = testdir.runpytest(*args)
|
||||||
|
assert res.ret == (0 if use_pyargs else 2)
|
||||||
|
msg = (
|
||||||
|
msg
|
||||||
|
) = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
|
||||||
|
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_unsupported_no_top_level_conftest(
|
||||||
|
self, testdir
|
||||||
|
):
|
||||||
|
subdirectory = testdir.tmpdir.join("subdirectory")
|
||||||
|
subdirectory.mkdir()
|
||||||
|
testdir.makeconftest(
|
||||||
|
"""
|
||||||
|
pytest_plugins=['capture']
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
testdir.tmpdir.join("conftest.py").move(subdirectory.join("conftest.py"))
|
||||||
|
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
def test_func():
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
res = testdir.runpytest_subprocess()
|
||||||
|
assert res.ret == 2
|
||||||
|
msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
|
||||||
|
res.stdout.fnmatch_lines(
|
||||||
|
[
|
||||||
|
"*{msg}*".format(msg=msg),
|
||||||
|
"*subdirectory{sep}conftest.py*".format(sep=os.sep),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_pytest_plugins_in_non_top_level_conftest_unsupported_no_false_positives(
|
||||||
|
self, testdir
|
||||||
|
):
|
||||||
|
subdirectory = testdir.tmpdir.join("subdirectory")
|
||||||
|
subdirectory.mkdir()
|
||||||
|
testdir.makeconftest(
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
testdir.tmpdir.join("conftest.py").move(subdirectory.join("conftest.py"))
|
||||||
|
|
||||||
|
testdir.makeconftest(
|
||||||
|
"""
|
||||||
|
import warnings
|
||||||
|
warnings.filterwarnings('always', category=DeprecationWarning)
|
||||||
|
pytest_plugins=['capture']
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
testdir.makepyfile(
|
||||||
|
"""
|
||||||
|
def test_func():
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
res = testdir.runpytest_subprocess()
|
||||||
|
assert res.ret == 0
|
||||||
|
msg = "Defining 'pytest_plugins' in a non-top-level conftest is no longer supported"
|
||||||
|
assert msg not in res.stdout.str()
|
||||||
|
|
|
@ -8,12 +8,6 @@ from _pytest.mark import EMPTY_PARAMETERSET_OPTION
|
||||||
from _pytest.mark import MarkGenerator as Mark
|
from _pytest.mark import MarkGenerator as Mark
|
||||||
from _pytest.nodes import Collector
|
from _pytest.nodes import Collector
|
||||||
from _pytest.nodes import Node
|
from _pytest.nodes import Node
|
||||||
from _pytest.warning_types import PytestDeprecationWarning
|
|
||||||
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
|
||||||
|
|
||||||
ignore_markinfo = pytest.mark.filterwarnings(
|
|
||||||
"ignore:MarkInfo objects:pytest.RemovedInPytest4Warning"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestMark:
|
class TestMark:
|
||||||
|
@ -25,7 +19,8 @@ class TestMark:
|
||||||
|
|
||||||
def test_pytest_mark_notcallable(self):
|
def test_pytest_mark_notcallable(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
pytest.raises((AttributeError, TypeError), mark)
|
with pytest.raises(TypeError):
|
||||||
|
mark()
|
||||||
|
|
||||||
def test_mark_with_param(self):
|
def test_mark_with_param(self):
|
||||||
def some_function(abc):
|
def some_function(abc):
|
||||||
|
@ -625,7 +620,6 @@ class TestFunctional:
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
@ignore_markinfo
|
|
||||||
def test_keyword_added_for_session(self, testdir):
|
def test_keyword_added_for_session(self, testdir):
|
||||||
testdir.makeconftest(
|
testdir.makeconftest(
|
||||||
"""
|
"""
|
||||||
|
@ -651,7 +645,7 @@ class TestFunctional:
|
||||||
assert marker.kwargs == {}
|
assert marker.kwargs == {}
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
reprec = testdir.inline_run("-m", "mark1", SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run("-m", "mark1")
|
||||||
reprec.assertoutcome(passed=1)
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
def assert_markers(self, items, **expected):
|
def assert_markers(self, items, **expected):
|
||||||
|
@ -689,7 +683,7 @@ class TestFunctional:
|
||||||
assert True
|
assert True
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(skipped=1)
|
reprec.assertoutcome(skipped=1)
|
||||||
|
|
||||||
|
|
||||||
|
@ -989,7 +983,7 @@ def test_markers_from_parametrize(testdir):
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest()
|
||||||
result.assert_outcomes(passed=4)
|
result.assert_outcomes(passed=4)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1003,15 +997,3 @@ def test_pytest_param_id_requires_string():
|
||||||
@pytest.mark.parametrize("s", (None, "hello world"))
|
@pytest.mark.parametrize("s", (None, "hello world"))
|
||||||
def test_pytest_param_id_allows_none_or_string(s):
|
def test_pytest_param_id_allows_none_or_string(s):
|
||||||
assert pytest.param(id=s)
|
assert pytest.param(id=s)
|
||||||
|
|
||||||
|
|
||||||
def test_pytest_param_warning_on_unknown_kwargs():
|
|
||||||
with pytest.warns(PytestDeprecationWarning) as warninfo:
|
|
||||||
# typo, should be marks=
|
|
||||||
pytest.param(1, 2, mark=pytest.mark.xfail())
|
|
||||||
assert warninfo[0].filename == __file__
|
|
||||||
msg, = warninfo[0].message.args
|
|
||||||
assert msg == (
|
|
||||||
"pytest.param() got unexpected keyword arguments: ['mark'].\n"
|
|
||||||
"This will be an error in future versions."
|
|
||||||
)
|
|
||||||
|
|
|
@ -72,8 +72,7 @@ def test_make_hook_recorder(testdir):
|
||||||
def test_parseconfig(testdir):
|
def test_parseconfig(testdir):
|
||||||
config1 = testdir.parseconfig()
|
config1 = testdir.parseconfig()
|
||||||
config2 = testdir.parseconfig()
|
config2 = testdir.parseconfig()
|
||||||
assert config2 != config1
|
assert config2 is not config1
|
||||||
assert config1 != pytest.config
|
|
||||||
|
|
||||||
|
|
||||||
def test_testdir_runs_with_plugin(testdir):
|
def test_testdir_runs_with_plugin(testdir):
|
||||||
|
|
|
@ -3,7 +3,6 @@ import warnings
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.recwarn import WarningsRecorder
|
from _pytest.recwarn import WarningsRecorder
|
||||||
from _pytest.warning_types import PytestDeprecationWarning
|
|
||||||
|
|
||||||
|
|
||||||
def test_recwarn_stacklevel(recwarn):
|
def test_recwarn_stacklevel(recwarn):
|
||||||
|
@ -206,22 +205,17 @@ class TestDeprecatedCall:
|
||||||
|
|
||||||
|
|
||||||
class TestWarns:
|
class TestWarns:
|
||||||
def test_strings(self):
|
def test_check_callable(self):
|
||||||
|
source = "warnings.warn('w1', RuntimeWarning)"
|
||||||
|
with pytest.raises(TypeError, match=r".* must be callable"):
|
||||||
|
pytest.warns(RuntimeWarning, source)
|
||||||
|
|
||||||
|
def test_several_messages(self):
|
||||||
# different messages, b/c Python suppresses multiple identical warnings
|
# different messages, b/c Python suppresses multiple identical warnings
|
||||||
source1 = "warnings.warn('w1', RuntimeWarning)"
|
pytest.warns(RuntimeWarning, lambda: warnings.warn("w1", RuntimeWarning))
|
||||||
source2 = "warnings.warn('w2', RuntimeWarning)"
|
with pytest.raises(pytest.fail.Exception):
|
||||||
source3 = "warnings.warn('w3', RuntimeWarning)"
|
pytest.warns(UserWarning, lambda: warnings.warn("w2", RuntimeWarning))
|
||||||
with pytest.warns(PytestDeprecationWarning) as warninfo: # yo dawg
|
pytest.warns(RuntimeWarning, lambda: warnings.warn("w3", RuntimeWarning))
|
||||||
pytest.warns(RuntimeWarning, source1)
|
|
||||||
pytest.raises(
|
|
||||||
pytest.fail.Exception, lambda: pytest.warns(UserWarning, source2)
|
|
||||||
)
|
|
||||||
pytest.warns(RuntimeWarning, source3)
|
|
||||||
assert len(warninfo) == 3
|
|
||||||
for w in warninfo:
|
|
||||||
assert w.filename == __file__
|
|
||||||
msg, = w.message.args
|
|
||||||
assert msg.startswith("warns(..., 'code(as_a_string)') is deprecated")
|
|
||||||
|
|
||||||
def test_function(self):
|
def test_function(self):
|
||||||
pytest.warns(
|
pytest.warns(
|
||||||
|
|
|
@ -5,7 +5,6 @@ import attr
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest import pathlib
|
from _pytest import pathlib
|
||||||
from _pytest.pathlib import Path
|
from _pytest.pathlib import Path
|
||||||
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
|
||||||
|
|
||||||
|
|
||||||
def test_tmpdir_fixture(testdir):
|
def test_tmpdir_fixture(testdir):
|
||||||
|
@ -14,13 +13,6 @@ def test_tmpdir_fixture(testdir):
|
||||||
results.stdout.fnmatch_lines(["*1 passed*"])
|
results.stdout.fnmatch_lines(["*1 passed*"])
|
||||||
|
|
||||||
|
|
||||||
def test_ensuretemp(recwarn):
|
|
||||||
d1 = pytest.ensuretemp("hello")
|
|
||||||
d2 = pytest.ensuretemp("hello")
|
|
||||||
assert d1 == d2
|
|
||||||
assert d1.check(dir=1)
|
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@attr.s
|
||||||
class FakeConfig:
|
class FakeConfig:
|
||||||
basetemp = attr.ib()
|
basetemp = attr.ib()
|
||||||
|
@ -85,12 +77,13 @@ def test_basetemp(testdir):
|
||||||
p = testdir.makepyfile(
|
p = testdir.makepyfile(
|
||||||
"""
|
"""
|
||||||
import pytest
|
import pytest
|
||||||
def test_1():
|
def test_1(tmpdir_factory):
|
||||||
pytest.ensuretemp("hello")
|
tmpdir_factory.mktemp('hello', numbered=False)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest(p, "--basetemp=%s" % mytemp, SHOW_PYTEST_WARNINGS_ARG)
|
result = testdir.runpytest(p, "--basetemp=%s" % mytemp)
|
||||||
assert result.ret == 0
|
assert result.ret == 0
|
||||||
|
print(mytemp)
|
||||||
assert mytemp.join("hello").check()
|
assert mytemp.join("hello").check()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -498,38 +498,15 @@ class TestDeprecationWarningsByDefault:
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("change_default", [None, "ini", "cmdline"])
|
@pytest.mark.parametrize("change_default", [None, "ini", "cmdline"])
|
||||||
def test_removed_in_pytest4_warning_as_error(testdir, change_default):
|
@pytest.mark.skip(
|
||||||
testdir.makepyfile(
|
reason="This test should be enabled again before pytest 6.0 is released"
|
||||||
"""
|
)
|
||||||
import warnings, pytest
|
|
||||||
def test():
|
|
||||||
warnings.warn(pytest.RemovedInPytest4Warning("some warning"))
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
if change_default == "ini":
|
|
||||||
testdir.makeini(
|
|
||||||
"""
|
|
||||||
[pytest]
|
|
||||||
filterwarnings =
|
|
||||||
ignore::pytest.RemovedInPytest4Warning
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
args = (
|
|
||||||
("-Wignore::pytest.RemovedInPytest4Warning",)
|
|
||||||
if change_default == "cmdline"
|
|
||||||
else ()
|
|
||||||
)
|
|
||||||
result = testdir.runpytest(*args)
|
|
||||||
if change_default is None:
|
|
||||||
result.stdout.fnmatch_lines(["* 1 failed in *"])
|
|
||||||
else:
|
|
||||||
assert change_default in ("ini", "cmdline")
|
|
||||||
result.stdout.fnmatch_lines(["* 1 passed in *"])
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("change_default", [None, "ini", "cmdline"])
|
|
||||||
def test_deprecation_warning_as_error(testdir, change_default):
|
def test_deprecation_warning_as_error(testdir, change_default):
|
||||||
|
"""This ensures that PytestDeprecationWarnings raised by pytest are turned into errors.
|
||||||
|
|
||||||
|
This test should be enabled as part of each major release, and skipped again afterwards
|
||||||
|
to ensure our deprecations are turning into warnings as expected.
|
||||||
|
"""
|
||||||
testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
"""
|
"""
|
||||||
import warnings, pytest
|
import warnings, pytest
|
||||||
|
|
3
tox.ini
3
tox.ini
|
@ -128,9 +128,6 @@ norecursedirs = testing/example_scripts
|
||||||
xfail_strict=true
|
xfail_strict=true
|
||||||
filterwarnings =
|
filterwarnings =
|
||||||
error
|
error
|
||||||
ignore:yield tests are deprecated, and scheduled to be removed in pytest 4.0:pytest.RemovedInPytest4Warning
|
|
||||||
ignore:Metafunc.addcall is deprecated and scheduled to be removed in pytest 4.0:pytest.RemovedInPytest4Warning
|
|
||||||
ignore::pytest.RemovedInPytest4Warning
|
|
||||||
ignore:Module already imported so cannot be rewritten:pytest.PytestWarning
|
ignore:Module already imported so cannot be rewritten:pytest.PytestWarning
|
||||||
# produced by path.local
|
# produced by path.local
|
||||||
ignore:bad escape.*:DeprecationWarning:re
|
ignore:bad escape.*:DeprecationWarning:re
|
||||||
|
|
Loading…
Reference in New Issue