Skip to content

Commit d925fff

Browse files
committed
add test to cover bad name case. Add assertions in validation functions to catch this as soon as it occurs
1 parent 72577b1 commit d925fff

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

Lib/test/test_ast.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,12 @@ def test_stdlib_validates(self):
20352035
kwd_attrs=[],
20362036
kwd_patterns=[ast.MatchStar()]
20372037
),
2038+
ast.MatchClass(
2039+
constant_true, # invalid name
2040+
patterns=[],
2041+
kwd_attrs=['True'],
2042+
kwd_patterns=[pattern_1]
2043+
),
20382044
ast.MatchSequence(
20392045
[
20402046
ast.MatchStar("True")

Python/ast.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static int validate_pattern(struct validator *, pattern_ty, int);
4646
static int
4747
validate_name(PyObject *name)
4848
{
49+
assert(!PyErr_Occurred());
4950
assert(PyUnicode_Check(name));
5051
static const char * const forbidden[] = {
5152
"None",
@@ -65,6 +66,7 @@ validate_name(PyObject *name)
6566
static int
6667
validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
6768
{
69+
assert(!PyErr_Occurred());
6870
Py_ssize_t i;
6971
if (!asdl_seq_LEN(gens)) {
7072
PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
@@ -83,6 +85,7 @@ validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
8385
static int
8486
validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
8587
{
88+
assert(!PyErr_Occurred());
8689
Py_ssize_t i;
8790
for (i = 0; i < asdl_seq_LEN(keywords); i++)
8891
if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
@@ -93,6 +96,7 @@ validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
9396
static int
9497
validate_args(struct validator *state, asdl_arg_seq *args)
9598
{
99+
assert(!PyErr_Occurred());
96100
Py_ssize_t i;
97101
for (i = 0; i < asdl_seq_LEN(args); i++) {
98102
arg_ty arg = asdl_seq_GET(args, i);
@@ -121,6 +125,7 @@ expr_context_name(expr_context_ty ctx)
121125
static int
122126
validate_arguments(struct validator *state, arguments_ty args)
123127
{
128+
assert(!PyErr_Occurred());
124129
if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
125130
return 0;
126131
}
@@ -149,6 +154,7 @@ validate_arguments(struct validator *state, arguments_ty args)
149154
static int
150155
validate_constant(struct validator *state, PyObject *value)
151156
{
157+
assert(!PyErr_Occurred());
152158
if (value == Py_None || value == Py_Ellipsis)
153159
return 1;
154160

@@ -205,6 +211,7 @@ validate_constant(struct validator *state, PyObject *value)
205211
static int
206212
validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
207213
{
214+
assert(!PyErr_Occurred());
208215
VALIDATE_POSITIONS(exp);
209216
int ret = -1;
210217
if (++state->recursion_depth > state->recursion_limit) {
@@ -465,6 +472,7 @@ ensure_literal_complex(expr_ty exp)
465472
static int
466473
validate_pattern_match_value(struct validator *state, expr_ty exp)
467474
{
475+
assert(!PyErr_Occurred());
468476
if (!validate_expr(state, exp, Load)) {
469477
return 0;
470478
}
@@ -518,6 +526,7 @@ validate_pattern_match_value(struct validator *state, expr_ty exp)
518526
static int
519527
validate_capture(PyObject *name)
520528
{
529+
assert(!PyErr_Occurred());
521530
if (_PyUnicode_EqualToASCIIString(name, "_")) {
522531
PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns");
523532
return 0;
@@ -528,6 +537,7 @@ validate_capture(PyObject *name)
528537
static int
529538
validate_pattern(struct validator *state, pattern_ty p, int star_ok)
530539
{
540+
assert(!PyErr_Occurred());
531541
VALIDATE_POSITIONS(p);
532542
int ret = -1;
533543
if (++state->recursion_depth > state->recursion_limit) {
@@ -693,22 +703,24 @@ _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
693703
static int
694704
validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
695705
{
706+
assert(!PyErr_Occurred());
696707
return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
697708
validate_exprs(state, targets, ctx, 0);
698709
}
699710

700711
static int
701712
validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
702713
{
714+
assert(!PyErr_Occurred());
703715
return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
704716
}
705717

706718
static int
707719
validate_stmt(struct validator *state, stmt_ty stmt)
708720
{
721+
assert(!PyErr_Occurred());
709722
VALIDATE_POSITIONS(stmt);
710723
int ret = -1;
711-
Py_ssize_t i;
712724
if (++state->recursion_depth > state->recursion_limit) {
713725
PyErr_SetString(PyExc_RecursionError,
714726
"maximum recursion depth exceeded during compilation");
@@ -779,7 +791,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
779791
case With_kind:
780792
if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
781793
return 0;
782-
for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
794+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
783795
withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
784796
if (!validate_expr(state, item->context_expr, Load) ||
785797
(item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
@@ -790,7 +802,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
790802
case AsyncWith_kind:
791803
if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
792804
return 0;
793-
for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
805+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
794806
withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
795807
if (!validate_expr(state, item->context_expr, Load) ||
796808
(item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
@@ -803,7 +815,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
803815
|| !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
804816
return 0;
805817
}
806-
for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
818+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
807819
match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
808820
if (!validate_pattern(state, m->pattern, /*star_ok=*/0)
809821
|| (m->guard && !validate_expr(state, m->guard, Load))
@@ -838,7 +850,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
838850
PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
839851
return 0;
840852
}
841-
for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
853+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
842854
excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
843855
VALIDATE_POSITIONS(handler);
844856
if ((handler->v.ExceptHandler.type &&
@@ -864,7 +876,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
864876
PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers");
865877
return 0;
866878
}
867-
for (i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
879+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
868880
excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i);
869881
if ((handler->v.ExceptHandler.type &&
870882
!validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
@@ -924,8 +936,8 @@ validate_stmt(struct validator *state, stmt_ty stmt)
924936
static int
925937
validate_stmts(struct validator *state, asdl_stmt_seq *seq)
926938
{
927-
Py_ssize_t i;
928-
for (i = 0; i < asdl_seq_LEN(seq); i++) {
939+
assert(!PyErr_Occurred());
940+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(seq); i++) {
929941
stmt_ty stmt = asdl_seq_GET(seq, i);
930942
if (stmt) {
931943
if (!validate_stmt(state, stmt))
@@ -943,8 +955,8 @@ validate_stmts(struct validator *state, asdl_stmt_seq *seq)
943955
static int
944956
validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
945957
{
946-
Py_ssize_t i;
947-
for (i = 0; i < asdl_seq_LEN(exprs); i++) {
958+
assert(!PyErr_Occurred());
959+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(exprs); i++) {
948960
expr_ty expr = asdl_seq_GET(exprs, i);
949961
if (expr) {
950962
if (!validate_expr(state, expr, ctx))
@@ -963,8 +975,8 @@ validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ct
963975
static int
964976
validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok)
965977
{
966-
Py_ssize_t i;
967-
for (i = 0; i < asdl_seq_LEN(patterns); i++) {
978+
assert(!PyErr_Occurred());
979+
for (Py_ssize_t i = 0; i < asdl_seq_LEN(patterns); i++) {
968980
pattern_ty pattern = asdl_seq_GET(patterns, i);
969981
if (!validate_pattern(state, pattern, star_ok)) {
970982
return 0;
@@ -980,6 +992,7 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_
980992
int
981993
_PyAST_Validate(mod_ty mod)
982994
{
995+
assert(!PyErr_Occurred());
983996
int res = -1;
984997
struct validator state;
985998
PyThreadState *tstate;

0 commit comments

Comments
 (0)