Skip to content

Commit bdb453d

Browse files
committed
Avoid ast deprecation warnings on Python 3.12
Fix #10977.
1 parent 9e491f4 commit bdb453d

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

src/_pytest/assertion/rewrite.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,14 @@
4646

4747
if sys.version_info >= (3, 8):
4848
namedExpr = ast.NamedExpr
49+
astNameConstant = ast.Constant
50+
astStr = ast.Constant
51+
astNum = ast.Constant
4952
else:
5053
namedExpr = ast.Expr
54+
astNameConstant = ast.NameConstant
55+
astStr = ast.Str
56+
astNum = ast.Num
5157

5258

5359
assertstate_key = StashKey["AssertionState"]()
@@ -680,7 +686,7 @@ def run(self, mod: ast.Module) -> None:
680686
if (
681687
expect_docstring
682688
and isinstance(item, ast.Expr)
683-
and isinstance(item.value, ast.Str)
689+
and isinstance(item.value, astStr)
684690
):
685691
doc = item.value.s
686692
if self.is_rewrite_disabled(doc):
@@ -814,7 +820,7 @@ def pop_format_context(self, expl_expr: ast.expr) -> ast.Name:
814820
current = self.stack.pop()
815821
if self.stack:
816822
self.explanation_specifiers = self.stack[-1]
817-
keys = [ast.Str(key) for key in current.keys()]
823+
keys = [astStr(key) for key in current.keys()]
818824
format_dict = ast.Dict(keys, list(current.values()))
819825
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
820826
name = "@py_format" + str(next(self.variable_counter))
@@ -868,16 +874,16 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
868874
negation = ast.UnaryOp(ast.Not(), top_condition)
869875

870876
if self.enable_assertion_pass_hook: # Experimental pytest_assertion_pass hook
871-
msg = self.pop_format_context(ast.Str(explanation))
877+
msg = self.pop_format_context(astStr(explanation))
872878

873879
# Failed
874880
if assert_.msg:
875881
assertmsg = self.helper("_format_assertmsg", assert_.msg)
876882
gluestr = "\n>assert "
877883
else:
878-
assertmsg = ast.Str("")
884+
assertmsg = astStr("")
879885
gluestr = "assert "
880-
err_explanation = ast.BinOp(ast.Str(gluestr), ast.Add(), msg)
886+
err_explanation = ast.BinOp(astStr(gluestr), ast.Add(), msg)
881887
err_msg = ast.BinOp(assertmsg, ast.Add(), err_explanation)
882888
err_name = ast.Name("AssertionError", ast.Load())
883889
fmt = self.helper("_format_explanation", err_msg)
@@ -893,8 +899,8 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
893899
hook_call_pass = ast.Expr(
894900
self.helper(
895901
"_call_assertion_pass",
896-
ast.Num(assert_.lineno),
897-
ast.Str(orig),
902+
astNum(assert_.lineno),
903+
astStr(orig),
898904
fmt_pass,
899905
)
900906
)
@@ -913,7 +919,7 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
913919
variables = [
914920
ast.Name(name, ast.Store()) for name in self.format_variables
915921
]
916-
clear_format = ast.Assign(variables, ast.NameConstant(None))
922+
clear_format = ast.Assign(variables, astNameConstant(None))
917923
self.statements.append(clear_format)
918924

