@@ -5355,9 +5355,114 @@ codegen_slice(compiler *c, expr_ty s)
53555355#define  WILDCARD_STAR_CHECK (N ) \
53565356    ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
53575357
5358- // Limit permitted subexpressions, even if the parser & AST validator let them through 
5359- #define  MATCH_VALUE_EXPR (N ) \
5360-     ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
5358+ static  bool 
5359+ is_unary_or_complex_expr (expr_ty  e )
5360+ {
5361+     if  (e -> kind  !=  UnaryOp_kind ) {
5362+         return  false;
5363+     }
5364+     if  (e -> v .UnaryOp .op  !=  USub ) {
5365+         return  false;
5366+     }
5367+     if  (e -> v .UnaryOp .operand -> kind  !=  Constant_kind ) {
5368+         return  false;
5369+     }
5370+     PyObject  * constant  =  e -> v .UnaryOp .operand -> v .Constant .value ;
5371+     return  PyLong_CheckExact (constant ) ||  PyFloat_CheckExact (constant ) ||  PyComplex_CheckExact (constant );
5372+ }
5373+ 
5374+ static  bool 
5375+ is_complex_binop_expr (expr_ty  e )
5376+ {
5377+     if  (e -> kind  !=  BinOp_kind ) {
5378+         return  false;
5379+     }
5380+     if  (e -> v .BinOp .op  !=  Add  &&  e -> v .BinOp .op  !=  Sub ) {
5381+         return  false;
5382+     }
5383+     if  (e -> v .BinOp .right -> kind  !=  Constant_kind ) {
5384+         return  false;
5385+     }
5386+     if  (e -> v .BinOp .left -> kind  !=  Constant_kind  &&  e -> v .BinOp .left -> kind  !=  UnaryOp_kind ) {
5387+         return  false;
5388+     }
5389+     PyObject  * leftconst ;
5390+     if  (e -> v .BinOp .left -> kind  ==  UnaryOp_kind ) {
5391+         if  (e -> v .BinOp .left -> v .UnaryOp .operand -> kind  !=  Constant_kind ) {
5392+             return  false;
5393+         }
5394+         if  (e -> v .BinOp .left -> v .UnaryOp .op  !=  USub ) {
5395+             return  false;
5396+         }
5397+         leftconst  =  e -> v .BinOp .left -> v .UnaryOp .operand -> v .Constant .value ;
5398+     }
5399+     else  {
5400+         leftconst  =  e -> v .BinOp .left -> v .Constant .value ;
5401+     }
5402+     PyObject  * rightconst  =  e -> v .BinOp .right -> v .Constant .value ;
5403+     return  (PyLong_CheckExact (leftconst ) ||  PyFloat_CheckExact (leftconst )) &&  PyComplex_CheckExact (rightconst );
5404+ }
5405+ 
5406+ static  void 
5407+ fold_node (expr_ty  node , PyObject  * folded )
5408+ {
5409+     assert (node -> kind  !=  Constant_kind );
5410+     node -> kind  =  Constant_kind ;
5411+     node -> v .Constant .kind  =  NULL ;
5412+     node -> v .Constant .value  =  folded ;
5413+ }
5414+ 
5415+ static  int 
5416+ fold_unary_or_complex_expr (expr_ty  e )
5417+ {
5418+     assert (e -> kind  ==  UnaryOp_kind );
5419+     assert (e -> v .UnaryOp .op  ==  USub );
5420+     assert (e -> v .UnaryOp .operand -> kind  ==  Constant_kind );
5421+     PyObject  * operand  =  e -> v .UnaryOp .operand -> v .Constant .value ;
5422+     assert (PyLong_CheckExact (operand ) ||  PyFloat_CheckExact (operand ) ||  PyComplex_CheckExact (operand ));
5423+     PyObject *  folded  =  PyNumber_Negative (operand );
5424+     if  (folded  ==  NULL ) {
5425+         return  ERROR ;
5426+     }
5427+     fold_node (e , folded );
5428+     return  SUCCESS ;
5429+ }
5430+ 
5431+ static  int 
5432+ fold_binary_complex_expr (expr_ty  e )
5433+ {
5434+     assert (e -> kind  ==  BinOp_kind );
5435+     assert (e -> v .BinOp .right -> kind  ==  Constant_kind );
5436+     assert (e -> v .BinOp .left -> kind  ==  UnaryOp_kind  ||  e -> v .BinOp .left -> kind  ==  Constant_kind );
5437+     if  (e -> v .BinOp .left -> kind  ==  UnaryOp_kind ) {
5438+         RETURN_IF_ERROR (fold_unary_or_complex_expr (e -> v .BinOp .left ));
5439+     }
5440+     assert (e -> v .BinOp .left -> kind  ==  Constant_kind );
5441+     operator_ty  op  =  e -> v .BinOp .op ;
5442+     PyObject  * left  =  e -> v .BinOp .left -> v .Constant .value ;
5443+     PyObject  * right  =  e -> v .BinOp .right -> v .Constant .value ;
5444+     assert (op  ==  Add  ||  op  ==  Sub );
5445+     assert (PyLong_CheckExact (left ) ||  PyFloat_CheckExact (left ));
5446+     assert (PyComplex_CheckExact (right ));
5447+     PyObject  * folded  =  op  ==  Add  ? PyNumber_Add (left , right ) : PyNumber_Subtract (left , right );
5448+     if  (folded  ==  NULL ) {
5449+         return  ERROR ;
5450+     }
5451+     fold_node (e , folded );
5452+     return  SUCCESS ;
5453+ }
5454+ 
5455+ static  int 
5456+ try_fold_unary_or_binary_complex_const_expr (expr_ty  key )
5457+ {
5458+     if  (is_unary_or_complex_expr (key )) {
5459+         return  fold_unary_or_complex_expr (key );
5460+     }
5461+     if  (is_complex_binop_expr (key )) {
5462+         return  fold_binary_complex_expr (key );
5463+     }
5464+     return  SUCCESS ;
5465+ }
53615466
53625467// Allocate or resize pc->fail_pop to allow for n items to be popped on failure. 
53635468static  int 
@@ -5688,7 +5793,7 @@ codegen_pattern_mapping_key(compiler *c, PyObject *seen, pattern_ty p, Py_ssize_
56885793        location  loc  =  LOC ((pattern_ty ) asdl_seq_GET (patterns , i ));
56895794        return  _PyCompile_Error (c , loc , e );
56905795    }
5691- 
5796+      RETURN_IF_ERROR ( try_fold_unary_or_binary_complex_const_expr ( key )); 
56925797    if  (key -> kind  ==  Constant_kind ) {
56935798        int  in_seen  =  PySet_Contains (seen , key -> v .Constant .value );
56945799        RETURN_IF_ERROR (in_seen );
@@ -6022,7 +6127,8 @@ codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc)
60226127{
60236128    assert (p -> kind  ==  MatchValue_kind );
60246129    expr_ty  value  =  p -> v .MatchValue .value ;
6025-     if  (!MATCH_VALUE_EXPR (value )) {
6130+     RETURN_IF_ERROR (try_fold_unary_or_binary_complex_const_expr (value ));
6131+     if  (value -> kind  !=  Constant_kind  &&  value -> kind  !=  Attribute_kind ) {
60266132        const  char  * e  =  "patterns may only match literals and attribute lookups" ;
60276133        return  _PyCompile_Error (c , LOC (p ), e );
60286134    }
0 commit comments