aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest/py3/_pytest/recwarn.py
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/python/pytest/py3/_pytest/recwarn.py')
-rw-r--r--contrib/python/pytest/py3/_pytest/recwarn.py296
1 files changed, 0 insertions, 296 deletions
diff --git a/contrib/python/pytest/py3/_pytest/recwarn.py b/contrib/python/pytest/py3/_pytest/recwarn.py
deleted file mode 100644
index 175b571a80..0000000000
--- a/contrib/python/pytest/py3/_pytest/recwarn.py
+++ /dev/null
@@ -1,296 +0,0 @@
-"""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 final
-from _pytest.deprecated import check_ispytest
-from _pytest.deprecated import WARNS_NONE_ARG
-from _pytest.fixtures import fixture
-from _pytest.outcomes import fail
-
-
-T = TypeVar("T")
-
-
-@fixture
-def recwarn() -> Generator["WarningsRecorder", None, None]:
- """Return a :class:`WarningsRecorder` instance that records all warnings emitted by test functions.
-
- See https://docs.python.org/library/how-to/capture-warnings.html for information
- on warning categories.
- """
- wrec = WarningsRecorder(_ispytest=True)
- with wrec:
- warnings.simplefilter("default")
- yield wrec
-
-
-@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
-
- >>> import pytest
- >>> with pytest.deprecated_call():
- ... assert api_call_v2() == 200
-
- 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:
- args = (func,) + args
- return warns((DeprecationWarning, PendingDeprecationWarning), *args, **kwargs)
-
-
-@overload
-def warns(
- expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = ...,
- *,
- match: Optional[Union[str, Pattern[str]]] = ...,
-) -> "WarningsChecker":
- ...
-
-
-@overload
-def warns(
- expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]],
- func: Callable[..., T],
- *args: Any,
- **kwargs: Any,
-) -> T:
- ...
-
-
-def warns(
- expected_warning: Union[Type[Warning], Tuple[Type[Warning], ...]] = Warning,
- *args: Any,
- match: Optional[Union[str, Pattern[str]]] = None,
- **kwargs: Any,
-) -> Union["WarningsChecker", Any]:
- r"""Assert that code raises a particular class of warning.
-
- Specifically, the parameter ``expected_warning`` can be a warning class or
- sequence of warning classes, and the inside the ``with`` block must issue a warning of that class or
- classes.
-
- This helper produces a list of :class:`warnings.WarningMessage` objects,
- one for each warning raised.
-
- This function can be used as a context manager, or any of the other ways
- :func:`pytest.raises` can be used::
-
- >>> 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 warning matches a text or regex::
-
- >>> with pytest.warns(UserWarning, match='must be 0 or None'):
- ... warnings.warn("value must be 0 or None", UserWarning)
-
- >>> with pytest.warns(UserWarning, match=r'must be \d+$'):
- ... warnings.warn("value must be 42", UserWarning)
-
- >>> with pytest.warns(UserWarning, match=r'must be \d+$'):
- ... warnings.warn("this is not here", UserWarning)
- Traceback (most recent call last):
- ...
- Failed: DID NOT WARN. No warnings of type ...UserWarning... were emitted...
-
- """
- __tracebackhide__ = True
- if not args:
- if kwargs:
- msg = "Unexpected keyword arguments passed to pytest.warns: "
- msg += ", ".join(sorted(kwargs))
- msg += "\nUse context-manager form instead?"
- raise TypeError(msg)
- return WarningsChecker(expected_warning, match_expr=match, _ispytest=True)
- else:
- func = args[0]
- if not callable(func):
- raise TypeError(f"{func!r} object (type: {type(func)}) must be callable")
- with WarningsChecker(expected_warning, _ispytest=True):
- return func(*args[1:], **kwargs)
-
-
-class WarningsRecorder(warnings.catch_warnings):
- """A context manager to record raised warnings.
-
- Adapted from `warnings.catch_warnings`.
- """
-
- 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: List[warnings.WarningMessage] = []
-
- @property
- def list(self) -> List["warnings.WarningMessage"]:
- """The list of recorded warnings."""
- return self._list
-
- def __getitem__(self, i: int) -> "warnings.WarningMessage":
- """Get a recorded warning by index."""
- return self._list[i]
-
- def __iter__(self) -> Iterator["warnings.WarningMessage"]:
- """Iterate through the recorded warnings."""
- return iter(self._list)
-
- def __len__(self) -> int:
- """The number of recorded warnings."""
- return len(self._list)
-
- 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):
- return self._list.pop(i)
- __tracebackhide__ = True
- raise AssertionError("%r not found in warning list" % cls)
-
- def clear(self) -> None:
- """Clear the list of recorded warnings."""
- self._list[:] = []
-
- # Type ignored because it doesn't exactly warnings.catch_warnings.__enter__
- # -- it returns a List but we only emulate one.
- def __enter__(self) -> "WarningsRecorder": # type: ignore
- if self._entered:
- __tracebackhide__ = True
- raise RuntimeError("Cannot enter %r twice" % self)
- _list = super().__enter__()
- # record=True means it's None.
- assert _list is not None
- self._list = _list
- warnings.simplefilter("always")
- return self
-
- def __exit__(
- self,
- exc_type: Optional[Type[BaseException]],
- exc_val: Optional[BaseException],
- exc_tb: Optional[TracebackType],
- ) -> None:
- if not self._entered:
- __tracebackhide__ = True
- raise RuntimeError("Cannot exit %r without entering first" % self)
-
- super().__exit__(exc_type, exc_val, exc_tb)
-
- # Built-in catch_warnings does not reset entered state so we do it
- # manually here for this context manager to become reusable.
- self._entered = False
-
-
-@final
-class WarningsChecker(WarningsRecorder):
- def __init__(
- self,
- expected_warning: Optional[
- Union[Type[Warning], Tuple[Type[Warning], ...]]
- ] = Warning,
- match_expr: Optional[Union[str, Pattern[str]]] = None,
- *,
- _ispytest: bool = False,
- ) -> None:
- check_ispytest(_ispytest)
- super().__init__(_ispytest=True)
-
- msg = "exceptions must be derived from Warning, not %s"
- if expected_warning is None:
- warnings.warn(WARNS_NONE_ARG, stacklevel=4)
- expected_warning_tup = None
- elif isinstance(expected_warning, tuple):
- for exc in expected_warning:
- if not issubclass(exc, Warning):
- raise TypeError(msg % type(exc))
- expected_warning_tup = expected_warning
- elif issubclass(expected_warning, Warning):
- expected_warning_tup = (expected_warning,)
- else:
- raise TypeError(msg % type(expected_warning))
-
- self.expected_warning = expected_warning_tup
- self.match_expr = match_expr
-
- def __exit__(
- self,
- exc_type: Optional[Type[BaseException]],
- exc_val: Optional[BaseException],
- exc_tb: Optional[TracebackType],
- ) -> None:
- super().__exit__(exc_type, exc_val, exc_tb)
-
- __tracebackhide__ = True
-
- # only check if we're not currently handling an exception
- if exc_type is None and exc_val is None and exc_tb is None:
- if self.expected_warning is not None:
- if not any(issubclass(r.category, self.expected_warning) for r in self):
- __tracebackhide__ = True
- fail(
- "DID NOT WARN. No warnings of type {} were emitted. "
- "The list of emitted warnings is: {}.".format(
- self.expected_warning, [each.message for each in self]
- )
- )
- elif self.match_expr is not None:
- for r in self:
- if issubclass(r.category, self.expected_warning):
- if re.compile(self.match_expr).search(str(r.message)):
- break
- else:
- fail(
- "DID NOT WARN. No warnings of type {} matching"
- " ('{}') were emitted. The list of emitted warnings"
- " is: {}.".format(
- self.expected_warning,
- self.match_expr,
- [each.message for each in self],
- )
- )