aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest
diff options
context:
space:
mode:
authorAlexSm <alex@ydb.tech>2024-01-09 18:56:40 +0100
committerGitHub <noreply@github.com>2024-01-09 18:56:40 +0100
commite95f266d2a3e48e62015220588a4fd73d5d5a5cb (patch)
treea8a784b6931fe52ad5f511cfef85af14e5f63991 /contrib/python/pytest
parent50a65e3b48a82d5b51f272664da389f2e0b0c99a (diff)
downloadydb-e95f266d2a3e48e62015220588a4fd73d5d5a5cb.tar.gz
Library import 6 (#888)
Diffstat (limited to 'contrib/python/pytest')
-rw-r--r--contrib/python/pytest/py3/.dist-info/METADATA2
-rw-r--r--contrib/python/pytest/py3/AUTHORS5
-rw-r--r--contrib/python/pytest/py3/_pytest/_version.py16
-rw-r--r--contrib/python/pytest/py3/_pytest/assertion/rewrite.py68
-rw-r--r--contrib/python/pytest/py3/_pytest/assertion/util.py2
-rw-r--r--contrib/python/pytest/py3/_pytest/compat.py25
-rw-r--r--contrib/python/pytest/py3/_pytest/faulthandler.py23
-rw-r--r--contrib/python/pytest/py3/_pytest/junitxml.py2
-rw-r--r--contrib/python/pytest/py3/_pytest/mark/structures.py4
-rw-r--r--contrib/python/pytest/py3/_pytest/nodes.py2
-rw-r--r--contrib/python/pytest/py3/_pytest/outcomes.py2
-rw-r--r--contrib/python/pytest/py3/_pytest/pathlib.py5
-rw-r--r--contrib/python/pytest/py3/_pytest/pytester.py2
-rw-r--r--contrib/python/pytest/py3/ya.make2
14 files changed, 114 insertions, 46 deletions
diff --git a/contrib/python/pytest/py3/.dist-info/METADATA b/contrib/python/pytest/py3/.dist-info/METADATA
index 8e45f6d805..20b02c2453 100644
--- a/contrib/python/pytest/py3/.dist-info/METADATA
+++ b/contrib/python/pytest/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pytest
-Version: 7.4.2
+Version: 7.4.4
Summary: pytest: simple powerful testing with Python
Home-page: https://docs.pytest.org/en/latest/
Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others
diff --git a/contrib/python/pytest/py3/AUTHORS b/contrib/python/pytest/py3/AUTHORS
index e8456d92b3..950672930f 100644
--- a/contrib/python/pytest/py3/AUTHORS
+++ b/contrib/python/pytest/py3/AUTHORS
@@ -47,6 +47,7 @@ Ariel Pillemer
Armin Rigo
Aron Coyle
Aron Curzon
+Arthur Richard
Ashish Kurmi
Aviral Verma
Aviv Palivoda
@@ -231,6 +232,7 @@ Maho
Maik Figura
Mandeep Bhutani
Manuel Krebber
+Marc Mueller
Marc Schlaich
Marcelo Duarte Trevisani
Marcin Bachry
@@ -322,6 +324,7 @@ Ronny Pfannschmidt
Ross Lawley
Ruaridh Williamson
Russel Winder
+Ryan Puddephatt
Ryan Wooden
Saiprasad Kale
Samuel Colvin
@@ -336,6 +339,7 @@ Serhii Mozghovyi
Seth Junot
Shantanu Jain
Shubham Adep
+Simon Blanchard
Simon Gomizelj
Simon Holesch
Simon Kerr
@@ -373,6 +377,7 @@ Tomer Keren
Tony Narlock
Tor Colvin
Trevor Bekolay
+Tushar Sadhwani
Tyler Goodlet
Tyler Smart
Tzu-ping Chung
diff --git a/contrib/python/pytest/py3/_pytest/_version.py b/contrib/python/pytest/py3/_pytest/_version.py
index a7f556f8a6..458d065928 100644
--- a/contrib/python/pytest/py3/_pytest/_version.py
+++ b/contrib/python/pytest/py3/_pytest/_version.py
@@ -1,4 +1,16 @@
# file generated by setuptools_scm
# don't change, don't track in version control
-__version__ = version = '7.4.2'
-__version_tuple__ = version_tuple = (7, 4, 2)
+TYPE_CHECKING = False
+if TYPE_CHECKING:
+ from typing import Tuple, Union
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
+else:
+ VERSION_TUPLE = object
+
+version: str
+__version__: str
+__version_tuple__: VERSION_TUPLE
+version_tuple: VERSION_TUPLE
+
+__version__ = version = '7.4.4'
+__version_tuple__ = version_tuple = (7, 4, 4)
diff --git a/contrib/python/pytest/py3/_pytest/assertion/rewrite.py b/contrib/python/pytest/py3/_pytest/assertion/rewrite.py
index ab83fee32b..d1974bb3b4 100644
--- a/contrib/python/pytest/py3/_pytest/assertion/rewrite.py
+++ b/contrib/python/pytest/py3/_pytest/assertion/rewrite.py
@@ -13,6 +13,7 @@ import struct
import sys
import tokenize
import types
+from collections import defaultdict
from pathlib import Path
from pathlib import PurePath
from typing import Callable
@@ -56,6 +57,10 @@ else:
astNum = ast.Num
+class Sentinel:
+ pass
+
+
assertstate_key = StashKey["AssertionState"]()
# pytest caches rewritten pycs in pycache dirs
@@ -63,6 +68,9 @@ PYTEST_TAG = f"{sys.implementation.cache_tag}-pytest-{version}"
PYC_EXT = ".py" + (__debug__ and "c" or "o")
PYC_TAIL = "." + PYTEST_TAG + PYC_EXT
+# Special marker that denotes we have just left a scope definition
+_SCOPE_END_MARKER = Sentinel()
+
class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader):
"""PEP302/PEP451 import hook which rewrites asserts."""
@@ -596,6 +604,13 @@ def _get_assertion_exprs(src: bytes) -> Dict[int, str]:
return ret
+def _get_ast_constant_value(value: astStr) -> object:
+ if sys.version_info >= (3, 8):
+ return value.value
+ else:
+ return value.s
+
+
class AssertionRewriter(ast.NodeVisitor):
"""Assertion rewriting implementation.
@@ -645,6 +660,8 @@ class AssertionRewriter(ast.NodeVisitor):
.push_format_context() and .pop_format_context() which allows
to build another %-formatted string while already building one.
+ :scope: A tuple containing the current scope used for variables_overwrite.
+
:variables_overwrite: A dict filled with references to variables
that change value within an assert. This happens when a variable is
reassigned with the walrus operator
@@ -666,7 +683,10 @@ class AssertionRewriter(ast.NodeVisitor):
else:
self.enable_assertion_pass_hook = False
self.source = source
- self.variables_overwrite: Dict[str, str] = {}
+ self.scope: tuple[ast.AST, ...] = ()
+ self.variables_overwrite: defaultdict[
+ tuple[ast.AST, ...], Dict[str, str]
+ ] = defaultdict(dict)
def run(self, mod: ast.Module) -> None:
"""Find all assert statements in *mod* and rewrite them."""
@@ -687,11 +707,10 @@ class AssertionRewriter(ast.NodeVisitor):
expect_docstring
and isinstance(item, ast.Expr)
and isinstance(item.value, astStr)
+ and isinstance(_get_ast_constant_value(item.value), str)
):
- if sys.version_info >= (3, 8):
- doc = item.value.value
- else:
- doc = item.value.s
+ doc = _get_ast_constant_value(item.value)
+ assert isinstance(doc, str)
if self.is_rewrite_disabled(doc):
return
expect_docstring = False
@@ -732,9 +751,17 @@ class AssertionRewriter(ast.NodeVisitor):
mod.body[pos:pos] = imports
# Collect asserts.
- nodes: List[ast.AST] = [mod]
+ self.scope = (mod,)
+ nodes: List[Union[ast.AST, Sentinel]] = [mod]
while nodes:
node = nodes.pop()
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
+ self.scope = tuple((*self.scope, node))
+ nodes.append(_SCOPE_END_MARKER)
+ if node == _SCOPE_END_MARKER:
+ self.scope = self.scope[:-1]
+ continue
+ assert isinstance(node, ast.AST)
for name, field in ast.iter_fields(node):
if isinstance(field, list):
new: List[ast.AST] = []
@@ -1005,7 +1032,7 @@ class AssertionRewriter(ast.NodeVisitor):
]
):
pytest_temp = self.variable()
- self.variables_overwrite[
+ self.variables_overwrite[self.scope][
v.left.target.id
] = v.left # type:ignore[assignment]
v.left.target.id = pytest_temp
@@ -1048,17 +1075,20 @@ class AssertionRewriter(ast.NodeVisitor):
new_args = []
new_kwargs = []
for arg in call.args:
- if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite:
- arg = self.variables_overwrite[arg.id] # type:ignore[assignment]
+ if isinstance(arg, ast.Name) and arg.id in self.variables_overwrite.get(
+ self.scope, {}
+ ):
+ arg = self.variables_overwrite[self.scope][
+ arg.id
+ ] # type:ignore[assignment]
res, expl = self.visit(arg)
arg_expls.append(expl)
new_args.append(res)
for keyword in call.keywords:
- if (
- isinstance(keyword.value, ast.Name)
- and keyword.value.id in self.variables_overwrite
- ):
- keyword.value = self.variables_overwrite[
+ if isinstance(
+ keyword.value, ast.Name
+ ) and keyword.value.id in self.variables_overwrite.get(self.scope, {}):
+ keyword.value = self.variables_overwrite[self.scope][
keyword.value.id
] # type:ignore[assignment]
res, expl = self.visit(keyword.value)
@@ -1094,12 +1124,14 @@ class AssertionRewriter(ast.NodeVisitor):
def visit_Compare(self, comp: ast.Compare) -> Tuple[ast.expr, str]:
self.push_format_context()
# We first check if we have overwritten a variable in the previous assert
- if isinstance(comp.left, ast.Name) and comp.left.id in self.variables_overwrite:
- comp.left = self.variables_overwrite[
+ if isinstance(
+ comp.left, ast.Name
+ ) and comp.left.id in self.variables_overwrite.get(self.scope, {}):
+ comp.left = self.variables_overwrite[self.scope][
comp.left.id
] # type:ignore[assignment]
if isinstance(comp.left, namedExpr):
- self.variables_overwrite[
+ self.variables_overwrite[self.scope][
comp.left.target.id
] = comp.left # type:ignore[assignment]
left_res, left_expl = self.visit(comp.left)
@@ -1119,7 +1151,7 @@ class AssertionRewriter(ast.NodeVisitor):
and next_operand.target.id == left_res.id
):
next_operand.target.id = self.variable()
- self.variables_overwrite[
+ self.variables_overwrite[self.scope][
left_res.id
] = next_operand # type:ignore[assignment]
next_res, next_expl = self.visit(next_operand)
diff --git a/contrib/python/pytest/py3/_pytest/assertion/util.py b/contrib/python/pytest/py3/_pytest/assertion/util.py
index fc5dfdbd5b..39ca5403e0 100644
--- a/contrib/python/pytest/py3/_pytest/assertion/util.py
+++ b/contrib/python/pytest/py3/_pytest/assertion/util.py
@@ -132,7 +132,7 @@ def isiterable(obj: Any) -> bool:
try:
iter(obj)
return not istext(obj)
- except TypeError:
+ except Exception:
return False
diff --git a/contrib/python/pytest/py3/_pytest/compat.py b/contrib/python/pytest/py3/_pytest/compat.py
index a1f9d37722..6fdb5a1d8e 100644
--- a/contrib/python/pytest/py3/_pytest/compat.py
+++ b/contrib/python/pytest/py3/_pytest/compat.py
@@ -380,15 +380,24 @@ else:
def get_user_id() -> int | None:
- """Return the current user id, or None if we cannot get it reliably on the current platform."""
- # win32 does not have a getuid() function.
- # On Emscripten, getuid() is a stub that always returns 0.
- if sys.platform in ("win32", "emscripten"):
+ """Return the current process's real user id or None if it could not be
+ determined.
+
+ :return: The user id or None if it could not be determined.
+ """
+ # mypy follows the version and platform checking expectation of PEP 484:
+ # https://mypy.readthedocs.io/en/stable/common_issues.html?highlight=platform#python-version-and-system-platform-checks
+ # Containment checks are too complex for mypy v1.5.0 and cause failure.
+ if sys.platform == "win32" or sys.platform == "emscripten":
+ # win32 does not have a getuid() function.
+ # Emscripten has a return 0 stub.
return None
- # getuid shouldn't fail, but cpython defines such a case.
- # Let's hope for the best.
- uid = os.getuid()
- return uid if uid != -1 else None
+ else:
+ # On other platforms, a return value of -1 is assumed to indicate that
+ # the current process's real user id could not be determined.
+ ERROR = -1
+ uid = os.getuid()
+ return uid if uid != ERROR else None
# Perform exhaustiveness checking.
diff --git a/contrib/python/pytest/py3/_pytest/faulthandler.py b/contrib/python/pytest/py3/_pytest/faulthandler.py
index af879aa44c..d8c7e9fd3b 100644
--- a/contrib/python/pytest/py3/_pytest/faulthandler.py
+++ b/contrib/python/pytest/py3/_pytest/faulthandler.py
@@ -1,4 +1,3 @@
-import io
import os
import sys
from typing import Generator
@@ -10,8 +9,8 @@ from _pytest.nodes import Item
from _pytest.stash import StashKey
+fault_handler_original_stderr_fd_key = StashKey[int]()
fault_handler_stderr_fd_key = StashKey[int]()
-fault_handler_originally_enabled_key = StashKey[bool]()
def pytest_addoption(parser: Parser) -> None:
@@ -25,8 +24,15 @@ def pytest_addoption(parser: Parser) -> None:
def pytest_configure(config: Config) -> None:
import faulthandler
- config.stash[fault_handler_stderr_fd_key] = os.dup(get_stderr_fileno())
- config.stash[fault_handler_originally_enabled_key] = faulthandler.is_enabled()
+ # at teardown we want to restore the original faulthandler fileno
+ # but faulthandler has no api to return the original fileno
+ # so here we stash the stderr fileno to be used at teardown
+ # sys.stderr and sys.__stderr__ may be closed or patched during the session
+ # so we can't rely on their values being good at that point (#11572).
+ stderr_fileno = get_stderr_fileno()
+ if faulthandler.is_enabled():
+ config.stash[fault_handler_original_stderr_fd_key] = stderr_fileno
+ config.stash[fault_handler_stderr_fd_key] = os.dup(stderr_fileno)
faulthandler.enable(file=config.stash[fault_handler_stderr_fd_key])
@@ -38,9 +44,10 @@ def pytest_unconfigure(config: Config) -> None:
if fault_handler_stderr_fd_key in config.stash:
os.close(config.stash[fault_handler_stderr_fd_key])
del config.stash[fault_handler_stderr_fd_key]
- if config.stash.get(fault_handler_originally_enabled_key, False):
- # Re-enable the faulthandler if it was originally enabled.
- faulthandler.enable(file=get_stderr_fileno())
+ # Re-enable the faulthandler if it was originally enabled.
+ if fault_handler_original_stderr_fd_key in config.stash:
+ faulthandler.enable(config.stash[fault_handler_original_stderr_fd_key])
+ del config.stash[fault_handler_original_stderr_fd_key]
def get_stderr_fileno() -> int:
@@ -51,7 +58,7 @@ def get_stderr_fileno() -> int:
if fileno == -1:
raise AttributeError()
return fileno
- except (AttributeError, io.UnsupportedOperation):
+ except (AttributeError, ValueError):
# pytest-xdist monkeypatches sys.stderr with an object that is not an actual file.
# https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors
# This is potentially dangerous, but the best we can do.
diff --git a/contrib/python/pytest/py3/_pytest/junitxml.py b/contrib/python/pytest/py3/_pytest/junitxml.py
index ed259e4c41..9ee35b84e8 100644
--- a/contrib/python/pytest/py3/_pytest/junitxml.py
+++ b/contrib/python/pytest/py3/_pytest/junitxml.py
@@ -369,7 +369,7 @@ def record_testsuite_property(request: FixtureRequest) -> Callable[[str, object]
__tracebackhide__ = True
def record_func(name: str, value: object) -> None:
- """No-op function in case --junitxml was not passed in the command-line."""
+ """No-op function in case --junit-xml was not passed in the command-line."""
__tracebackhide__ = True
_check_record_param_type("name", name)
diff --git a/contrib/python/pytest/py3/_pytest/mark/structures.py b/contrib/python/pytest/py3/_pytest/mark/structures.py
index 42fb294c6d..32bdc7e38b 100644
--- a/contrib/python/pytest/py3/_pytest/mark/structures.py
+++ b/contrib/python/pytest/py3/_pytest/mark/structures.py
@@ -373,7 +373,9 @@ def get_unpacked_marks(
if not consider_mro:
mark_lists = [obj.__dict__.get("pytestmark", [])]
else:
- mark_lists = [x.__dict__.get("pytestmark", []) for x in obj.__mro__]
+ mark_lists = [
+ x.__dict__.get("pytestmark", []) for x in reversed(obj.__mro__)
+ ]
mark_list = []
for item in mark_lists:
if isinstance(item, list):
diff --git a/contrib/python/pytest/py3/_pytest/nodes.py b/contrib/python/pytest/py3/_pytest/nodes.py
index 667a02b77a..a5313cb765 100644
--- a/contrib/python/pytest/py3/_pytest/nodes.py
+++ b/contrib/python/pytest/py3/_pytest/nodes.py
@@ -567,7 +567,7 @@ class Collector(Node):
ntraceback = traceback.cut(path=self.path)
if ntraceback == traceback:
ntraceback = ntraceback.cut(excludepath=tracebackcutdir)
- return excinfo.traceback.filter(excinfo)
+ return ntraceback.filter(excinfo)
return excinfo.traceback
diff --git a/contrib/python/pytest/py3/_pytest/outcomes.py b/contrib/python/pytest/py3/_pytest/outcomes.py
index 1be97dda4e..53c3e1511c 100644
--- a/contrib/python/pytest/py3/_pytest/outcomes.py
+++ b/contrib/python/pytest/py3/_pytest/outcomes.py
@@ -123,7 +123,7 @@ def exit(
only because `msg` is deprecated.
:param returncode:
- Return code to be used when exiting pytest.
+ 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.
diff --git a/contrib/python/pytest/py3/_pytest/pathlib.py b/contrib/python/pytest/py3/_pytest/pathlib.py
index 5c765c6834..c2f8535f5f 100644
--- a/contrib/python/pytest/py3/_pytest/pathlib.py
+++ b/contrib/python/pytest/py3/_pytest/pathlib.py
@@ -623,8 +623,9 @@ def module_name_from_path(path: Path, root: Path) -> str:
# Use the parts for the relative path to the root path.
path_parts = relative_path.parts
- # Module name for packages do not contain the __init__ file.
- if path_parts[-1] == "__init__":
+ # Module name for packages do not contain the __init__ file, unless
+ # the `__init__.py` file is at the root.
+ if len(path_parts) >= 2 and path_parts[-1] == "__init__":
path_parts = path_parts[:-1]
return ".".join(path_parts)
diff --git a/contrib/python/pytest/py3/_pytest/pytester.py b/contrib/python/pytest/py3/_pytest/pytester.py
index cdfc2c04ae..0771065e06 100644
--- a/contrib/python/pytest/py3/_pytest/pytester.py
+++ b/contrib/python/pytest/py3/_pytest/pytester.py
@@ -1074,7 +1074,7 @@ class Pytester:
return self.inline_run(*values)
def inline_genitems(self, *args) -> Tuple[List[Item], HookRecorder]:
- """Run ``pytest.main(['--collectonly'])`` in-process.
+ """Run ``pytest.main(['--collect-only'])`` in-process.
Runs the :py:func:`pytest.main` function to run all of pytest inside
the test process itself like :py:meth:`inline_run`, but returns a
diff --git a/contrib/python/pytest/py3/ya.make b/contrib/python/pytest/py3/ya.make
index 8bef9919d6..a1ab790ee2 100644
--- a/contrib/python/pytest/py3/ya.make
+++ b/contrib/python/pytest/py3/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(7.4.2)
+VERSION(7.4.4)
LICENSE(MIT)