@@ -3487,12 +3487,13 @@ def visit_op_expr(self, e: OpExpr) -> Type:
34873487 if isinstance (e .left , StrExpr ):
34883488 return self .strfrm_checker .check_str_interpolation (e .left , e .right )
34893489 left_type = self .accept (e .left )
3490-
3490+ right_type = self . accept ( e . right )
34913491 proper_left_type = get_proper_type (left_type )
3492+ proper_right_type = get_proper_type (right_type )
3493+
34923494 if isinstance (proper_left_type , TupleType ) and e .op == "+" :
34933495 left_add_method = proper_left_type .partial_fallback .type .get ("__add__" )
34943496 if left_add_method and left_add_method .fullname == "builtins.tuple.__add__" :
3495- proper_right_type = get_proper_type (self .accept (e .right ))
34963497 if isinstance (proper_right_type , TupleType ):
34973498 right_radd_method = proper_right_type .partial_fallback .type .get ("__radd__" )
34983499 if right_radd_method is None :
@@ -3520,7 +3521,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
35203521 items = proper_left_type .items + [UnpackType (mapped )]
35213522 )
35223523
3523- if e .op == "+" and (result := self .literal_expression_addition (e , left_type )):
3524+ if e .op == "+" and (result := self .literal_expression_addition (e , left_type , right_type )):
35243525 return result
35253526
35263527 use_reverse : UseReverse = USE_REVERSE_DEFAULT
@@ -3529,14 +3530,12 @@ def visit_op_expr(self, e: OpExpr) -> Type:
35293530 # This is a special case for `dict | TypedDict`.
35303531 # 1. Find `dict | TypedDict` case
35313532 # 2. Switch `dict.__or__` to `TypedDict.__ror__` (the same from both runtime and typing perspective)
3532- proper_right_type = get_proper_type (self .accept (e .right ))
35333533 if isinstance (proper_right_type , TypedDictType ):
35343534 use_reverse = USE_REVERSE_ALWAYS
35353535 if isinstance (proper_left_type , TypedDictType ):
35363536 # This is the reverse case: `TypedDict | dict`,
35373537 # simply do not allow the reverse checking:
35383538 # do not call `__dict__.__ror__`.
3539- proper_right_type = get_proper_type (self .accept (e .right ))
35403539 if is_named_instance (proper_right_type , "builtins.dict" ):
35413540 use_reverse = USE_REVERSE_NEVER
35423541
@@ -3547,7 +3546,6 @@ def visit_op_expr(self, e: OpExpr) -> Type:
35473546 and isinstance (proper_left_type , Instance )
35483547 and proper_left_type .type .fullname == "builtins.tuple"
35493548 ):
3550- proper_right_type = get_proper_type (self .accept (e .right ))
35513549 if (
35523550 isinstance (proper_right_type , TupleType )
35533551 and proper_right_type .partial_fallback .type .fullname == "builtins.tuple"
@@ -3571,7 +3569,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
35713569 result , method_type = self .check_op (
35723570 # The reverse operator here gives better error messages:
35733571 operators .reverse_op_methods [method ],
3574- base_type = self . accept ( e . right ) ,
3572+ base_type = right_type ,
35753573 arg = e .left ,
35763574 context = e ,
35773575 allow_reverse = False ,
@@ -3584,7 +3582,7 @@ def visit_op_expr(self, e: OpExpr) -> Type:
35843582 raise RuntimeError (f"Unknown operator { e .op } " )
35853583
35863584 def literal_value_from_expr (
3587- self , expr : Expression , typ : Type | None = None
3585+ self , expr : Expression , typ : Type
35883586 ) -> tuple [list [str | int ], str , bool ] | None :
35893587 if isinstance (expr , StrExpr ):
35903588 return [expr .value ], "builtins.str" , False
@@ -3593,7 +3591,6 @@ def literal_value_from_expr(
35933591 if isinstance (expr , BytesExpr ):
35943592 return [expr .value ], "builtins.bytes" , False
35953593
3596- typ = typ or self .accept (expr )
35973594 ptype = get_proper_type (typ )
35983595
35993596 if isinstance (ptype , LiteralType ) and not isinstance (ptype .value , (bool , float )):
@@ -3611,18 +3608,20 @@ def literal_value_from_expr(
36113608 if fallback != pitem .fallback .type .fullname :
36123609 break
36133610 values .append (pitem .value )
3614- else :
3611+ else : # no break
36153612 assert fallback is not None
36163613 return values , fallback , True
36173614 return None
36183615
3619- def literal_expression_addition (self , e : OpExpr , left_type : Type ) -> Type | None :
3616+ def literal_expression_addition (
3617+ self , e : OpExpr , left_type : Type , right_type : Type
3618+ ) -> Type | None :
36203619 """Check if literal values can be combined with addition."""
36213620 assert e .op == "+"
36223621 if not (lvalue := self .literal_value_from_expr (e .left , left_type )):
36233622 return None
36243623 if (
3625- not (rvalue := self .literal_value_from_expr (e .right ))
3624+ not (rvalue := self .literal_value_from_expr (e .right , right_type ))
36263625 or lvalue [1 ] != rvalue [1 ] # different fallback
36273626 or lvalue [2 ] + rvalue [2 ] == 0 # no LiteralType
36283627 ):
0 commit comments