2Tests handling of the LiteralString special form.
5# Specification: https://typing.readthedocs.io/en/latest/spec/literal.html#literalstring
20variable_annotation: LiteralString
23def my_function(literal_string: LiteralString) -> LiteralString:
24 raise NotImplementedError
28 my_attribute: LiteralString = ""
31type_argument: list[LiteralString]
33T = TypeVar("T", bound=LiteralString)
36bad_union: Literal["hello", LiteralString] # E
[invalid-type-form] Type arguments for `Literal` must be `None`, a literal value (int, bool, str, or bytes), or an enum member
37bad_nesting: Literal[LiteralString] # E
[invalid-type-form] Type arguments for `Literal` must be `None`, a literal value (int, bool, str, or bytes), or an enum member
40def func1(a: Literal["one"], b: Literal["two"]):
43 x2: Literal[""] = b # E
[invalid-assignment] Object of type `Literal["two"]` is not assignable to `Literal[""]`
46def func2(a: LiteralString, b: LiteralString, non_literal: str):
47 # > Addition: x + y is of type LiteralString if both x and y are compatible with LiteralString.
48 assert_type(a + b, LiteralString)
50 # > Joining: sep.join(xs) is of type LiteralString if sep’s type is
51 # > compatible with LiteralString and xs’s type is compatible with Iterable[LiteralString].
52 assert_type(",".join((a, b)), LiteralString)
53 assert_type(",".join((a, non_literal)), str)
55 # > In-place addition: If s has type LiteralString and x has type compatible with
56 # > LiteralString, then s += x preserves s’s type as LiteralString.
60 # > String formatting: An f-string has type LiteralString if and only if its constituent
61 # > expressions are literal strings. s.format(...) has type LiteralString if and only if
62 # > s and the arguments have types compatible with LiteralString.
63 assert_type(f"{a} {b}", LiteralString)
65 x1: LiteralString = f"{a} {non_literal}" # E
[invalid-assignment] Object of type `str` is not assignable to `LiteralString`
67 assert_type(a + non_literal, str)
69 # > LiteralString is compatible with the type str
72 # > Other literal types, such as literal integers, are not compatible with LiteralString.
73 x3: LiteralString = 3 # E
[invalid-assignment] Object of type `Literal[3]` is not assignable to `LiteralString`
74 x4: LiteralString = b"test" # E
[invalid-assignment] Object of type `Literal[b"test"]` is not assignable to `LiteralString`
77# > Conditional statements and expressions work as expected.
78def condition1() -> bool:
79 raise NotImplementedError
82def return_literal_string() -> LiteralString:
83 return "foo" if condition1() else "bar" # OK
86def return_literal_str2(literal_string: LiteralString) -> LiteralString:
87 return "foo" if condition1() else literal_string # OK
90def return_literal_str3() -> LiteralString:
100# > TypeVars can be bound to LiteralString.
101TLiteral = TypeVar("TLiteral", bound=LiteralString)
104def literal_identity(s: TLiteral) -> TLiteral:
108def func3(s: Literal["hello"]):
109 y = literal_identity(s)
110 assert_type(y, Literal["hello"])
113def func4(s: LiteralString):
114 y2 = literal_identity(s)
115 assert_type(y2, LiteralString)
119 literal_identity(s) # E
[invalid-argument-type] Argument to function `literal_identity` is incorrect: Argument type `str` does not satisfy upper bound `LiteralString` of type variable `TLiteral`
122# > LiteralString can be used as a type argument for generic classes.
123class Container(Generic[T]):
124 def __init__(self, value: T) -> None:
128def func6(s: LiteralString):
129 x: Container[LiteralString] = Container(s) # OK
133 x_error: Container[LiteralString] = Container(s) # E
[invalid-assignment] Object of type `Container[T@Container]` is not assignable to `Container[LiteralString]`
[invalid-argument-type] Argument to bound method `__init__` is incorrect: Argument type `str` does not satisfy upper bound `LiteralString` of type variable `T`
[invalid-argument-type] Argument to bound method `__init__` is incorrect: Expected `LiteralString`, found `str`
136# > Standard containers like List work as expected.
137xs: list[LiteralString] = ["foo", "bar", "baz"]
146def func8(x: Literal["foo"]) -> C:
151def func8(x: LiteralString) -> B:
156def func8(x: str) -> A:
160def func8(x: Any) -> Any:
161 raise NotImplementedError
164def call_func8(x: str) -> None:
165 assert_type(func8("foo"), C) # First overload
166 assert_type(func8("bar"), B) # Second overload
167 assert_type(func8(x), A) # Third overload
170def func9(val: list[LiteralString]):
171 x1: list[str] = val # E
[invalid-assignment] Object of type `list[LiteralString]` is not assignable to `list[str]`
174def func10(val: Sequence[LiteralString]):
175 x1: Sequence[str] = val # OK