919925
else: # Original assertion rewriting
@@ -924,9 +930,9 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
924930
assertmsg = self.helper("_format_assertmsg", assert_.msg)
925931
explanation = "\n>assert " + explanation
926932
else:
927-
assertmsg = ast.Str("")
933+
assertmsg = astStr("")
928934
explanation = "assert " + explanation
929-
template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation))
935+
template = ast.BinOp(assertmsg, ast.Add(), astStr(explanation))
930936
msg = self.pop_format_context(template)
931937
fmt = self.helper("_format_explanation", msg)
932938
err_name = ast.Name("AssertionError", ast.Load())
@@ -938,7 +944,7 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
938944
# Clear temporary variables by setting them to None.
939945
if self.variables:
940946
variables = [ast.Name(name, ast.Store()) for name in self.variables]
941-
clear = ast.Assign(variables, ast.NameConstant(None))
947+
clear = ast.Assign(variables, astNameConstant(None))
942948
self.statements.append(clear)
943949
# Fix locations (line numbers/column offsets).
944950
for stmt in self.statements:
@@ -952,20 +958,20 @@ def visit_NamedExpr(self, name: namedExpr) -> Tuple[namedExpr, str]:
952958
# thinks it's acceptable.
953959
locs = ast.Call(self.builtin("locals"), [], [])
954960
target_id = name.target.id # type: ignore[attr-defined]
955-
inlocs = ast.Compare(ast.Str(target_id), [ast.In()], [locs])
961+
inlocs = ast.Compare(astStr(target_id), [ast.In()], [locs])
956962
dorepr = self.helper("_should_repr_global_name", name)
957963
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
958-
expr = ast.IfExp(test, self.display(name), ast.Str(target_id))
964+
expr = ast.IfExp(test, self.display(name), astStr(target_id))
959965
return name, self.explanation_param(expr)
960966

961967
def visit_Name(self, name: ast.Name) -> Tuple[ast.Name, str]:
962968
# Display the repr of the name if it's a local variable or
963969
# _should_repr_global_name() thinks it's acceptable.
964970
locs = ast.Call(self.builtin("locals"), [], [])
965-
inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
971+
inlocs = ast.Compare(astStr(name.id), [ast.In()], [locs])
966972
dorepr = self.helper("_should_repr_global_name", name)
967973
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
968-
expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
974+
expr = ast.IfExp(test, self.display(name), astStr(name.id))
969975
return name, self.explanation_param(expr)
970976

971977
def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]:
@@ -1001,7 +1007,7 @@ def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]:
10011007
self.push_format_context()
10021008
res, expl = self.visit(v)
10031009
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
1004-
expl_format = self.pop_format_context(ast.Str(expl))
1010+
expl_format = self.pop_format_context(astStr(expl))
10051011
call = ast.Call(app, [expl_format], [])
10061012
self.expl_stmts.append(ast.Expr(call))
10071013
if i < levels:
@@ -1013,7 +1019,7 @@ def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]:
10131019
self.statements = body = inner
10141020
self.statements = save
10151021
self.expl_stmts = fail_save
1016-
expl_template = self.helper("_format_boolop", expl_list, ast.Num(is_or))
1022+
expl_template = self.helper("_format_boolop", expl_list, astNum(is_or))
10171023
expl = self.pop_format_context(expl_template)
10181024
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
10191025

@@ -1099,9 +1105,9 @@ def visit_Compare(self, comp: ast.Compare) -> Tuple[ast.expr, str]:
10991105
next_expl = f"({next_expl})"
11001106
results.append(next_res)
11011107
sym = BINOP_MAP[op.__class__]
1102-
syms.append(ast.Str(sym))
1108+
syms.append(astStr(sym))
11031109
expl = f"{left_expl} {sym} {next_expl}"
1104-
expls.append(ast.Str(expl))
1110+
expls.append(astStr(expl))
11051111
res_expr = ast.Compare(left_res, [op], [next_res])
11061112
self.statements.append(ast.Assign([store_names[i]], res_expr))
11071113
left_res, left_expl = next_res, next_expl

src/_pytest/mark/expression.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import dataclasses
1919
import enum
2020
import re
21+
import sys
2122
import types
2223
from typing import Callable
2324
from typing import Iterator
@@ -26,6 +27,11 @@
2627
from typing import Optional
2728
from typing import Sequence
2829

30+
if sys.version_info >= (3, 8):
31+
astNameConstant = ast.Constant
32+
else:
33+
astNameConstant = ast.NameConstant
34+
2935

3036
__all__ = [
3137
"Expression",
@@ -132,7 +138,7 @@ def reject(self, expected: Sequence[TokenType]) -> NoReturn:
132138

133139
def expression(s: Scanner) -> ast.Expression:
134140
if s.accept(TokenType.EOF):
135-
ret: ast.expr = ast.NameConstant(False)
141+
ret: ast.expr = astNameConstant(False)
136142
else:
137143
ret = expr(s)
138144
s.accept(TokenType.EOF, reject=True)

0 commit comments

Comments
 (0)