aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest/py3/_pytest/warnings.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/warnings.py
parent6b813c17d56d1d05f92c61ddc347d0e4d358fe85 (diff)
downloadydb-8e1413fed79d1e8036e65228af6c93399ccf5502.tar.gz
intermediate changes
ref:614ed510ddd3cdf86a8c5dbf19afd113397e0172
Diffstat (limited to 'contrib/python/pytest/py3/_pytest/warnings.py')
-rw-r--r--contrib/python/pytest/py3/_pytest/warnings.py140
1 files changed, 55 insertions, 85 deletions
diff --git a/contrib/python/pytest/py3/_pytest/warnings.py b/contrib/python/pytest/py3/_pytest/warnings.py
index 2a4d189d57..35eed96df5 100644
--- a/contrib/python/pytest/py3/_pytest/warnings.py
+++ b/contrib/python/pytest/py3/_pytest/warnings.py
@@ -2,106 +2,88 @@ import sys
import warnings
from contextlib import contextmanager
from typing import Generator
+from typing import Optional
+from typing import TYPE_CHECKING
import pytest
+from _pytest.config import apply_warning_filters
+from _pytest.config import Config
+from _pytest.config import parse_warning_filter
from _pytest.main import Session
+from _pytest.nodes import Item
+from _pytest.terminal import TerminalReporter
+if TYPE_CHECKING:
+ from typing_extensions import Literal
-def _setoption(wmod, arg):
- """
- Copy of the warning._setoption function but does not escape arguments.
- """
- parts = arg.split(":")
- if len(parts) > 5:
- raise wmod._OptionError("too many fields (max 5): {!r}".format(arg))
- while len(parts) < 5:
- parts.append("")
- action, message, category, module, lineno = [s.strip() for s in parts]
- action = wmod._getaction(action)
- category = wmod._getcategory(category)
- if lineno:
- try:
- lineno = int(lineno)
- if lineno < 0:
- raise ValueError
- except (ValueError, OverflowError):
- raise wmod._OptionError("invalid lineno {!r}".format(lineno))
- else:
- lineno = 0
- wmod.filterwarnings(action, message, category, module, lineno)
-
-
-def pytest_addoption(parser):
- group = parser.getgroup("pytest-warnings")
- group.addoption(
- "-W",
- "--pythonwarnings",
- action="append",
- help="set which warnings to report, see -W option of python itself.",
- )
- parser.addini(
- "filterwarnings",
- type="linelist",
- help="Each line specifies a pattern for "
- "warnings.filterwarnings. "
- "Processed after -W/--pythonwarnings.",
- )
-
-def pytest_configure(config):
+def pytest_configure(config: Config) -> None:
config.addinivalue_line(
"markers",
"filterwarnings(warning): add a warning filter to the given test. "
- "see https://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings ",
+ "see https://docs.pytest.org/en/stable/warnings.html#pytest-mark-filterwarnings ",
)
@contextmanager
-def catch_warnings_for_item(config, ihook, when, item):
- """
- Context manager that catches warnings generated in the contained execution block.
+def catch_warnings_for_item(
+ config: Config,
+ ihook,
+ when: "Literal['config', 'collect', 'runtest']",
+ item: Optional[Item],
+) -> Generator[None, None, None]:
+ """Context manager that catches warnings generated in the contained execution block.
``item`` can be None if we are not in the context of an item execution.
- Each warning captured triggers the ``pytest_warning_captured`` hook.
+ Each warning captured triggers the ``pytest_warning_recorded`` hook.
"""
- cmdline_filters = config.getoption("pythonwarnings") or []
- inifilters = config.getini("filterwarnings")
+ config_filters = config.getini("filterwarnings")
+ cmdline_filters = config.known_args_namespace.pythonwarnings or []
with warnings.catch_warnings(record=True) as log:
# mypy can't infer that record=True means log is not None; help it.
assert log is not None
if not sys.warnoptions:
- # if user is not explicitly configuring warning filters, show deprecation warnings by default (#2908)
+ # If user is not explicitly configuring warning filters, show deprecation warnings by default (#2908).
warnings.filterwarnings("always", category=DeprecationWarning)
warnings.filterwarnings("always", category=PendingDeprecationWarning)
- # filters should have this precedence: mark, cmdline options, ini
- # filters should be applied in the inverse order of precedence
- for arg in inifilters:
- _setoption(warnings, arg)
-
- for arg in cmdline_filters:
- warnings._setoption(arg)
+ apply_warning_filters(config_filters, cmdline_filters)
+ # apply filters from "filterwarnings" marks
+ nodeid = "" if item is None else item.nodeid
if item is not None:
for mark in item.iter_markers(name="filterwarnings"):
for arg in mark.args:
- _setoption(warnings, arg)
+ warnings.filterwarnings(*parse_warning_filter(arg, escape=False))
yield
for warning_message in log:
ihook.pytest_warning_captured.call_historic(
- kwargs=dict(warning_message=warning_message, when=when, item=item)
+ kwargs=dict(
+ warning_message=warning_message,
+ when=when,
+ item=item,
+ location=None,
+ )
+ )
+ ihook.pytest_warning_recorded.call_historic(
+ kwargs=dict(
+ warning_message=warning_message,
+ nodeid=nodeid,
+ when=when,
+ location=None,
+ )
)
-def warning_record_to_str(warning_message):
+def warning_record_to_str(warning_message: warnings.WarningMessage) -> str:
"""Convert a warnings.WarningMessage to a string."""
warn_msg = warning_message.message
msg = warnings.formatwarning(
- warn_msg,
+ str(warn_msg),
warning_message.category,
warning_message.filename,
warning_message.lineno,
@@ -111,7 +93,7 @@ def warning_record_to_str(warning_message):
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
-def pytest_runtest_protocol(item):
+def pytest_runtest_protocol(item: Item) -> Generator[None, None, None]:
with catch_warnings_for_item(
config=item.config, ihook=item.ihook, when="runtest", item=item
):
@@ -128,7 +110,9 @@ def pytest_collection(session: Session) -> Generator[None, None, None]:
@pytest.hookimpl(hookwrapper=True)
-def pytest_terminal_summary(terminalreporter):
+def pytest_terminal_summary(
+ terminalreporter: TerminalReporter,
+) -> Generator[None, None, None]:
config = terminalreporter.config
with catch_warnings_for_item(
config=config, ihook=config.hook, when="config", item=None
@@ -137,7 +121,7 @@ def pytest_terminal_summary(terminalreporter):
@pytest.hookimpl(hookwrapper=True)
-def pytest_sessionfinish(session):
+def pytest_sessionfinish(session: Session) -> Generator[None, None, None]:
config = session.config
with catch_warnings_for_item(
config=config, ihook=config.hook, when="config", item=None
@@ -145,25 +129,11 @@ def pytest_sessionfinish(session):
yield
-def _issue_warning_captured(warning, hook, stacklevel):
- """
- This function should be used instead of calling ``warnings.warn`` directly when we are in the "configure" stage:
- at this point the actual options might not have been set, so we manually trigger the pytest_warning_captured
- hook so we can display these warnings in the terminal. This is a hack until we can sort out #2891.
-
- :param warning: the warning instance.
- :param hook: the hook caller
- :param stacklevel: stacklevel forwarded to warnings.warn
- """
- with warnings.catch_warnings(record=True) as records:
- warnings.simplefilter("always", type(warning))
- warnings.warn(warning, stacklevel=stacklevel)
- # Mypy can't infer that record=True means records is not None; help it.
- assert records is not None
- frame = sys._getframe(stacklevel - 1)
- location = frame.f_code.co_filename, frame.f_lineno, frame.f_code.co_name
- hook.pytest_warning_captured.call_historic(
- kwargs=dict(
- warning_message=records[0], when="config", item=None, location=location
- )
- )
+@pytest.hookimpl(hookwrapper=True)
+def pytest_load_initial_conftests(
+ early_config: "Config",
+) -> Generator[None, None, None]:
+ with catch_warnings_for_item(
+ config=early_config, ihook=early_config.hook, when="config", item=None
+ ):
+ yield