Remove deprecated pytest.{exit,fail,skip}(msg=...) argument

This commit is contained in:
Ran Benita 2024-01-01 13:41:52 +02:00
parent 477959ef7d
commit 0591569b4b
5 changed files with 39 additions and 206 deletions

View File

@ -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

View File

@ -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"

View File

@ -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()."""

View File

@ -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("")

View File

@ -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(
""" """