bpo-43897: Reject "_" captures and top-level MatchStar in the AST val… · python/cpython@8d06474

GitHub

@@ -20,7 +20,7 @@ static int validate_patterns(struct validator *, asdl_pattern_seq *, int);

2020staticint_validate_nonempty_seq(asdl_seq*, constchar*, constchar*);

2121staticintvalidate_stmt(structvalidator*, stmt_ty);

2222staticintvalidate_expr(structvalidator*, expr_ty, expr_context_ty);

23-staticintvalidate_pattern(structvalidator*, pattern_ty);

23+staticintvalidate_pattern(structvalidator*, pattern_ty, int);

24242525staticint

2626validate_name(PyObject*name)

@@ -493,16 +493,24 @@ validate_pattern_match_value(struct validator *state, expr_ty exp)

493493}

494494495495staticint

496-validate_pattern(structvalidator*state, pattern_typ)

496+validate_capture(PyObject*name)

497+{

498+if (_PyUnicode_EqualToASCIIString(name, "_")) {

499+PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns");

500+return0;

501+ }

502+returnvalidate_name(name);

503+}

504+505+staticint

506+validate_pattern(structvalidator*state, pattern_typ, intstar_ok)

497507{

498508intret=-1;

499509if (++state->recursion_depth>state->recursion_limit) {

500510PyErr_SetString(PyExc_RecursionError,

501511"maximum recursion depth exceeded during compilation");

502512return0;

503513 }

504-// Coming soon: https://bugs.python.org/issue43897 (thanks Batuhan)!

505-// TODO: Ensure no subnodes use "_" as an ordinary identifier

506514switch (p->kind) {

507515caseMatchValue_kind:

508516ret=validate_pattern_match_value(state, p->v.MatchValue.value);

@@ -525,7 +533,7 @@ validate_pattern(struct validator *state, pattern_ty p)

525533break;

526534 }

527535528-if (p->v.MatchMapping.rest&& !validate_name(p->v.MatchMapping.rest)) {

536+if (p->v.MatchMapping.rest&& !validate_capture(p->v.MatchMapping.rest)) {

529537ret=0;

530538break;

531539 }

@@ -575,16 +583,16 @@ validate_pattern(struct validator *state, pattern_ty p)

575583else {

576584PyErr_SetString(PyExc_ValueError,

577585"MatchClass cls field can only contain Name or Attribute nodes.");

578-state->recursion_depth--;

579-return0;

586+ret=0;

587+break;

580588 }

581589 }

582590583591for (Py_ssize_ti=0; i<asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) {

584592PyObject*identifier=asdl_seq_GET(p->v.MatchClass.kwd_attrs, i);

585593if (!validate_name(identifier)) {

586-state->recursion_depth--;

587-return0;

594+ret=0;

595+break;

588596 }

589597 }

590598@@ -596,10 +604,15 @@ validate_pattern(struct validator *state, pattern_ty p)

596604ret=validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0);

597605break;

598606caseMatchStar_kind:

599-ret=p->v.MatchStar.name==NULL||validate_name(p->v.MatchStar.name);

607+if (!star_ok) {

608+PyErr_SetString(PyExc_ValueError, "can't use MatchStar here");

609+ret=0;

610+break;

611+ }

612+ret=p->v.MatchStar.name==NULL||validate_capture(p->v.MatchStar.name);

600613break;

601614caseMatchAs_kind:

602-if (p->v.MatchAs.name&& !validate_name(p->v.MatchAs.name)) {

615+if (p->v.MatchAs.name&& !validate_capture(p->v.MatchAs.name)) {

603616ret=0;

604617break;

605618 }

@@ -609,10 +622,10 @@ validate_pattern(struct validator *state, pattern_ty p)

609622elseif (p->v.MatchAs.name==NULL) {

610623PyErr_SetString(PyExc_ValueError,

611624"MatchAs must specify a target name if a pattern is given");

612-return0;

625+ret=0;

613626 }

614627else {

615-ret=validate_pattern(state, p->v.MatchAs.pattern);

628+ret=validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0);

616629 }

617630break;

618631caseMatchOr_kind:

@@ -759,7 +772,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)

759772 }

760773for (i=0; i<asdl_seq_LEN(stmt->v.Match.cases); i++) {

761774match_case_tym=asdl_seq_GET(stmt->v.Match.cases, i);

762-if (!validate_pattern(state, m->pattern)

775+if (!validate_pattern(state, m->pattern, /*star_ok=*/0)

763776|| (m->guard&& !validate_expr(state, m->guard, Load))

764777|| !validate_body(state, m->body, "match_case")) {

765778return0;

@@ -894,12 +907,7 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_

894907Py_ssize_ti;

895908for (i=0; i<asdl_seq_LEN(patterns); i++) {

896909pattern_typattern=asdl_seq_GET(patterns, i);

897-if (pattern->kind==MatchStar_kind&& !star_ok) {

898-PyErr_SetString(PyExc_ValueError,

899-"Can't use MatchStar within this sequence of patterns");

900-return0;

901- }

902-if (!validate_pattern(state, pattern)) {

910+if (!validate_pattern(state, pattern, star_ok)) {

903911return0;

904912 }

905913 }