permit node to warn with any warning type, not just PytestWarning (#8052)
Co-authored-by: Bruno Oliveira <nicoddemus@gmail.com>
This commit is contained in:
parent
afd53ede6f
commit
52fef811c2
|
@ -0,0 +1 @@
|
||||||
|
:meth:`Node.warn <_pytest.nodes.Node.warn>` now permits any subclass of :class:`Warning`, not just :class:`PytestWarning <pytest.PytestWarning>`.
|
|
@ -34,7 +34,6 @@ from _pytest.store import Store
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
# Imported here due to circular import.
|
# Imported here due to circular import.
|
||||||
from _pytest.main import Session
|
from _pytest.main import Session
|
||||||
from _pytest.warning_types import PytestWarning
|
|
||||||
from _pytest._code.code import _TracebackStyle
|
from _pytest._code.code import _TracebackStyle
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,27 +197,31 @@ class Node(metaclass=NodeMeta):
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return "<{} {}>".format(self.__class__.__name__, getattr(self, "name", None))
|
return "<{} {}>".format(self.__class__.__name__, getattr(self, "name", None))
|
||||||
|
|
||||||
def warn(self, warning: "PytestWarning") -> None:
|
def warn(self, warning: Warning) -> None:
|
||||||
"""Issue a warning for this Node.
|
"""Issue a warning for this Node.
|
||||||
|
|
||||||
Warnings will be displayed after the test session, unless explicitly suppressed.
|
Warnings will be displayed after the test session, unless explicitly suppressed.
|
||||||
|
|
||||||
:param Warning warning:
|
:param Warning warning:
|
||||||
The warning instance to issue. Must be a subclass of PytestWarning.
|
The warning instance to issue.
|
||||||
|
|
||||||
:raises ValueError: If ``warning`` instance is not a subclass of PytestWarning.
|
:raises ValueError: If ``warning`` instance is not a subclass of Warning.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
node.warn(PytestWarning("some message"))
|
node.warn(PytestWarning("some message"))
|
||||||
"""
|
node.warn(UserWarning("some message"))
|
||||||
from _pytest.warning_types import PytestWarning
|
|
||||||
|
|
||||||
if not isinstance(warning, PytestWarning):
|
.. versionchanged:: 6.2
|
||||||
|
Any subclass of :class:`Warning` is now accepted, rather than only
|
||||||
|
:class:`PytestWarning <pytest.PytestWarning>` subclasses.
|
||||||
|
"""
|
||||||
|
# enforce type checks here to avoid getting a generic type error later otherwise.
|
||||||
|
if not isinstance(warning, Warning):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"warning must be an instance of PytestWarning or subclass, got {!r}".format(
|
"warning must be an instance of Warning or subclass, got {!r}".format(
|
||||||
warning
|
warning
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
|
from typing import Type
|
||||||
|
|
||||||
import py
|
import py
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
from _pytest.pytester import Pytester
|
from _pytest.pytester import Pytester
|
||||||
|
from _pytest.warning_types import PytestWarning
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
@ -35,15 +37,33 @@ def test_node_from_parent_disallowed_arguments() -> None:
|
||||||
nodes.Node.from_parent(None, config=None) # type: ignore[arg-type]
|
nodes.Node.from_parent(None, config=None) # type: ignore[arg-type]
|
||||||
|
|
||||||
|
|
||||||
def test_std_warn_not_pytestwarning(pytester: Pytester) -> None:
|
@pytest.mark.parametrize(
|
||||||
|
"warn_type, msg", [(DeprecationWarning, "deprecated"), (PytestWarning, "pytest")]
|
||||||
|
)
|
||||||
|
def test_node_warn_is_no_longer_only_pytest_warnings(
|
||||||
|
pytester: Pytester, warn_type: Type[Warning], msg: str
|
||||||
|
) -> None:
|
||||||
items = pytester.getitems(
|
items = pytester.getitems(
|
||||||
"""
|
"""
|
||||||
def test():
|
def test():
|
||||||
pass
|
pass
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
with pytest.raises(ValueError, match=".*instance of PytestWarning.*"):
|
with pytest.warns(warn_type, match=msg):
|
||||||
items[0].warn(UserWarning("some warning")) # type: ignore[arg-type]
|
items[0].warn(warn_type(msg))
|
||||||
|
|
||||||
|
|
||||||
|
def test_node_warning_enforces_warning_types(pytester: Pytester) -> None:
|
||||||
|
items = pytester.getitems(
|
||||||
|
"""
|
||||||
|
def test():
|
||||||
|
pass
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
with pytest.raises(
|
||||||
|
ValueError, match="warning must be an instance of Warning or subclass"
|
||||||
|
):
|
||||||
|
items[0].warn(Exception("ok")) # type: ignore[arg-type]
|
||||||
|
|
||||||
|
|
||||||
def test__check_initialpaths_for_relpath() -> None:
|
def test__check_initialpaths_for_relpath() -> None:
|
||||||
|
|
Loading…
Reference in New Issue