@@ -20,7 +20,7 @@ static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
20
20
static int _validate_nonempty_seq (asdl_seq * , const char * , const char * );
21
21
static int validate_stmt (struct validator * , stmt_ty );
22
22
static 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 );
24
24
25
25
static int
26
26
validate_name (PyObject * name )
@@ -493,16 +493,24 @@ validate_pattern_match_value(struct validator *state, expr_ty exp)
493
493
}
494
494
495
495
static 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 )
497
507
{
498
508
int ret = -1 ;
499
509
if (++ state -> recursion_depth > state -> recursion_limit ) {
500
510
PyErr_SetString (PyExc_RecursionError ,
501
511
"maximum recursion depth exceeded during compilation" );
502
512
return 0 ;
503
513
}
504
- // Coming soon: https://bugs.python.org/issue43897 (thanks Batuhan)!
505
- // TODO: Ensure no subnodes use "_" as an ordinary identifier
506
514
switch (p -> kind ) {
507
515
case MatchValue_kind :
508
516
ret = validate_pattern_match_value (state , p -> v .MatchValue .value );
@@ -525,7 +533,7 @@ validate_pattern(struct validator *state, pattern_ty p)
525
533
break ;
526
534
}
527
535
528
- if (p -> v .MatchMapping .rest && !validate_name (p -> v .MatchMapping .rest )) {
536
+ if (p -> v .MatchMapping .rest && !validate_capture (p -> v .MatchMapping .rest )) {
529
537
ret = 0 ;
530
538
break ;
531
539
}
@@ -575,16 +583,16 @@ validate_pattern(struct validator *state, pattern_ty p)
575
583
else {
576
584
PyErr_SetString (PyExc_ValueError ,
577
585
"MatchClass cls field can only contain Name or Attribute nodes." );
578
- state -> recursion_depth -- ;
579
- return 0 ;
586
+ ret = 0 ;
587
+ break ;
580
588
}
581
589
}
582
590
583
591
for (Py_ssize_t i = 0 ; i < asdl_seq_LEN (p -> v .MatchClass .kwd_attrs ); i ++ ) {
584
592
PyObject * identifier = asdl_seq_GET (p -> v .MatchClass .kwd_attrs , i );
585
593
if (!validate_name (identifier )) {
586
- state -> recursion_depth -- ;
587
- return 0 ;
594
+ ret = 0 ;
595
+ break ;
588
596
}
589
597
}
590
598
@@ -596,10 +604,15 @@ validate_pattern(struct validator *state, pattern_ty p)
596
604
ret = validate_patterns (state , p -> v .MatchClass .kwd_patterns , /*star_ok=*/ 0 );
597
605
break ;
598
606
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 );
600
613
break ;
601
614
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 )) {
603
616
ret = 0 ;
604
617
break ;
605
618
}
@@ -609,10 +622,10 @@ validate_pattern(struct validator *state, pattern_ty p)
609
622
else if (p -> v .MatchAs .name == NULL ) {
610
623
PyErr_SetString (PyExc_ValueError ,
611
624
"MatchAs must specify a target name if a pattern is given" );
612
- return 0 ;
625
+ ret = 0 ;
613
626
}
614
627
else {
615
- ret = validate_pattern (state , p -> v .MatchAs .pattern );
628
+ ret = validate_pattern (state , p -> v .MatchAs .pattern , /*star_ok=*/ 0 );
616
629
}
617
630
break ;
618
631
case MatchOr_kind :
@@ -759,7 +772,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
759
772
}
760
773
for (i = 0 ; i < asdl_seq_LEN (stmt -> v .Match .cases ); i ++ ) {
761
774
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 )
763
776
|| (m -> guard && !validate_expr (state , m -> guard , Load ))
764
777
|| !validate_body (state , m -> body , "match_case" )) {
765
778
return 0 ;
@@ -894,12 +907,7 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_
894
907
Py_ssize_t i ;
895
908
for (i = 0 ; i < asdl_seq_LEN (patterns ); i ++ ) {
896
909
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 )) {
903
911
return 0 ;
904
912
}
905
913
}
0 commit comments