@@ -20,7 +20,7 @@ static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
2020static int _validate_nonempty_seq (asdl_seq * , const char * , const char * );
2121static int validate_stmt (struct validator * , stmt_ty );
2222static int validate_expr (struct validator * , expr_ty , expr_context_ty );
23- static int validate_pattern (struct validator * , pattern_ty );
23+ static int validate_pattern (struct validator * , pattern_ty , int );
2424
2525static int
2626validate_name (PyObject * name )
@@ -493,16 +493,24 @@ validate_pattern_match_value(struct validator *state, expr_ty exp)
493493}
494494
495495static int
496- validate_pattern (struct validator * state , pattern_ty p )
496+ validate_capture (PyObject * name )
497+ {
498+ if (_PyUnicode_EqualToASCIIString (name , "_" )) {
499+ PyErr_Format (PyExc_ValueError , "can't capture name '_' in patterns" );
500+ return 0 ;
501+ }
502+ return validate_name (name );
503+ }
504+
505+ static int
506+ validate_pattern (struct validator * state , pattern_ty p , int star_ok )
497507{
498508 int ret = -1 ;
499509 if (++ state -> recursion_depth > state -> recursion_limit ) {
500510 PyErr_SetString (PyExc_RecursionError ,
501511 "maximum recursion depth exceeded during compilation" );
502512 return 0 ;
503513 }
504- // Coming soon: https://bugs.python.org/issue43897 (thanks Batuhan)!
505- // TODO: Ensure no subnodes use "_" as an ordinary identifier
506514 switch (p -> kind ) {
507515 case MatchValue_kind :
508516 ret = validate_pattern_match_value (state , p -> v .MatchValue .value );
@@ -525,7 +533,7 @@ validate_pattern(struct validator *state, pattern_ty p)
525533 break ;
526534 }
527535
528- if (p -> v .MatchMapping .rest && !validate_name (p -> v .MatchMapping .rest )) {
536+ if (p -> v .MatchMapping .rest && !validate_capture (p -> v .MatchMapping .rest )) {
529537 ret = 0 ;
530538 break ;
531539 }
@@ -575,16 +583,16 @@ validate_pattern(struct validator *state, pattern_ty p)
575583 else {
576584 PyErr_SetString (PyExc_ValueError ,
577585 "MatchClass cls field can only contain Name or Attribute nodes." );
578- state -> recursion_depth -- ;
579- return 0 ;
586+ ret = 0 ;
587+ break ;
580588 }
581589 }
582590
583591 for (Py_ssize_t i = 0 ; i < asdl_seq_LEN (p -> v .MatchClass .kwd_attrs ); i ++ ) {
584592 PyObject * identifier = asdl_seq_GET (p -> v .MatchClass .kwd_attrs , i );
585593 if (!validate_name (identifier )) {
586- state -> recursion_depth -- ;
587- return 0 ;
594+ ret = 0 ;
595+ break ;
588596 }
589597 }
590598
@@ -596,10 +604,15 @@ validate_pattern(struct validator *state, pattern_ty p)
596604 ret = validate_patterns (state , p -> v .MatchClass .kwd_patterns , /*star_ok=*/ 0 );
597605 break ;
598606 case MatchStar_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 );
600613 break ;
601614 case MatchAs_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 )) {
603616 ret = 0 ;
604617 break ;
605618 }
@@ -609,10 +622,10 @@ validate_pattern(struct validator *state, pattern_ty p)
609622 else if (p -> v .MatchAs .name == NULL ) {
610623 PyErr_SetString (PyExc_ValueError ,
611624 "MatchAs must specify a target name if a pattern is given" );
612- return 0 ;
625+ ret = 0 ;
613626 }
614627 else {
615- ret = validate_pattern (state , p -> v .MatchAs .pattern );
628+ ret = validate_pattern (state , p -> v .MatchAs .pattern , /*star_ok=*/ 0 );
616629 }
617630 break ;
618631 case MatchOr_kind :
@@ -759,7 +772,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
759772 }
760773 for (i = 0 ; i < asdl_seq_LEN (stmt -> v .Match .cases ); i ++ ) {
761774 match_case_ty m = 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" )) {
765778 return 0 ;
@@ -894,12 +907,7 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_
894907 Py_ssize_t i ;
895908 for (i = 0 ; i < asdl_seq_LEN (patterns ); i ++ ) {
896909 pattern_ty pattern = 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- return 0 ;
901- }
902- if (!validate_pattern (state , pattern )) {
910+ if (!validate_pattern (state , pattern , star_ok )) {
903911 return 0 ;
904912 }
905913 }
0 commit comments