Skip to content

Commit 9335a0b

Browse files
committed
Avoid ast deprecation warnings on Python 3.12
Fix #10977.
1 parent 0ded329 commit 9335a0b

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

src/_pytest/assertion/rewrite.py

Lines changed: 29 additions & 20 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,9 +686,12 @@ 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
):
685-
doc = item.value.s
691+
if sys.version_info >= (3, 8):
692+
doc = item.value.value
693+
else:
694+
doc = item.value.s
686695
if self.is_rewrite_disabled(doc):
687696
return
688697
expect_docstring = False
@@ -814,7 +823,7 @@ def pop_format_context(self, expl_expr: ast.expr) -> ast.Name:
814823
current = self.stack.pop()
815824
if self.stack:
816825
self.explanation_specifiers = self.stack[-1]
817-
keys = [ast.Str(key) for key in current.keys()]
826+
keys = [astStr(key) for key in current.keys()]
818827
format_dict = ast.Dict(keys, list(current.values()))
819828
form = ast.BinOp(expl_expr, ast.Mod(), format_dict)
820829
name = "@py_format" + str(next(self.variable_counter))
@@ -868,16 +877,16 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
868877
negation = ast.UnaryOp(ast.Not(), top_condition)
869878

870879
if self.enable_assertion_pass_hook: # Experimental pytest_assertion_pass hook
871-
msg = self.pop_format_context(ast.Str(explanation))
880+
msg = self.pop_format_context(astStr(explanation))
872881

873882
# Failed
874883
if assert_.msg:
875884
assertmsg = self.helper("_format_assertmsg", assert_.msg)
876885
gluestr = "\n>assert "
877886
else:
878-
assertmsg = ast.Str("")
887+
assertmsg = astStr("")
879888
gluestr = "assert "
880-
err_explanation = ast.BinOp(ast.Str(gluestr), ast.Add(), msg)
889+
err_explanation = ast.BinOp(astStr(gluestr), ast.Add(), msg)
881890
err_msg = ast.BinOp(assertmsg, ast.Add(), err_explanation)
882891
err_name = ast.Name("AssertionError", ast.Load())
883892
fmt = self.helper("_format_explanation", err_msg)
@@ -893,8 +902,8 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
893902
hook_call_pass = ast.Expr(
894903
self.helper(
895904
"_call_assertion_pass",
896-
ast.Num(assert_.lineno),
897-
ast.Str(orig),
905+
astNum(assert_.lineno),
906+
astStr(orig),
898907
fmt_pass,
899908
)
900909
)
@@ -913,7 +922,7 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
913922
variables = [
914923
ast.Name(name, ast.Store()) for name in self.format_variables
915924
]
916-
clear_format = ast.Assign(variables, ast.NameConstant(None))
925+
clear_format = ast.Assign(variables, astNameConstant(None))
917926
self.statements.append(clear_format)
918927

919928
else: # Original assertion rewriting
@@ -924,9 +933,9 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
924933
assertmsg = self.helper("_format_assertmsg", assert_.msg)
925934
explanation = "\n>assert " + explanation
926935
else:
927-
assertmsg = ast.Str("")
936+
assertmsg = astStr("")
928937
explanation = "assert " + explanation
929-
template = ast.BinOp(assertmsg, ast.Add(), ast.Str(explanation))
938+
template = ast.BinOp(assertmsg, ast.Add(), astStr(explanation))
930939
msg = self.pop_format_context(template)
931940
fmt = self.helper("_format_explanation", msg)
932941
err_name = ast.Name("AssertionError", ast.Load())
@@ -938,7 +947,7 @@ def visit_Assert(self, assert_: ast.Assert) -> List[ast.stmt]:
938947
# Clear temporary variables by setting them to None.
939948
if self.variables:
940949
variables = [ast.Name(name, ast.Store()) for name in self.variables]
941-
clear = ast.Assign(variables, ast.NameConstant(None))
950+
clear = ast.Assign(variables, astNameConstant(None))
942951
self.statements.append(clear)
943952
# Fix locations (line numbers/column offsets).
944953
for stmt in self.statements:
@@ -952,20 +961,20 @@ def visit_NamedExpr(self, name: namedExpr) -> Tuple[namedExpr, str]:
952961
# thinks it's acceptable.
953962
locs = ast.Call(self.builtin("locals"), [], [])
954963
target_id = name.target.id # type: ignore[attr-defined]
955-
inlocs = ast.Compare(ast.Str(target_id), [ast.In()], [locs])
964+
inlocs = ast.Compare(astStr(target_id), [ast.In()], [locs])
956965
dorepr = self.helper("_should_repr_global_name", name)
957966
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
958-
expr = ast.IfExp(test, self.display(name), ast.Str(target_id))
967+
expr = ast.IfExp(test, self.display(name), astStr(target_id))
959968
return name, self.explanation_param(expr)
960969

961970
def visit_Name(self, name: ast.Name) -> Tuple[ast.Name, str]:
962971
# Display the repr of the name if it's a local variable or
963972
# _should_repr_global_name() thinks it's acceptable.
964973
locs = ast.Call(self.builtin("locals"), [], [])
965-
inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
974+
inlocs = ast.Compare(astStr(name.id), [ast.In()], [locs])
966975
dorepr = self.helper("_should_repr_global_name", name)
967976
test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
968-
expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
977+
expr = ast.IfExp(test, self.display(name), astStr(name.id))
969978
return name, self.explanation_param(expr)
970979

971980
def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]:
@@ -1003,7 +1012,7 @@ def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]:
10031012
self.push_format_context()
10041013
res, expl = self.visit(v)
10051014
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
1006-
expl_format = self.pop_format_context(ast.Str(expl))
1015+
expl_format = self.pop_format_context(astStr(expl))
10071016
call = ast.Call(app, [expl_format], [])
10081017
self.expl_stmts.append(ast.Expr(call))
10091018
if i < levels:
@@ -1015,7 +1024,7 @@ def visit_BoolOp(self, boolop: ast.BoolOp) -> Tuple[ast.Name, str]:
10151024
self.statements = body = inner
10161025
self.statements = save
10171026
self.expl_stmts = fail_save
1018-
expl_template = self.helper("_format_boolop", expl_list, ast.Num(is_or))
1027+
expl_template = self.helper("_format_boolop", expl_list, astNum(is_or))
10191028
expl = self.pop_format_context(expl_template)
10201029
return ast.Name(res_var, ast.Load()), self.explanation_param(expl)
10211030

@@ -1118,9 +1127,9 @@ def visit_Compare(self, comp: ast.Compare) -> Tuple[ast.expr, str]:
11181127
next_expl = f"({next_expl})"
11191128
results.append(next_res)
11201129
sym = BINOP_MAP[op.__class__]
1121-
syms.append(ast.Str(sym))
1130+
syms.append(astStr(sym))
11221131
expl = f"{left_expl} {sym} {next_expl}"
1123-
expls.append(ast.Str(expl))
1132+
expls.append(astStr(expl))
11241133
res_expr = ast.Compare(left_res, [op], [next_res])
11251134
self.statements.append(ast.Assign([store_names[i]], res_expr))
11261135
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)