Remove deprecated pytest.{exit,fail,skip}(msg=...) argument
This commit is contained in:
parent
477959ef7d
commit
0591569b4b
|
@ -255,37 +255,6 @@ Directly constructing the following classes is now deprecated:
|
||||||
|
|
||||||
These constructors have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 8.
|
These constructors have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 8.
|
||||||
|
|
||||||
Passing ``msg=`` to ``pytest.skip``, ``pytest.fail`` or ``pytest.exit``
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. deprecated:: 7.0
|
|
||||||
|
|
||||||
Passing the keyword argument ``msg`` to :func:`pytest.skip`, :func:`pytest.fail` or :func:`pytest.exit`
|
|
||||||
is now deprecated and ``reason`` should be used instead. This change is to bring consistency between these
|
|
||||||
functions and the ``@pytest.mark.skip`` and ``@pytest.mark.xfail`` markers which already accept a ``reason`` argument.
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
def test_fail_example():
|
|
||||||
# old
|
|
||||||
pytest.fail(msg="foo")
|
|
||||||
# new
|
|
||||||
pytest.fail(reason="bar")
|
|
||||||
|
|
||||||
|
|
||||||
def test_skip_example():
|
|
||||||
# old
|
|
||||||
pytest.skip(msg="foo")
|
|
||||||
# new
|
|
||||||
pytest.skip(reason="bar")
|
|
||||||
|
|
||||||
|
|
||||||
def test_exit_example():
|
|
||||||
# old
|
|
||||||
pytest.exit(msg="foo")
|
|
||||||
# new
|
|
||||||
pytest.exit(reason="bar")
|
|
||||||
|
|
||||||
.. _diamond-inheritance-deprecated:
|
.. _diamond-inheritance-deprecated:
|
||||||
|
|
||||||
Diamond inheritance between :class:`pytest.Collector` and :class:`pytest.Item`
|
Diamond inheritance between :class:`pytest.Collector` and :class:`pytest.Item`
|
||||||
|
@ -414,6 +383,39 @@ an appropriate period of deprecation has passed.
|
||||||
|
|
||||||
Some breaking changes which could not be deprecated are also listed.
|
Some breaking changes which could not be deprecated are also listed.
|
||||||
|
|
||||||
|
Passing ``msg=`` to ``pytest.skip``, ``pytest.fail`` or ``pytest.exit``
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. deprecated:: 7.0
|
||||||
|
.. versionremoved:: 8.0
|
||||||
|
|
||||||
|
Passing the keyword argument ``msg`` to :func:`pytest.skip`, :func:`pytest.fail` or :func:`pytest.exit`
|
||||||
|
is now deprecated and ``reason`` should be used instead. This change is to bring consistency between these
|
||||||
|
functions and the ``@pytest.mark.skip`` and ``@pytest.mark.xfail`` markers which already accept a ``reason`` argument.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def test_fail_example():
|
||||||
|
# old
|
||||||
|
pytest.fail(msg="foo")
|
||||||
|
# new
|
||||||
|
pytest.fail(reason="bar")
|
||||||
|
|
||||||
|
|
||||||
|
def test_skip_example():
|
||||||
|
# old
|
||||||
|
pytest.skip(msg="foo")
|
||||||
|
# new
|
||||||
|
pytest.skip(reason="bar")
|
||||||
|
|
||||||
|
|
||||||
|
def test_exit_example():
|
||||||
|
# old
|
||||||
|
pytest.exit(msg="foo")
|
||||||
|
# new
|
||||||
|
pytest.exit(reason="bar")
|
||||||
|
|
||||||
|
|
||||||
.. _instance-collector-deprecation:
|
.. _instance-collector-deprecation:
|
||||||
|
|
||||||
The ``pytest.Instance`` collector
|
The ``pytest.Instance`` collector
|
||||||
|
|
|
@ -65,11 +65,6 @@ NODE_CTOR_FSPATH_ARG = UnformattedWarning(
|
||||||
"#fspath-argument-for-node-constructors-replaced-with-pathlib-path",
|
"#fspath-argument-for-node-constructors-replaced-with-pathlib-path",
|
||||||
)
|
)
|
||||||
|
|
||||||
KEYWORD_MSG_ARG = UnformattedWarning(
|
|
||||||
PytestRemovedIn8Warning,
|
|
||||||
"pytest.{func}(msg=...) is now deprecated, use pytest.{func}(reason=...) instead",
|
|
||||||
)
|
|
||||||
|
|
||||||
HOOK_LEGACY_MARKING = UnformattedWarning(
|
HOOK_LEGACY_MARKING = UnformattedWarning(
|
||||||
PytestDeprecationWarning,
|
PytestDeprecationWarning,
|
||||||
"The hook{type} {fullname} uses old-style configuration options (marks or attributes).\n"
|
"The hook{type} {fullname} uses old-style configuration options (marks or attributes).\n"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
"""Exception classes and constants handling test outcomes as well as
|
"""Exception classes and constants handling test outcomes as well as
|
||||||
functions creating them."""
|
functions creating them."""
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
@ -11,8 +10,6 @@ from typing import Protocol
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
from _pytest.deprecated import KEYWORD_MSG_ARG
|
|
||||||
|
|
||||||
|
|
||||||
class OutcomeException(BaseException):
|
class OutcomeException(BaseException):
|
||||||
"""OutcomeException and its subclass instances indicate and contain info
|
"""OutcomeException and its subclass instances indicate and contain info
|
||||||
|
@ -103,7 +100,8 @@ def _with_exception(exception_type: _ET) -> Callable[[_F], _WithException[_F, _E
|
||||||
|
|
||||||
@_with_exception(Exit)
|
@_with_exception(Exit)
|
||||||
def exit(
|
def exit(
|
||||||
reason: str = "", returncode: Optional[int] = None, *, msg: Optional[str] = None
|
reason: str = "",
|
||||||
|
returncode: Optional[int] = None,
|
||||||
) -> NoReturn:
|
) -> NoReturn:
|
||||||
"""Exit testing process.
|
"""Exit testing process.
|
||||||
|
|
||||||
|
@ -113,28 +111,16 @@ def exit(
|
||||||
|
|
||||||
:param returncode:
|
:param returncode:
|
||||||
Return code to be used when exiting pytest. None means the same as ``0`` (no error), same as :func:`sys.exit`.
|
Return code to be used when exiting pytest. None means the same as ``0`` (no error), same as :func:`sys.exit`.
|
||||||
|
|
||||||
:param msg:
|
|
||||||
Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead.
|
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
from _pytest.config import UsageError
|
|
||||||
|
|
||||||
if reason and msg:
|
|
||||||
raise UsageError(
|
|
||||||
"cannot pass reason and msg to exit(), `msg` is deprecated, use `reason`."
|
|
||||||
)
|
|
||||||
if not reason:
|
|
||||||
if msg is None:
|
|
||||||
raise UsageError("exit() requires a reason argument")
|
|
||||||
warnings.warn(KEYWORD_MSG_ARG.format(func="exit"), stacklevel=2)
|
|
||||||
reason = msg
|
|
||||||
raise Exit(reason, returncode)
|
raise Exit(reason, returncode)
|
||||||
|
|
||||||
|
|
||||||
@_with_exception(Skipped)
|
@_with_exception(Skipped)
|
||||||
def skip(
|
def skip(
|
||||||
reason: str = "", *, allow_module_level: bool = False, msg: Optional[str] = None
|
reason: str = "",
|
||||||
|
*,
|
||||||
|
allow_module_level: bool = False,
|
||||||
) -> NoReturn:
|
) -> NoReturn:
|
||||||
"""Skip an executing test with the given message.
|
"""Skip an executing test with the given message.
|
||||||
|
|
||||||
|
@ -153,9 +139,6 @@ def skip(
|
||||||
|
|
||||||
Defaults to False.
|
Defaults to False.
|
||||||
|
|
||||||
:param msg:
|
|
||||||
Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
It is better to use the :ref:`pytest.mark.skipif ref` marker when
|
It is better to use the :ref:`pytest.mark.skipif ref` marker when
|
||||||
possible to declare a test to be skipped under certain conditions
|
possible to declare a test to be skipped under certain conditions
|
||||||
|
@ -164,12 +147,11 @@ def skip(
|
||||||
to skip a doctest statically.
|
to skip a doctest statically.
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
reason = _resolve_msg_to_reason("skip", reason, msg)
|
|
||||||
raise Skipped(msg=reason, allow_module_level=allow_module_level)
|
raise Skipped(msg=reason, allow_module_level=allow_module_level)
|
||||||
|
|
||||||
|
|
||||||
@_with_exception(Failed)
|
@_with_exception(Failed)
|
||||||
def fail(reason: str = "", pytrace: bool = True, msg: Optional[str] = None) -> NoReturn:
|
def fail(reason: str = "", pytrace: bool = True) -> NoReturn:
|
||||||
"""Explicitly fail an executing test with the given message.
|
"""Explicitly fail an executing test with the given message.
|
||||||
|
|
||||||
:param reason:
|
:param reason:
|
||||||
|
@ -178,51 +160,11 @@ def fail(reason: str = "", pytrace: bool = True, msg: Optional[str] = None) -> N
|
||||||
:param pytrace:
|
:param pytrace:
|
||||||
If False, msg represents the full failure information and no
|
If False, msg represents the full failure information and no
|
||||||
python traceback will be reported.
|
python traceback will be reported.
|
||||||
|
|
||||||
:param msg:
|
|
||||||
Same as ``reason``, but deprecated. Will be removed in a future version, use ``reason`` instead.
|
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
reason = _resolve_msg_to_reason("fail", reason, msg)
|
|
||||||
raise Failed(msg=reason, pytrace=pytrace)
|
raise Failed(msg=reason, pytrace=pytrace)
|
||||||
|
|
||||||
|
|
||||||
def _resolve_msg_to_reason(
|
|
||||||
func_name: str, reason: str, msg: Optional[str] = None
|
|
||||||
) -> str:
|
|
||||||
"""
|
|
||||||
Handles converting the deprecated msg parameter if provided into
|
|
||||||
reason, raising a deprecation warning. This function will be removed
|
|
||||||
when the optional msg argument is removed from here in future.
|
|
||||||
|
|
||||||
:param str func_name:
|
|
||||||
The name of the offending function, this is formatted into the deprecation message.
|
|
||||||
|
|
||||||
:param str reason:
|
|
||||||
The reason= passed into either pytest.fail() or pytest.skip()
|
|
||||||
|
|
||||||
:param str msg:
|
|
||||||
The msg= passed into either pytest.fail() or pytest.skip(). This will
|
|
||||||
be converted into reason if it is provided to allow pytest.skip(msg=) or
|
|
||||||
pytest.fail(msg=) to continue working in the interim period.
|
|
||||||
|
|
||||||
:returns:
|
|
||||||
The value to use as reason.
|
|
||||||
|
|
||||||
"""
|
|
||||||
__tracebackhide__ = True
|
|
||||||
if msg is not None:
|
|
||||||
if reason:
|
|
||||||
from pytest import UsageError
|
|
||||||
|
|
||||||
raise UsageError(
|
|
||||||
f"Passing both ``reason`` and ``msg`` to pytest.{func_name}(...) is not permitted."
|
|
||||||
)
|
|
||||||
warnings.warn(KEYWORD_MSG_ARG.format(func=func_name), stacklevel=3)
|
|
||||||
reason = msg
|
|
||||||
return reason
|
|
||||||
|
|
||||||
|
|
||||||
class XFailed(Failed):
|
class XFailed(Failed):
|
||||||
"""Raised from an explicit call to pytest.xfail()."""
|
"""Raised from an explicit call to pytest.xfail()."""
|
||||||
|
|
||||||
|
|
|
@ -120,64 +120,6 @@ def test_hookproxy_warnings_for_pathlib(tmp_path, hooktype, request):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestSkipMsgArgumentDeprecated:
|
|
||||||
def test_skip_with_msg_is_deprecated(self, pytester: Pytester) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
def test_skipping_msg():
|
|
||||||
pytest.skip(msg="skippedmsg")
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
result = pytester.runpytest(p, "-Wdefault::pytest.PytestRemovedIn8Warning")
|
|
||||||
result.stdout.fnmatch_lines(
|
|
||||||
[
|
|
||||||
"*PytestRemovedIn8Warning: pytest.skip(msg=...) is now deprecated, "
|
|
||||||
"use pytest.skip(reason=...) instead",
|
|
||||||
'*pytest.skip(msg="skippedmsg")*',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
result.assert_outcomes(skipped=1, warnings=1)
|
|
||||||
|
|
||||||
def test_fail_with_msg_is_deprecated(self, pytester: Pytester) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
def test_failing_msg():
|
|
||||||
pytest.fail(msg="failedmsg")
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
result = pytester.runpytest(p, "-Wdefault::pytest.PytestRemovedIn8Warning")
|
|
||||||
result.stdout.fnmatch_lines(
|
|
||||||
[
|
|
||||||
"*PytestRemovedIn8Warning: pytest.fail(msg=...) is now deprecated, "
|
|
||||||
"use pytest.fail(reason=...) instead",
|
|
||||||
'*pytest.fail(msg="failedmsg")',
|
|
||||||
]
|
|
||||||
)
|
|
||||||
result.assert_outcomes(failed=1, warnings=1)
|
|
||||||
|
|
||||||
def test_exit_with_msg_is_deprecated(self, pytester: Pytester) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
def test_exit_msg():
|
|
||||||
pytest.exit(msg="exitmsg")
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
result = pytester.runpytest(p, "-Wdefault::pytest.PytestRemovedIn8Warning")
|
|
||||||
result.stdout.fnmatch_lines(
|
|
||||||
[
|
|
||||||
"*PytestRemovedIn8Warning: pytest.exit(msg=...) is now deprecated, "
|
|
||||||
"use pytest.exit(reason=...) instead",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
result.assert_outcomes(warnings=1)
|
|
||||||
|
|
||||||
|
|
||||||
def test_node_ctor_fspath_argument_is_deprecated(pytester: Pytester) -> None:
|
def test_node_ctor_fspath_argument_is_deprecated(pytester: Pytester) -> None:
|
||||||
mod = pytester.getmodulecol("")
|
mod = pytester.getmodulecol("")
|
||||||
|
|
||||||
|
|
|
@ -1494,54 +1494,6 @@ def test_fail_using_reason_works_ok(pytester: Pytester) -> None:
|
||||||
result.assert_outcomes(failed=1)
|
result.assert_outcomes(failed=1)
|
||||||
|
|
||||||
|
|
||||||
def test_fail_fails_with_msg_and_reason(pytester: Pytester) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
def test_fail_both_arguments():
|
|
||||||
pytest.fail(reason="foo", msg="bar")
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
result = pytester.runpytest(p)
|
|
||||||
result.stdout.fnmatch_lines(
|
|
||||||
"*UsageError: Passing both ``reason`` and ``msg`` to pytest.fail(...) is not permitted.*"
|
|
||||||
)
|
|
||||||
result.assert_outcomes(failed=1)
|
|
||||||
|
|
||||||
|
|
||||||
def test_skip_fails_with_msg_and_reason(pytester: Pytester) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
def test_skip_both_arguments():
|
|
||||||
pytest.skip(reason="foo", msg="bar")
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
result = pytester.runpytest(p)
|
|
||||||
result.stdout.fnmatch_lines(
|
|
||||||
"*UsageError: Passing both ``reason`` and ``msg`` to pytest.skip(...) is not permitted.*"
|
|
||||||
)
|
|
||||||
result.assert_outcomes(failed=1)
|
|
||||||
|
|
||||||
|
|
||||||
def test_exit_with_msg_and_reason_fails(pytester: Pytester) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
def test_exit_both_arguments():
|
|
||||||
pytest.exit(reason="foo", msg="bar")
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
result = pytester.runpytest(p)
|
|
||||||
result.stdout.fnmatch_lines(
|
|
||||||
"*UsageError: cannot pass reason and msg to exit(), `msg` is deprecated, use `reason`.*"
|
|
||||||
)
|
|
||||||
result.assert_outcomes(failed=1)
|
|
||||||
|
|
||||||
|
|
||||||
def test_exit_with_reason_works_ok(pytester: Pytester) -> None:
|
def test_exit_with_reason_works_ok(pytester: Pytester) -> None:
|
||||||
p = pytester.makepyfile(
|
p = pytester.makepyfile(
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue