aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pytest/py3/_pytest/assertion/rewrite.py
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2025-05-05 12:31:52 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2025-05-05 12:41:33 +0300
commit6ff49ec58061f642c3a2f83c61eba12820787dfc (patch)
treec733ec9bdb15ed280080d31dea8725bfec717acd /contrib/python/pytest/py3/_pytest/assertion/rewrite.py
parenteefca8305c6a545cc6b16dca3eb0d91dcef2adcd (diff)
downloadydb-6ff49ec58061f642c3a2f83c61eba12820787dfc.tar.gz
Intermediate changes
commit_hash:8b3bb826b17db8329ed1221f545c0645f12c552d
Diffstat (limited to 'contrib/python/pytest/py3/_pytest/assertion/rewrite.py')
-rw-r--r--contrib/python/pytest/py3/_pytest/assertion/rewrite.py120
1 files changed, 48 insertions, 72 deletions
diff --git a/contrib/python/pytest/py3/_pytest/assertion/rewrite.py b/contrib/python/pytest/py3/_pytest/assertion/rewrite.py
index d1974bb3b4a..0ab6eaa1393 100644
--- a/contrib/python/pytest/py3/_pytest/assertion/rewrite.py
+++ b/contrib/python/pytest/py3/_pytest/assertion/rewrite.py
@@ -1,5 +1,7 @@
"""Rewrite assertion AST to produce nice error messages."""
+
import ast
+from collections import defaultdict
import errno
import functools
import importlib.abc
@@ -9,13 +11,12 @@ import io
import itertools
import marshal
import os
+from pathlib import Path
+from pathlib import PurePath
import struct
import sys
import tokenize
import types
-from collections import defaultdict
-from pathlib import Path
-from pathlib import PurePath
from typing import Callable
from typing import Dict
from typing import IO
@@ -33,29 +34,20 @@ from _pytest._io.saferepr import DEFAULT_REPR_MAX_SIZE
from _pytest._io.saferepr import saferepr
from _pytest._version import version
from _pytest.assertion import util
-from _pytest.assertion.util import ( # noqa: F401
- format_explanation as _format_explanation,
-)
from _pytest.config import Config
from _pytest.main import Session
from _pytest.pathlib import absolutepath
from _pytest.pathlib import fnmatch_ex
from _pytest.stash import StashKey
+
+# fmt: off
+from _pytest.assertion.util import format_explanation as _format_explanation # noqa:F401, isort:skip
+# fmt:on
+
if TYPE_CHECKING:
from _pytest.assertion import AssertionState
-if sys.version_info >= (3, 8):
- namedExpr = ast.NamedExpr
- astNameConstant = ast.Constant
- astStr = ast.Constant
- astNum = ast.Constant
-else:
- namedExpr = ast.Expr
- astNameConstant = ast.NameConstant
- astStr = ast.Str
- astNum = ast.Num
-
class Sentinel:
pass
@@ -437,7 +429,10 @@ def _saferepr(obj: object) -> str:
def _get_maxsize_for_saferepr(config: Optional[Config]) -> Optional[int]:
"""Get `maxsize` configuration for saferepr based on the given config object."""
- verbosity = config.getoption("verbose") if config is not None else 0
+ if config is None:
+ verbosity = 0
+ else:
+ verbosity = config.get_verbosity(Config.VERBOSITY_ASSERTIONS)
if verbosity >= 2:
return None
if verbosity >= 1:
@@ -604,13 +599,6 @@ 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.
@@ -706,11 +694,10 @@ class AssertionRewriter(ast.NodeVisitor):
if (
expect_docstring
and isinstance(item, ast.Expr)
- and isinstance(item.value, astStr)
- and isinstance(_get_ast_constant_value(item.value), str)
+ and isinstance(item.value, ast.Constant)
+ and isinstance(item.value.value, str)
):
- doc = _get_ast_constant_value(item.value)
- assert isinstance(doc, str)
+ doc = item.value.value
if self.is_rewrite_disabled(doc):
return
expect_docstring = False
@@ -850,7 +837,7 @@ class AssertionRewriter(ast.NodeVisitor):
current = self.stack.pop()
if self.stack:
self.explanation_specifiers = self.stack[-1]
- keys = [astStr(key) for key in current.keys()]
+ keys = [ast.Constant(key) for key in current.keys()]
format_dict = ast.Dict(keys, list(current.values()))
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
name = "@py_format" + str(next(self.variable_counter))
@@ -874,9 +861,10 @@ class AssertionRewriter(ast.NodeVisitor):
the expression is false.
"""
if isinstance(assert_.test, ast.Tuple) and len(assert_.test.elts) >= 1:
- from _pytest.warning_types import PytestAssertRewriteWarning
import warnings
+ from _pytest.warning_types import PytestAssertRewriteWarning
+
# TODO: This assert should not be needed.
assert self.module_path is not None
warnings.warn_explicit(
@@ -904,16 +892,16 @@ class AssertionRewriter(ast.NodeVisitor):
negation = ast.UnaryOp(ast.Not(), top_condition)
if self.enable_assertion_pass_hook: # Experimental pytest_assertion_pass hook
- msg = self.pop_format_context(astStr(explanation))
+ msg = self.pop_format_context(ast.Constant(explanation))
# Failed
if assert_.msg:
assertmsg = self.helper("_format_assertmsg", assert_.msg)
gluestr = "\n>assert "
else:
- assertmsg = astStr("")
+ assertmsg = ast.Constant("")
gluestr = "assert "
- err_explanation = ast.BinOp(astStr(gluestr), ast.Add(), msg)
+ err_explanation = ast.BinOp(ast.Constant(gluestr), ast.Add(), msg)
err_msg = ast.BinOp(assertmsg, ast.Add(), err_explanation)
err_name = ast.Name("AssertionError", ast.Load())
fmt = self.helper("_format_explanation", err_msg)
@@ -929,8 +917,8 @@ class AssertionRewriter(ast.NodeVisitor):
hook_call_pass = ast.Expr(
self.helper(
"_call_assertion_pass",
- astNum(assert_.lineno),
- astStr(orig),
+ ast.Constant(assert_.lineno),
+ ast.Constant(orig),
fmt_pass,
)
)
@@ -949,7 +937,7 @@ class AssertionRewriter(ast.NodeVisitor):
variables = [
ast.Name(name, ast.Store()) for name in self.format_variables
]
- clear_format = ast.Assign(variables, astNameConstant(None))
+ clear_format = ast.Assign(variables, ast.Constant(None))
self.statements.append(clear_format)
else: # Original assertion rewriting
@@ -960,9 +948,9 @@ class AssertionRewriter(ast.NodeVisitor):
assertmsg = self.helper("_format_assertmsg", assert_.msg)
explanation = "\n>assert " + explanation
else:
- assertmsg = astStr("")
+ assertmsg = ast.Constant("")
explanation = "assert " + explanation
- template = ast.BinOp(assertmsg, ast.Add(), astStr(explanation))
+ template = ast.BinOp(assertmsg, ast.Add(), ast.Constant(explanation))
msg = self.pop_format_context(template)
fmt = self.helper("_format_explanation", msg)
err_name = ast.Name("AssertionError", ast.Load())
@@ -974,7 +962,7 @@ class AssertionRewriter(ast.NodeVisitor):
# Clear temporary variables by setting them to None.
if self.variables:
variables = [ast.Name(name, ast.Store()) for name in self.variables]
- clear = ast.Assign(variables, astNameConstant(None))
+ clear = ast.Assign(variables, ast.Constant(None))
self.statements.append(clear)
# Fix locations (line numbers/column offsets).
for stmt in self.statements:
@@ -982,26 +970,26 @@ class AssertionRewriter(ast.NodeVisitor):
ast.copy_location(node, assert_)
return self.statements
- def visit_NamedExpr(self, name: namedExpr) -> Tuple[namedExpr, str]:
+ def visit_NamedExpr(self, name: ast.NamedExpr) -> Tuple[ast.NamedExpr, str]:
# This method handles the 'walrus operator' repr of the target
# name if it's a local variable or _should_repr_global_name()
# thinks it's acceptable.
locs = ast.Call(self.builtin("locals"), [], [])
target_id = name.target.id # type: ignore[attr-defined]
- inlocs = ast.Compare(astStr(target_id), [ast.In()], [locs])
+ inlocs = ast.Compare(ast.Constant(target_id), [ast.In()], [locs])
dorepr = self.helper("_should_repr_global_name", name)
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
- expr = ast.IfExp(test, self.display(name), astStr(target_id))
+ expr = ast.IfExp(test, self.display(name), ast.Constant(target_id))
return name, self.explanation_param(expr)
def visit_Name(self, name: ast.Name) -> Tuple[ast.Name, str]:
# Display the repr of the name if it's a local variable or
# _should_repr_global_name() thinks it's acceptable.
locs = ast.Call(self.builtin("locals"), [], [])
- inlocs = ast.Compare(astStr(name.id), [ast.In()], [locs])
+ inlocs = ast.Compare(ast.Constant(name.id), [ast.In()], [locs])
dorepr = self.helper("_should_repr_global_name", name)
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
- expr = ast.IfExp(test, self.display(name), astStr(name.id))
+ expr = ast.IfExp(test, self.display(name), ast.Constant(name.id))
return name, self.explanation_param(expr)
def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]:
@@ -1020,10 +1008,10 @@ class AssertionRewriter(ast.NodeVisitor):
# cond is set in a prior loop iteration below
self.expl_stmts.append(ast.If(cond, fail_inner, [])) # noqa
self.expl_stmts = fail_inner
- # Check if the left operand is a namedExpr and the value has already been visited
+ # Check if the left operand is a ast.NamedExpr and the value has already been visited
if (
isinstance(v, ast.Compare)
- and isinstance(v.left, namedExpr)
+ and isinstance(v.left, ast.NamedExpr)
and v.left.target.id
in [
ast_expr.id
@@ -1032,14 +1020,12 @@ class AssertionRewriter(ast.NodeVisitor):
]
):
pytest_temp = self.variable()
- self.variables_overwrite[self.scope][
- v.left.target.id
- ] = v.left # type:ignore[assignment]
+ self.variables_overwrite[self.scope][v.left.target.id] = v.left # type:ignore[assignment]
v.left.target.id = pytest_temp
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
- expl_format = self.pop_format_context(astStr(expl))
+ expl_format = self.pop_format_context(ast.Constant(expl))
call = ast.Call(app, [expl_format], [])
self.expl_stmts.append(ast.Expr(call))
if i < levels:
@@ -1051,7 +1037,7 @@ class AssertionRewriter(ast.NodeVisitor):
self.statements = body = inner
self.statements = save
self.expl_stmts = fail_save
- expl_template = self.helper("_format_boolop", expl_list, astNum(is_or))
+ expl_template = self.helper("_format_boolop", expl_list, ast.Constant(is_or))
expl = self.pop_format_context(expl_template)
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
@@ -1078,9 +1064,7 @@ class AssertionRewriter(ast.NodeVisitor):
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]
+ arg = self.variables_overwrite[self.scope][arg.id] # type:ignore[assignment]
res, expl = self.visit(arg)
arg_expls.append(expl)
new_args.append(res)
@@ -1088,9 +1072,7 @@ class AssertionRewriter(ast.NodeVisitor):
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]
+ keyword.value = self.variables_overwrite[self.scope][keyword.value.id] # type:ignore[assignment]
res, expl = self.visit(keyword.value)
new_kwargs.append(ast.keyword(keyword.arg, res))
if keyword.arg:
@@ -1127,13 +1109,9 @@ class AssertionRewriter(ast.NodeVisitor):
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.scope][
- comp.left.target.id
- ] = comp.left # type:ignore[assignment]
+ comp.left = self.variables_overwrite[self.scope][comp.left.id] # type:ignore[assignment]
+ if isinstance(comp.left, ast.NamedExpr):
+ self.variables_overwrite[self.scope][comp.left.target.id] = comp.left # type:ignore[assignment]
left_res, left_expl = self.visit(comp.left)
if isinstance(comp.left, (ast.Compare, ast.BoolOp)):
left_expl = f"({left_expl})"
@@ -1146,22 +1124,20 @@ class AssertionRewriter(ast.NodeVisitor):
results = [left_res]
for i, op, next_operand in it:
if (
- isinstance(next_operand, namedExpr)
+ isinstance(next_operand, ast.NamedExpr)
and isinstance(left_res, ast.Name)
and next_operand.target.id == left_res.id
):
next_operand.target.id = self.variable()
- self.variables_overwrite[self.scope][
- left_res.id
- ] = next_operand # type:ignore[assignment]
+ self.variables_overwrite[self.scope][left_res.id] = next_operand # type:ignore[assignment]
next_res, next_expl = self.visit(next_operand)
if isinstance(next_operand, (ast.Compare, ast.BoolOp)):
next_expl = f"({next_expl})"
results.append(next_res)
sym = BINOP_MAP[op.__class__]
- syms.append(astStr(sym))
+ syms.append(ast.Constant(sym))
expl = f"{left_expl} {sym} {next_expl}"
- expls.append(astStr(expl))
+ expls.append(ast.Constant(expl))
res_expr = ast.Compare(left_res, [op], [next_res])
self.statements.append(ast.Assign([store_names[i]], res_expr))
left_res, left_expl = next_res, next_expl
@@ -1205,7 +1181,7 @@ def try_makedirs(cache_dir: Path) -> bool:
def get_cache_dir(file_path: Path) -> Path:
"""Return the cache directory to write .pyc files for the given .py file path."""
- if sys.version_info >= (3, 8) and sys.pycache_prefix:
+ if sys.pycache_prefix:
# given:
# prefix = '/tmp/pycs'
# path = '/home/user/proj/test_app.py'