@@ -1416,19 +1416,19 @@ c: Literal[4]
14161416d: Literal['foo']
14171417e: str
14181418
1419- reveal_type(a + a) # N: Revealed type is "builtins.int "
1419+ reveal_type(a + a) # N: Revealed type is "Literal[6] "
14201420reveal_type(a + b) # N: Revealed type is "builtins.int"
14211421reveal_type(b + a) # N: Revealed type is "builtins.int"
1422- reveal_type(a + 1) # N: Revealed type is "builtins.int "
1423- reveal_type(1 + a) # N: Revealed type is "builtins.int "
1424- reveal_type(a + c) # N: Revealed type is "builtins.int "
1425- reveal_type(c + a) # N: Revealed type is "builtins.int "
1422+ reveal_type(a + 1) # N: Revealed type is "Literal[4] "
1423+ reveal_type(1 + a) # N: Revealed type is "Literal[4] "
1424+ reveal_type(a + c) # N: Revealed type is "Literal[7] "
1425+ reveal_type(c + a) # N: Revealed type is "Literal[7] "
14261426
1427- reveal_type(d + d) # N: Revealed type is "builtins.str "
1427+ reveal_type(d + d) # N: Revealed type is "Literal['foofoo'] "
14281428reveal_type(d + e) # N: Revealed type is "builtins.str"
14291429reveal_type(e + d) # N: Revealed type is "builtins.str"
1430- reveal_type(d + 'foo ') # N: Revealed type is "builtins.str "
1431- reveal_type('foo ' + d) # N: Revealed type is "builtins.str "
1430+ reveal_type(d + 'bar ') # N: Revealed type is "Literal['foobar'] "
1431+ reveal_type('bar ' + d) # N: Revealed type is "Literal['barfoo'] "
14321432
14331433reveal_type(a.__add__(b)) # N: Revealed type is "builtins.int"
14341434reveal_type(b.__add__(a)) # N: Revealed type is "builtins.int"
@@ -2960,3 +2960,87 @@ class C(B[Literal["word"]]):
29602960reveal_type(C().collection) # N: Revealed type is "builtins.list[Literal['word']]"
29612961reveal_type(C().word) # N: Revealed type is "Literal['word']"
29622962[builtins fixtures/tuple.pyi]
2963+
2964+ [case testLiteralAddition]
2965+ from typing import Union
2966+ from typing_extensions import Literal
2967+
2968+ str_a: Literal["a"]
2969+ str_b: Literal["b"]
2970+ str_union_1: Literal["a", "b"]
2971+ str_union_2: Literal["c", "d"]
2972+ s: str
2973+ int_1: Literal[1]
2974+ int_2: Literal[2]
2975+ int_union_1: Literal[1, 2]
2976+ int_union_2: Literal[3, 4]
2977+ i: int
2978+ bytes_a: Literal[b"a"]
2979+ bytes_b: Literal[b"b"]
2980+ bytes_union_1: Literal[b"a", b"b"]
2981+ bytes_union_2: Literal[b"c", b"d"]
2982+ b: bytes
2983+
2984+ misc_union: Literal["a", 1]
2985+
2986+ reveal_type(str_a + str_b) # N: Revealed type is "Literal['ab']"
2987+ reveal_type(str_a + "b") # N: Revealed type is "Literal['ab']"
2988+ reveal_type("a" + str_b) # N: Revealed type is "Literal['ab']"
2989+ reveal_type(str_union_1 + "b") # N: Revealed type is "Union[Literal['ab'], Literal['bb']]"
2990+ reveal_type(str_union_1 + str_b) # N: Revealed type is "Union[Literal['ab'], Literal['bb']]"
2991+ reveal_type("a" + str_union_1) # N: Revealed type is "Union[Literal['aa'], Literal['ab']]"
2992+ reveal_type(str_a + str_union_1) # N: Revealed type is "Union[Literal['aa'], Literal['ab']]"
2993+ reveal_type(str_union_1 + str_union_2) # N: Revealed type is "Union[Literal['ac'], Literal['ad'], Literal['bc'], Literal['bd']]"
2994+ reveal_type(str_a + s) # N: Revealed type is "builtins.str"
2995+ reveal_type(s + str_a) # N: Revealed type is "builtins.str"
2996+ reveal_type(str_union_1 + s) # N: Revealed type is "builtins.str"
2997+ reveal_type(s + str_union_1) # N: Revealed type is "builtins.str"
2998+
2999+ reveal_type(int_1 + int_2) # N: Revealed type is "Literal[3]"
3000+ reveal_type(int_1 + 1) # N: Revealed type is "Literal[2]"
3001+ reveal_type(1 + int_1) # N: Revealed type is "Literal[2]"
3002+ reveal_type(int_union_1 + 1) # N: Revealed type is "Union[Literal[2], Literal[3]]"
3003+ reveal_type(int_union_1 + int_1) # N: Revealed type is "Union[Literal[2], Literal[3]]"
3004+ reveal_type(1 + int_union_1) # N: Revealed type is "Union[Literal[2], Literal[3]]"
3005+ reveal_type(int_1 + int_union_1) # N: Revealed type is "Union[Literal[2], Literal[3]]"
3006+ reveal_type(int_union_1 + int_union_2) # N: Revealed type is "Union[Literal[4], Literal[5], Literal[6]]"
3007+ reveal_type(int_1 + i) # N: Revealed type is "builtins.int"
3008+ reveal_type(i + int_1) # N: Revealed type is "builtins.int"
3009+ reveal_type(int_union_1 + i) # N: Revealed type is "builtins.int"
3010+ reveal_type(i + int_union_1) # N: Revealed type is "builtins.int"
3011+
3012+ reveal_type(bytes_a + bytes_b) # N: Revealed type is "Literal[b'ab']"
3013+ reveal_type(bytes_a + b"b") # N: Revealed type is "Literal[b'ab']"
3014+ reveal_type(b"a" + bytes_b) # N: Revealed type is "Literal[b'ab']"
3015+ reveal_type(bytes_union_1 + b"b") # N: Revealed type is "Union[Literal[b'ab'], Literal[b'bb']]"
3016+ reveal_type(bytes_union_1 + bytes_b) # N: Revealed type is "Union[Literal[b'ab'], Literal[b'bb']]"
3017+ reveal_type(b"a" + bytes_union_1) # N: Revealed type is "Union[Literal[b'aa'], Literal[b'ab']]"
3018+ reveal_type(bytes_a + bytes_union_1) # N: Revealed type is "Union[Literal[b'aa'], Literal[b'ab']]"
3019+ reveal_type(bytes_union_1 + bytes_union_2) # N: Revealed type is "Union[Literal[b'ac'], Literal[b'ad'], Literal[b'bc'], Literal[b'bd']]"
3020+ reveal_type(bytes_a + b) # N: Revealed type is "builtins.bytes"
3021+ reveal_type(b + bytes_a) # N: Revealed type is "builtins.bytes"
3022+ reveal_type(bytes_union_1 + b) # N: Revealed type is "builtins.bytes"
3023+ reveal_type(b + bytes_union_1) # N: Revealed type is "builtins.bytes"
3024+
3025+ reveal_type(misc_union + "a") # N: Revealed type is "Union[builtins.str, builtins.int]" \
3026+ # E: Unsupported operand types for + ("Literal[1]" and "str") \
3027+ # N: Left operand is of type "Literal['a', 1]"
3028+ reveal_type("a" + misc_union) # E: Unsupported operand types for + ("str" and "Literal[1]") \
3029+ # N: Right operand is of type "Literal['a', 1]" \
3030+ # N: Revealed type is "builtins.str"
3031+ [builtins fixtures/primitives.pyi]
3032+
3033+ [case testLiteralAdditionTypedDict]
3034+ from typing import TypedDict
3035+ from typing_extensions import Literal
3036+
3037+ class LookupDict(TypedDict):
3038+ top_var: str
3039+ bottom_var: str
3040+ var: str
3041+
3042+ def func(d: LookupDict, pos: Literal["top_", "bottom_", ""]) -> str:
3043+ return d[pos + "var"]
3044+
3045+ [builtins fixtures/dict.pyi]
3046+ [typing fixtures/typing-typeddict.pyi]
0 commit comments