@@ -3418,12 +3418,13 @@ def visit_op_expr(self, e: OpExpr) -> Type:
34183418 if isinstance (e .left , StrExpr ):
34193419 return self .strfrm_checker .check_str_interpolation (e .left , e .right )
34203420 left_type = self .accept (e .left )
3421-
3421+ right_type = self . accept ( e . right )
34223422 proper_left_type = get_proper_type (left_type )
3423+ proper_right_type = get_proper_type (right_type )
3424+
34233425 if isinstance (proper_left_type , TupleType ) and e .op == "+" :
34243426 left_add_method = proper_left_type .partial_fallback .type .get ("__add__" )
34253427 if left_add_method and left_add_method .fullname == "builtins.tuple.__add__" :
3426- proper_right_type = get_proper_type (self .accept (e .right ))
34273428 if isinstance (proper_right_type , TupleType ):
34283429 right_radd_method = proper_right_type .partial_fallback .type .get ("__radd__" )
34293430 if right_radd_method is None :
@@ -3451,7 +3452,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
34513452 items = proper_left_type .items + [UnpackType (mapped )]
34523453 )
34533454
3454- if e .op == "+" and (result := self .literal_expression_addition (e , left_type )):
3455+ if e .op == "+" and (result := self .literal_expression_addition (e , left_type , right_type )):
34553456 return result
34563457
34573458 use_reverse : UseReverse = USE_REVERSE_DEFAULT
@@ -3460,14 +3461,12 @@ def visit_op_expr(self, e: OpExpr) -> Type:
34603461 # This is a special case for `dict | TypedDict`.
34613462 # 1. Find `dict | TypedDict` case
34623463 # 2. Switch `dict.__or__` to `TypedDict.__ror__` (the same from both runtime and typing perspective)
3463- proper_right_type = get_proper_type (self .accept (e .right ))
34643464 if isinstance (proper_right_type , TypedDictType ):
34653465 use_reverse = USE_REVERSE_ALWAYS
34663466 if isinstance (proper_left_type , TypedDictType ):
34673467 # This is the reverse case: `TypedDict | dict`,
34683468 # simply do not allow the reverse checking:
34693469 # do not call `__dict__.__ror__`.
3470- proper_right_type = get_proper_type (self .accept (e .right ))
34713470 if is_named_instance (proper_right_type , "builtins.dict" ):
34723471 use_reverse = USE_REVERSE_NEVER
34733472
@@ -3478,7 +3477,6 @@ def visit_op_expr(self, e: OpExpr) -> Type:
34783477 and isinstance (proper_left_type , Instance )
34793478 and proper_left_type .type .fullname == "builtins.tuple"
34803479 ):
3481- proper_right_type = get_proper_type (self .accept (e .right ))
34823480 if (
34833481 isinstance (proper_right_type , TupleType )
34843482 and proper_right_type .partial_fallback .type .fullname == "builtins.tuple"
@@ -3502,7 +3500,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
35023500 result , method_type = self .check_op (
35033501 # The reverse operator here gives better error messages:
35043502 operators .reverse_op_methods [method ],
3505- base_type = self . accept ( e . right ) ,
3503+ base_type = right_type ,
35063504 arg = e .left ,
35073505 context = e ,
35083506 allow_reverse = False ,
@@ -3515,7 +3513,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
35153513 raise RuntimeError (f"Unknown operator { e .op } " )
35163514
35173515 def literal_value_from_expr (
3518- self , expr : Expression , typ : Type | None = None
3516+ self , expr : Expression , typ : Type
35193517 ) -> tuple [list [str | int ], str , bool ] | None :
35203518 if isinstance (expr , StrExpr ):
35213519 return [expr .value ], "builtins.str" , False
@@ -3524,7 +3522,6 @@ def literal_value_from_expr(
35243522 if isinstance (expr , BytesExpr ):
35253523 return [expr .value ], "builtins.bytes" , False
35263524
3527- typ = typ or self .accept (expr )
35283525 ptype = get_proper_type (typ )
35293526
35303527 if isinstance (ptype , LiteralType ) and not isinstance (ptype .value , (bool , float )):
@@ -3542,18 +3539,20 @@ def literal_value_from_expr(
35423539 if fallback != pitem .fallback .type .fullname :
35433540 break
35443541 values .append (pitem .value )
3545- else :
3542+ else : # no break
35463543 assert fallback is not None
35473544 return values , fallback , True
35483545 return None
35493546
3550- def literal_expression_addition (self , e : OpExpr , left_type : Type ) -> Type | None :
3547+ def literal_expression_addition (
3548+ self , e : OpExpr , left_type : Type , right_type : Type
3549+ ) -> Type | None :
35513550 """Check if literal values can be combined with addition."""
35523551 assert e .op == "+"
35533552 if not (lvalue := self .literal_value_from_expr (e .left , left_type )):
35543553 return None
35553554 if (
3556- not (rvalue := self .literal_value_from_expr (e .right ))
3555+ not (rvalue := self .literal_value_from_expr (e .right , right_type ))
35573556 or lvalue [1 ] != rvalue [1 ] # different fallback
35583557 or lvalue [2 ] + rvalue [2 ] == 0 # no LiteralType
35593558 ):
0 commit comments