aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest/py3/_pytest/recwarn.py
diff options
context:
space:
mode:
authorarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-02-09 12:00:52 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 15:58:17 +0300
commit8e1413fed79d1e8036e65228af6c93399ccf5502 (patch)
tree502c9df7b2614d20541c7a2d39d390e9a51877cc /contrib/python/pytest/py3/_pytest/recwarn.py
parent6b813c17d56d1d05f92c61ddc347d0e4d358fe85 (diff)
downloadydb-8e1413fed79d1e8036e65228af6c93399ccf5502.tar.gz
intermediate changes
ref:614ed510ddd3cdf86a8c5dbf19afd113397e0172
Diffstat (limited to 'contrib/python/pytest/py3/_pytest/recwarn.py')
-rw-r--r--contrib/python/pytest/py3/_pytest/recwarn.py134
1 files changed, 83 insertions, 51 deletions
diff --git a/contrib/python/pytest/py3/_pytest/recwarn.py b/contrib/python/pytest/py3/_pytest/recwarn.py
index c57c94b1cb1..d872d9da401 100644
--- a/contrib/python/pytest/py3/_pytest/recwarn.py
+++ b/contrib/python/pytest/py3/_pytest/recwarn.py
@@ -1,53 +1,79 @@
-""" recording warnings during test function execution. """
+"""Record warnings during test function execution."""
import re
import warnings
from types import TracebackType
from typing import Any
from typing import Callable
+from typing import Generator
from typing import Iterator
from typing import List
from typing import Optional
+from typing import overload
from typing import Pattern
from typing import Tuple
+from typing import Type
+from typing import TypeVar
from typing import Union
-from _pytest.compat import overload
-from _pytest.compat import TYPE_CHECKING
-from _pytest.fixtures import yield_fixture
+from _pytest.compat import final
+from _pytest.deprecated import check_ispytest
+from _pytest.fixtures import fixture
from _pytest.outcomes import fail
-if TYPE_CHECKING:
- from typing import Type
+T = TypeVar("T")
-@yield_fixture
-def recwarn():
+
+@fixture
+def recwarn() -> Generator["WarningsRecorder", None, None]:
"""Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.
See http://docs.python.org/library/warnings.html for information
on warning categories.
"""
- wrec = WarningsRecorder()
+ wrec = WarningsRecorder(_ispytest=True)
with wrec:
warnings.simplefilter("default")
yield wrec
-def deprecated_call(func=None, *args, **kwargs):
- """context manager that can be used to ensure a block of code triggers a
- ``DeprecationWarning`` or ``PendingDeprecationWarning``::
+@overload
+def deprecated_call(
+ *, match: Optional[Union[str, Pattern[str]]] = ...
+) -> "WarningsRecorder":
+ ...
+
+
+@overload
+def deprecated_call(func: Callable[..., T], *args: Any, **kwargs: Any) -> T:
+ ...
+
+
+def deprecated_call(
+ func: Optional[Callable[..., Any]] = None, *args: Any, **kwargs: Any
+) -> Union["WarningsRecorder", Any]:
+ """Assert that code produces a ``DeprecationWarning`` or ``PendingDeprecationWarning``.
+
+ This function can be used as a context manager::
>>> import warnings
>>> def api_call_v2():
... warnings.warn('use v3 of this api', DeprecationWarning)
... return 200
- >>> with deprecated_call():
+ >>> import pytest
+ >>> with pytest.deprecated_call():
... assert api_call_v2() == 200
- ``deprecated_call`` can also be used by passing a function and ``*args`` and ``*kwargs``,
- in which case it will ensure calling ``func(*args, **kwargs)`` produces one of the warnings
- types above.
+ It can also be used by passing a function and ``*args`` and ``**kwargs``,
+ in which case it will ensure calling ``func(*args, **kwargs)`` produces one of
+ the warnings types above. The return value is the return value of the function.
+
+ In the context manager form you may use the keyword argument ``match`` to assert
+ that the warning matches a text or regex.
+
+ The context manager produces a list of :class:`warnings.WarningMessage` objects,
+ one for each warning raised.
"""
__tracebackhide__ = True
if func is not None:
@@ -57,29 +83,28 @@ def deprecated_call(func=None, *args, **kwargs):
@overload
def warns(
- expected_warning: Optional[Union["Type[Warning]", Tuple["Type[Warning]", ...]]],
+ expected_warning: Optional[Union[Type[Warning], Tuple[Type[Warning], ...]]],
*,
- match: "Optional[Union[str, Pattern]]" = ...
+ match: Optional[Union[str, Pattern[str]]] = ...,
) -> "WarningsChecker":
- raise NotImplementedError()
+ ...
-@overload # noqa: F811
-def warns( # noqa: F811
- expected_warning: Optional[Union["Type[Warning]", Tuple["Type[Warning]", ...]]],
- func: Callable,
+@overload
+def warns(
+ expected_warning: Optional[Union[Type[Warning], Tuple[Type[Warning], ...]]],
+ func: Callable[..., T],
*args: Any,
- match: Optional[Union[str, "Pattern"]] = ...,
- **kwargs: Any
-) -> Union[Any]:
- raise NotImplementedError()
+ **kwargs: Any,
+) -> T:
+ ...
-def warns( # noqa: F811
- expected_warning: Optional[Union["Type[Warning]", Tuple["Type[Warning]", ...]]],
+def warns(
+ expected_warning: Optional[Union[Type[Warning], Tuple[Type[Warning], ...]]],
*args: Any,
- match: Optional[Union[str, "Pattern"]] = None,
- **kwargs: Any
+ match: Optional[Union[str, Pattern[str]]] = None,
+ **kwargs: Any,
) -> Union["WarningsChecker", Any]:
r"""Assert that code raises a particular class of warning.
@@ -91,21 +116,22 @@ def warns( # noqa: F811
one for each warning raised.
This function can be used as a context manager, or any of the other ways
- ``pytest.raises`` can be used::
+ :func:`pytest.raises` can be used::
- >>> with warns(RuntimeWarning):
+ >>> import pytest
+ >>> with pytest.warns(RuntimeWarning):
... warnings.warn("my warning", RuntimeWarning)
In the context manager form you may use the keyword argument ``match`` to assert
- that the exception matches a text or regex::
+ that the warning matches a text or regex::
- >>> with warns(UserWarning, match='must be 0 or None'):
+ >>> with pytest.warns(UserWarning, match='must be 0 or None'):
... warnings.warn("value must be 0 or None", UserWarning)
- >>> with warns(UserWarning, match=r'must be \d+$'):
+ >>> with pytest.warns(UserWarning, match=r'must be \d+$'):
... warnings.warn("value must be 42", UserWarning)
- >>> with warns(UserWarning, match=r'must be \d+$'):
+ >>> with pytest.warns(UserWarning, match=r'must be \d+$'):
... warnings.warn("this is not here", UserWarning)
Traceback (most recent call last):
...
@@ -119,14 +145,14 @@ def warns( # noqa: F811
msg += ", ".join(sorted(kwargs))
msg += "\nUse context-manager form instead?"
raise TypeError(msg)
- return WarningsChecker(expected_warning, match_expr=match)
+ return WarningsChecker(expected_warning, match_expr=match, _ispytest=True)
else:
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, _ispytest=True):
return func(*args[1:], **kwargs)
@@ -136,21 +162,23 @@ class WarningsRecorder(warnings.catch_warnings):
Adapted from `warnings.catch_warnings`.
"""
- def __init__(self):
- super().__init__(record=True)
+ def __init__(self, *, _ispytest: bool = False) -> None:
+ check_ispytest(_ispytest)
+ # Type ignored due to the way typeshed handles warnings.catch_warnings.
+ super().__init__(record=True) # type: ignore[call-arg]
self._entered = False
- self._list = [] # type: List[warnings._Record]
+ self._list: List[warnings.WarningMessage] = []
@property
- def list(self) -> List["warnings._Record"]:
+ def list(self) -> List["warnings.WarningMessage"]:
"""The list of recorded warnings."""
return self._list
- def __getitem__(self, i: int) -> "warnings._Record":
+ def __getitem__(self, i: int) -> "warnings.WarningMessage":
"""Get a recorded warning by index."""
return self._list[i]
- def __iter__(self) -> Iterator["warnings._Record"]:
+ def __iter__(self) -> Iterator["warnings.WarningMessage"]:
"""Iterate through the recorded warnings."""
return iter(self._list)
@@ -158,7 +186,7 @@ class WarningsRecorder(warnings.catch_warnings):
"""The number of recorded warnings."""
return len(self._list)
- def pop(self, cls: "Type[Warning]" = Warning) -> "warnings._Record":
+ def pop(self, cls: Type[Warning] = Warning) -> "warnings.WarningMessage":
"""Pop the first recorded warning, raise exception if not exists."""
for i, w in enumerate(self._list):
if issubclass(w.category, cls):
@@ -185,7 +213,7 @@ class WarningsRecorder(warnings.catch_warnings):
def __exit__(
self,
- exc_type: Optional["Type[BaseException]"],
+ exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
@@ -200,15 +228,19 @@ class WarningsRecorder(warnings.catch_warnings):
self._entered = False
+@final
class WarningsChecker(WarningsRecorder):
def __init__(
self,
expected_warning: Optional[
- Union["Type[Warning]", Tuple["Type[Warning]", ...]]
+ Union[Type[Warning], Tuple[Type[Warning], ...]]
] = None,
- match_expr: Optional[Union[str, "Pattern"]] = None,
+ match_expr: Optional[Union[str, Pattern[str]]] = None,
+ *,
+ _ispytest: bool = False,
) -> None:
- super().__init__()
+ check_ispytest(_ispytest)
+ super().__init__(_ispytest=True)
msg = "exceptions must be derived from Warning, not %s"
if expected_warning is None:
@@ -228,7 +260,7 @@ class WarningsChecker(WarningsRecorder):
def __exit__(
self,
- exc_type: Optional["Type[BaseException]"],
+ exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None: