@@ -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 }