@@ -1880,6 +1880,11 @@ def infer_literal_expr_type(self, value: LiteralValue, fallback_name: str) -> Ty
1880
1880
column = typ .column ,
1881
1881
))
1882
1882
1883
+ def concat_tuples (self , left : TupleType , right : TupleType ) -> TupleType :
1884
+ """Concatenate two fixed length tuples."""
1885
+ return TupleType (items = left .items + right .items ,
1886
+ fallback = self .named_type ('builtins.tuple' ))
1887
+
1883
1888
def visit_int_expr (self , e : IntExpr ) -> Type :
1884
1889
"""Type check an integer literal (trivial)."""
1885
1890
return self .infer_literal_expr_type (e .value , 'builtins.int' )
@@ -1939,6 +1944,16 @@ def visit_op_expr(self, e: OpExpr) -> Type:
1939
1944
return self .strfrm_checker .check_str_interpolation (e .left , e .right )
1940
1945
left_type = self .accept (e .left )
1941
1946
1947
+ proper_left_type = get_proper_type (left_type )
1948
+ if isinstance (proper_left_type , TupleType ) and e .op == '+' :
1949
+ left_add_method = proper_left_type .partial_fallback .type .get ('__add__' )
1950
+ if left_add_method and left_add_method .fullname == 'builtins.tuple.__add__' :
1951
+ proper_right_type = get_proper_type (self .accept (e .right ))
1952
+ if isinstance (proper_right_type , TupleType ):
1953
+ right_radd_method = proper_right_type .partial_fallback .type .get ('__radd__' )
1954
+ if right_radd_method is None :
1955
+ return self .concat_tuples (proper_left_type , proper_right_type )
1956
+
1942
1957
if e .op in nodes .op_methods :
1943
1958
method = self .get_operator_method (e .op )
1944
1959
result , method_type = self .check_op (method , left_type , e .right , e ,
0 commit comments