| -- |
| -- Check to see how we handle raw types, error handling, and other |
| -- semantic analysis shenanigans |
| -- |
| |
| [case testLiteralInvalidString] |
| from typing_extensions import Literal |
| def f1(x: 'A[') -> None: pass # E: Invalid type comment or annotation |
| def g1(x: Literal['A[']) -> None: pass |
| reveal_type(f1) # N: Revealed type is "def (x: Any)" |
| reveal_type(g1) # N: Revealed type is "def (x: Literal['A['])" |
| |
| def f2(x: 'A B') -> None: pass # E: Invalid type comment or annotation |
| def g2(x: Literal['A B']) -> None: pass |
| reveal_type(f2) # N: Revealed type is "def (x: Any)" |
| reveal_type(g2) # N: Revealed type is "def (x: Literal['A B'])" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInvalidTypeComment] |
| from typing_extensions import Literal |
| def f(x): # E: syntax error in type comment "(A[) -> None" |
| # type: (A[) -> None |
| pass |
| |
| [case testLiteralInvalidTypeComment2] |
| from typing_extensions import Literal |
| def f(x): # E: Invalid type comment or annotation |
| # type: ("A[") -> None |
| pass |
| |
| def g(x): |
| # type: (Literal["A["]) -> None |
| pass |
| |
| reveal_type(f) # N: Revealed type is "def (x: Any)" |
| reveal_type(g) # N: Revealed type is "def (x: Literal['A['])" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralFromTypingWorks] |
| from typing import Literal |
| |
| x: Literal[42] |
| x = 43 # E: Incompatible types in assignment (expression has type "Literal[43]", variable has type "Literal[42]") |
| |
| y: Literal[43] |
| y = 43 |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testLiteralParsingPython2] |
| # flags: --python-version 2.7 |
| from typing import Optional |
| from typing_extensions import Literal |
| |
| def f(x): # E: Invalid type comment or annotation |
| # type: ("A[") -> None |
| pass |
| |
| def g(x): |
| # type: (Literal["A["]) -> None |
| pass |
| |
| x = None # type: Optional[1] # E: Invalid type: try using Literal[1] instead? |
| y = None # type: Optional[Literal[1]] |
| |
| reveal_type(x) # N: Revealed type is "Union[Any, None]" |
| reveal_type(y) # N: Revealed type is "Union[Literal[1], None]" |
| [out] |
| |
| [case testLiteralInsideOtherTypes] |
| from typing import Tuple |
| from typing_extensions import Literal |
| |
| x: Tuple[1] # E: Invalid type: try using Literal[1] instead? |
| def foo(x: Tuple[1]) -> None: ... # E: Invalid type: try using Literal[1] instead? |
| |
| y: Tuple[Literal[2]] |
| def bar(x: Tuple[Literal[2]]) -> None: ... |
| reveal_type(x) # N: Revealed type is "Tuple[Any]" |
| reveal_type(y) # N: Revealed type is "Tuple[Literal[2]]" |
| reveal_type(bar) # N: Revealed type is "def (x: Tuple[Literal[2]])" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInsideOtherTypesPython2] |
| # flags: --python-version 2.7 |
| from typing import Tuple, Optional |
| from typing_extensions import Literal |
| |
| x = None # type: Optional[Tuple[1]] # E: Invalid type: try using Literal[1] instead? |
| def foo(x): # E: Invalid type: try using Literal[1] instead? |
| # type: (Tuple[1]) -> None |
| pass |
| |
| y = None # type: Optional[Tuple[Literal[2]]] |
| def bar(x): |
| # type: (Tuple[Literal[2]]) -> None |
| pass |
| reveal_type(x) # N: Revealed type is "Union[Tuple[Any], None]" |
| reveal_type(y) # N: Revealed type is "Union[Tuple[Literal[2]], None]" |
| reveal_type(bar) # N: Revealed type is "def (x: Tuple[Literal[2]])" |
| [out] |
| |
| [case testLiteralInsideOtherTypesTypeCommentsPython3] |
| # flags: --python-version 3.7 |
| from typing import Tuple, Optional |
| from typing_extensions import Literal |
| |
| x = None # type: Optional[Tuple[1]] # E: Invalid type: try using Literal[1] instead? |
| def foo(x): # E: Invalid type: try using Literal[1] instead? |
| # type: (Tuple[1]) -> None |
| pass |
| |
| y = None # type: Optional[Tuple[Literal[2]]] |
| def bar(x): |
| # type: (Tuple[Literal[2]]) -> None |
| pass |
| reveal_type(x) # N: Revealed type is "Union[Tuple[Any], None]" |
| reveal_type(y) # N: Revealed type is "Union[Tuple[Literal[2]], None]" |
| reveal_type(bar) # N: Revealed type is "def (x: Tuple[Literal[2]])" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralValidExpressionsInStringsPython3] |
| from wrapper import * |
| |
| [file wrapper.pyi] |
| from typing_extensions import Literal |
| |
| alias_1 = Literal['a+b'] |
| alias_2 = Literal['1+2'] |
| alias_3 = Literal['3'] |
| alias_4 = Literal['True'] |
| alias_5 = Literal['None'] |
| alias_6 = Literal['"foo"'] |
| expr_of_alias_1: alias_1 |
| expr_of_alias_2: alias_2 |
| expr_of_alias_3: alias_3 |
| expr_of_alias_4: alias_4 |
| expr_of_alias_5: alias_5 |
| expr_of_alias_6: alias_6 |
| reveal_type(expr_of_alias_1) # N: Revealed type is "Literal['a+b']" |
| reveal_type(expr_of_alias_2) # N: Revealed type is "Literal['1+2']" |
| reveal_type(expr_of_alias_3) # N: Revealed type is "Literal['3']" |
| reveal_type(expr_of_alias_4) # N: Revealed type is "Literal['True']" |
| reveal_type(expr_of_alias_5) # N: Revealed type is "Literal['None']" |
| reveal_type(expr_of_alias_6) # N: Revealed type is "Literal['"foo"']" |
| |
| expr_ann_1: Literal['a+b'] |
| expr_ann_2: Literal['1+2'] |
| expr_ann_3: Literal['3'] |
| expr_ann_4: Literal['True'] |
| expr_ann_5: Literal['None'] |
| expr_ann_6: Literal['"foo"'] |
| reveal_type(expr_ann_1) # N: Revealed type is "Literal['a+b']" |
| reveal_type(expr_ann_2) # N: Revealed type is "Literal['1+2']" |
| reveal_type(expr_ann_3) # N: Revealed type is "Literal['3']" |
| reveal_type(expr_ann_4) # N: Revealed type is "Literal['True']" |
| reveal_type(expr_ann_5) # N: Revealed type is "Literal['None']" |
| reveal_type(expr_ann_6) # N: Revealed type is "Literal['"foo"']" |
| |
| expr_str_1: "Literal['a+b']" |
| expr_str_2: "Literal['1+2']" |
| expr_str_3: "Literal['3']" |
| expr_str_4: "Literal['True']" |
| expr_str_5: "Literal['None']" |
| expr_str_6: "Literal['\"foo\"']" |
| reveal_type(expr_str_1) # N: Revealed type is "Literal['a+b']" |
| reveal_type(expr_str_2) # N: Revealed type is "Literal['1+2']" |
| reveal_type(expr_str_3) # N: Revealed type is "Literal['3']" |
| reveal_type(expr_str_4) # N: Revealed type is "Literal['True']" |
| reveal_type(expr_str_5) # N: Revealed type is "Literal['None']" |
| reveal_type(expr_str_6) # N: Revealed type is "Literal['"foo"']" |
| |
| expr_com_1 = ... # type: Literal['a+b'] |
| expr_com_2 = ... # type: Literal['1+2'] |
| expr_com_3 = ... # type: Literal['3'] |
| expr_com_4 = ... # type: Literal['True'] |
| expr_com_5 = ... # type: Literal['None'] |
| expr_com_6 = ... # type: Literal['"foo"'] |
| reveal_type(expr_com_1) # N: Revealed type is "Literal['a+b']" |
| reveal_type(expr_com_2) # N: Revealed type is "Literal['1+2']" |
| reveal_type(expr_com_3) # N: Revealed type is "Literal['3']" |
| reveal_type(expr_com_4) # N: Revealed type is "Literal['True']" |
| reveal_type(expr_com_5) # N: Revealed type is "Literal['None']" |
| reveal_type(expr_com_6) # N: Revealed type is "Literal['"foo"']" |
| [builtins fixtures/bool.pyi] |
| [out] |
| |
| [case testLiteralValidExpressionsInStringsPython2] |
| # flags: --python-version=2.7 |
| from wrapper import * |
| |
| [file wrapper.pyi] |
| from typing_extensions import Literal |
| |
| alias_1 = Literal['a+b'] |
| alias_2 = Literal['1+2'] |
| alias_3 = Literal['3'] |
| alias_4 = Literal['True'] |
| alias_5 = Literal['None'] |
| alias_6 = Literal['"foo"'] |
| expr_of_alias_1: alias_1 |
| expr_of_alias_2: alias_2 |
| expr_of_alias_3: alias_3 |
| expr_of_alias_4: alias_4 |
| expr_of_alias_5: alias_5 |
| expr_of_alias_6: alias_6 |
| reveal_type(expr_of_alias_1) # N: Revealed type is "Literal['a+b']" |
| reveal_type(expr_of_alias_2) # N: Revealed type is "Literal['1+2']" |
| reveal_type(expr_of_alias_3) # N: Revealed type is "Literal['3']" |
| reveal_type(expr_of_alias_4) # N: Revealed type is "Literal['True']" |
| reveal_type(expr_of_alias_5) # N: Revealed type is "Literal['None']" |
| reveal_type(expr_of_alias_6) # N: Revealed type is "Literal['"foo"']" |
| |
| expr_com_1 = ... # type: Literal['a+b'] |
| expr_com_2 = ... # type: Literal['1+2'] |
| expr_com_3 = ... # type: Literal['3'] |
| expr_com_4 = ... # type: Literal['True'] |
| expr_com_5 = ... # type: Literal['None'] |
| expr_com_6 = ... # type: Literal['"foo"'] |
| reveal_type(expr_com_1) # N: Revealed type is "Literal[u'a+b']" |
| reveal_type(expr_com_2) # N: Revealed type is "Literal[u'1+2']" |
| reveal_type(expr_com_3) # N: Revealed type is "Literal[u'3']" |
| reveal_type(expr_com_4) # N: Revealed type is "Literal[u'True']" |
| reveal_type(expr_com_5) # N: Revealed type is "Literal[u'None']" |
| reveal_type(expr_com_6) # N: Revealed type is "Literal[u'"foo"']" |
| [builtins fixtures/bool.pyi] |
| [out] |
| |
| [case testLiteralMixingUnicodeAndBytesPython3] |
| from typing_extensions import Literal |
| |
| a_ann: Literal[u"foo"] |
| b_ann: Literal["foo"] |
| c_ann: Literal[b"foo"] |
| |
| a_hint = u"foo" # type: Literal[u"foo"] |
| b_hint = "foo" # type: Literal["foo"] |
| c_hint = b"foo" # type: Literal[b"foo"] |
| |
| AAlias = Literal[u"foo"] |
| BAlias = Literal["foo"] |
| CAlias = Literal[b"foo"] |
| a_alias: AAlias |
| b_alias: BAlias |
| c_alias: CAlias |
| |
| def accepts_str_1(x: Literal[u"foo"]) -> None: pass |
| def accepts_str_2(x: Literal["foo"]) -> None: pass |
| def accepts_bytes(x: Literal[b"foo"]) -> None: pass |
| |
| reveal_type(a_ann) # N: Revealed type is "Literal['foo']" |
| reveal_type(b_ann) # N: Revealed type is "Literal['foo']" |
| reveal_type(c_ann) # N: Revealed type is "Literal[b'foo']" |
| reveal_type(a_hint) # N: Revealed type is "Literal['foo']" |
| reveal_type(b_hint) # N: Revealed type is "Literal['foo']" |
| reveal_type(c_hint) # N: Revealed type is "Literal[b'foo']" |
| reveal_type(a_alias) # N: Revealed type is "Literal['foo']" |
| reveal_type(b_alias) # N: Revealed type is "Literal['foo']" |
| reveal_type(c_alias) # N: Revealed type is "Literal[b'foo']" |
| |
| accepts_str_1(a_ann) |
| accepts_str_1(b_ann) |
| accepts_str_1(c_ann) # E: Argument 1 to "accepts_str_1" has incompatible type "Literal[b'foo']"; expected "Literal['foo']" |
| accepts_str_1(a_hint) |
| accepts_str_1(b_hint) |
| accepts_str_1(c_hint) # E: Argument 1 to "accepts_str_1" has incompatible type "Literal[b'foo']"; expected "Literal['foo']" |
| accepts_str_1(a_alias) |
| accepts_str_1(b_alias) |
| accepts_str_1(c_alias) # E: Argument 1 to "accepts_str_1" has incompatible type "Literal[b'foo']"; expected "Literal['foo']" |
| |
| accepts_str_2(a_ann) |
| accepts_str_2(b_ann) |
| accepts_str_2(c_ann) # E: Argument 1 to "accepts_str_2" has incompatible type "Literal[b'foo']"; expected "Literal['foo']" |
| accepts_str_2(a_hint) |
| accepts_str_2(b_hint) |
| accepts_str_2(c_hint) # E: Argument 1 to "accepts_str_2" has incompatible type "Literal[b'foo']"; expected "Literal['foo']" |
| accepts_str_2(a_alias) |
| accepts_str_2(b_alias) |
| accepts_str_2(c_alias) # E: Argument 1 to "accepts_str_2" has incompatible type "Literal[b'foo']"; expected "Literal['foo']" |
| |
| accepts_bytes(a_ann) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" |
| accepts_bytes(b_ann) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" |
| accepts_bytes(c_ann) |
| accepts_bytes(a_hint) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" |
| accepts_bytes(b_hint) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" |
| accepts_bytes(c_hint) |
| accepts_bytes(a_alias) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" |
| accepts_bytes(b_alias) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" |
| accepts_bytes(c_alias) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralMixingUnicodeAndBytesPython2] |
| # flags: --python-version 2.7 |
| from typing_extensions import Literal |
| |
| a_hint = u"foo" # type: Literal[u"foo"] |
| b_hint = "foo" # type: Literal["foo"] |
| c_hint = b"foo" # type: Literal[b"foo"] |
| |
| AAlias = Literal[u"foo"] |
| BAlias = Literal["foo"] |
| CAlias = Literal[b"foo"] |
| a_alias = u"foo" # type: AAlias |
| b_alias = "foo" # type: BAlias |
| c_alias = b"foo" # type: CAlias |
| |
| def accepts_unicode(x): |
| # type: (Literal[u"foo"]) -> None |
| pass |
| def accepts_bytes_1(x): |
| # type: (Literal["foo"]) -> None |
| pass |
| def accepts_bytes_2(x): |
| # type: (Literal[b"foo"]) -> None |
| pass |
| |
| reveal_type(a_hint) # N: Revealed type is "Literal[u'foo']" |
| reveal_type(b_hint) # N: Revealed type is "Literal['foo']" |
| reveal_type(c_hint) # N: Revealed type is "Literal['foo']" |
| reveal_type(a_alias) # N: Revealed type is "Literal[u'foo']" |
| reveal_type(b_alias) # N: Revealed type is "Literal['foo']" |
| reveal_type(c_alias) # N: Revealed type is "Literal['foo']" |
| |
| accepts_unicode(a_hint) |
| accepts_unicode(b_hint) # E: Argument 1 to "accepts_unicode" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| accepts_unicode(c_hint) # E: Argument 1 to "accepts_unicode" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| accepts_unicode(a_alias) |
| accepts_unicode(b_alias) # E: Argument 1 to "accepts_unicode" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| accepts_unicode(c_alias) # E: Argument 1 to "accepts_unicode" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| |
| accepts_bytes_1(a_hint) # E: Argument 1 to "accepts_bytes_1" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes_1(b_hint) |
| accepts_bytes_1(c_hint) |
| accepts_bytes_1(a_alias) # E: Argument 1 to "accepts_bytes_1" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes_1(b_alias) |
| accepts_bytes_1(c_alias) |
| |
| accepts_bytes_2(a_hint) # E: Argument 1 to "accepts_bytes_2" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes_2(b_hint) |
| accepts_bytes_2(c_hint) |
| accepts_bytes_2(a_alias) # E: Argument 1 to "accepts_bytes_2" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes_2(b_alias) |
| accepts_bytes_2(c_alias) |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralMixingUnicodeAndBytesPython2UnicodeLiterals] |
| # flags: --python-version 2.7 |
| from __future__ import unicode_literals |
| from typing_extensions import Literal |
| |
| a_hint = u"foo" # type: Literal[u"foo"] |
| b_hint = "foo" # type: Literal["foo"] |
| c_hint = b"foo" # type: Literal[b"foo"] |
| |
| AAlias = Literal[u"foo"] |
| BAlias = Literal["foo"] |
| CAlias = Literal[b"foo"] |
| a_alias = u"foo" # type: AAlias |
| b_alias = "foo" # type: BAlias |
| c_alias = b"foo" # type: CAlias |
| |
| def accepts_unicode_1(x): |
| # type: (Literal[u"foo"]) -> None |
| pass |
| def accepts_unicode_2(x): |
| # type: (Literal["foo"]) -> None |
| pass |
| def accepts_bytes(x): |
| # type: (Literal[b"foo"]) -> None |
| pass |
| |
| reveal_type(a_hint) # N: Revealed type is "Literal[u'foo']" |
| reveal_type(b_hint) # N: Revealed type is "Literal[u'foo']" |
| reveal_type(c_hint) # N: Revealed type is "Literal['foo']" |
| reveal_type(a_alias) # N: Revealed type is "Literal[u'foo']" |
| reveal_type(b_alias) # N: Revealed type is "Literal[u'foo']" |
| reveal_type(c_alias) # N: Revealed type is "Literal['foo']" |
| |
| accepts_unicode_1(a_hint) |
| accepts_unicode_1(b_hint) |
| accepts_unicode_1(c_hint) # E: Argument 1 to "accepts_unicode_1" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| accepts_unicode_1(a_alias) |
| accepts_unicode_1(b_alias) |
| accepts_unicode_1(c_alias) # E: Argument 1 to "accepts_unicode_1" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| |
| accepts_unicode_2(a_hint) |
| accepts_unicode_2(b_hint) |
| accepts_unicode_2(c_hint) # E: Argument 1 to "accepts_unicode_2" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| accepts_unicode_2(a_alias) |
| accepts_unicode_2(b_alias) |
| accepts_unicode_2(c_alias) # E: Argument 1 to "accepts_unicode_2" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| |
| accepts_bytes(a_hint) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes(b_hint) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes(c_hint) |
| accepts_bytes(a_alias) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes(b_alias) # E: Argument 1 to "accepts_bytes" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| accepts_bytes(c_alias) |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralMixingUnicodeAndBytesPython3ForwardStrings] |
| from typing import TypeVar, Generic |
| from typing_extensions import Literal |
| |
| a_unicode_wrapper: u"Literal[u'foo']" |
| b_unicode_wrapper: u"Literal['foo']" |
| c_unicode_wrapper: u"Literal[b'foo']" |
| |
| a_str_wrapper: "Literal[u'foo']" |
| b_str_wrapper: "Literal['foo']" |
| c_str_wrapper: "Literal[b'foo']" |
| |
| # In Python 3, forward references MUST be str, not bytes |
| a_bytes_wrapper: b"Literal[u'foo']" # E: Invalid type comment or annotation |
| b_bytes_wrapper: b"Literal['foo']" # E: Invalid type comment or annotation |
| c_bytes_wrapper: b"Literal[b'foo']" # E: Invalid type comment or annotation |
| |
| reveal_type(a_unicode_wrapper) # N: Revealed type is "Literal['foo']" |
| reveal_type(b_unicode_wrapper) # N: Revealed type is "Literal['foo']" |
| reveal_type(c_unicode_wrapper) # N: Revealed type is "Literal[b'foo']" |
| |
| reveal_type(a_str_wrapper) # N: Revealed type is "Literal['foo']" |
| reveal_type(b_str_wrapper) # N: Revealed type is "Literal['foo']" |
| reveal_type(c_str_wrapper) # N: Revealed type is "Literal[b'foo']" |
| |
| T = TypeVar('T') |
| class Wrap(Generic[T]): pass |
| |
| AUnicodeWrapperAlias = Wrap[u"Literal[u'foo']"] |
| BUnicodeWrapperAlias = Wrap[u"Literal['foo']"] |
| CUnicodeWrapperAlias = Wrap[u"Literal[b'foo']"] |
| a_unicode_wrapper_alias: AUnicodeWrapperAlias |
| b_unicode_wrapper_alias: BUnicodeWrapperAlias |
| c_unicode_wrapper_alias: CUnicodeWrapperAlias |
| |
| AStrWrapperAlias = Wrap["Literal[u'foo']"] |
| BStrWrapperAlias = Wrap["Literal['foo']"] |
| CStrWrapperAlias = Wrap["Literal[b'foo']"] |
| a_str_wrapper_alias: AStrWrapperAlias |
| b_str_wrapper_alias: BStrWrapperAlias |
| c_str_wrapper_alias: CStrWrapperAlias |
| |
| ABytesWrapperAlias = Wrap[b"Literal[u'foo']"] |
| BBytesWrapperAlias = Wrap[b"Literal['foo']"] |
| CBytesWrapperAlias = Wrap[b"Literal[b'foo']"] |
| a_bytes_wrapper_alias: ABytesWrapperAlias |
| b_bytes_wrapper_alias: BBytesWrapperAlias |
| c_bytes_wrapper_alias: CBytesWrapperAlias |
| |
| # In Python 3, we assume that Literal['foo'] and Literal[u'foo'] are always |
| # equivalent, no matter what. |
| reveal_type(a_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(b_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(c_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[b'foo']]" |
| |
| reveal_type(a_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(b_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(c_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[b'foo']]" |
| |
| reveal_type(a_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(b_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(c_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[b'foo']]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralMixingUnicodeAndBytesPython2ForwardStrings] |
| # flags: --python-version 2.7 |
| from typing import TypeVar, Generic |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| class Wrap(Generic[T]): pass |
| |
| AUnicodeWrapperAlias = Wrap[u"Literal[u'foo']"] |
| BUnicodeWrapperAlias = Wrap[u"Literal['foo']"] |
| CUnicodeWrapperAlias = Wrap[u"Literal[b'foo']"] |
| a_unicode_wrapper_alias = Wrap() # type: AUnicodeWrapperAlias |
| b_unicode_wrapper_alias = Wrap() # type: BUnicodeWrapperAlias |
| c_unicode_wrapper_alias = Wrap() # type: CUnicodeWrapperAlias |
| |
| AStrWrapperAlias = Wrap["Literal[u'foo']"] |
| BStrWrapperAlias = Wrap["Literal['foo']"] |
| CStrWrapperAlias = Wrap["Literal[b'foo']"] |
| a_str_wrapper_alias = Wrap() # type: AStrWrapperAlias |
| b_str_wrapper_alias = Wrap() # type: BStrWrapperAlias |
| c_str_wrapper_alias = Wrap() # type: CStrWrapperAlias |
| |
| ABytesWrapperAlias = Wrap[b"Literal[u'foo']"] |
| BBytesWrapperAlias = Wrap[b"Literal['foo']"] |
| CBytesWrapperAlias = Wrap[b"Literal[b'foo']"] |
| a_bytes_wrapper_alias = Wrap() # type: ABytesWrapperAlias |
| b_bytes_wrapper_alias = Wrap() # type: BBytesWrapperAlias |
| c_bytes_wrapper_alias = Wrap() # type: CBytesWrapperAlias |
| |
| # Unlike Python 3, the exact meaning of Literal['foo'] is "inherited" from the "outer" |
| # string. For example, the "outer" string is unicode in the first example here. So |
| # we treat Literal['foo'] as the same as Literal[u'foo']. |
| reveal_type(a_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(b_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(c_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| |
| # However, for both of these examples, the "outer" string is bytes, so we don't treat |
| # Literal['foo'] as a unicode Literal. |
| reveal_type(a_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(b_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(c_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| |
| reveal_type(a_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(b_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(c_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| [out] |
| |
| [case testLiteralMixingUnicodeAndBytesPython2ForwardStringsUnicodeLiterals] |
| # flags: --python-version 2.7 |
| from __future__ import unicode_literals |
| from typing import TypeVar, Generic |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| class Wrap(Generic[T]): pass |
| |
| AUnicodeWrapperAlias = Wrap[u"Literal[u'foo']"] |
| BUnicodeWrapperAlias = Wrap[u"Literal['foo']"] |
| CUnicodeWrapperAlias = Wrap[u"Literal[b'foo']"] |
| a_unicode_wrapper_alias = Wrap() # type: AUnicodeWrapperAlias |
| b_unicode_wrapper_alias = Wrap() # type: BUnicodeWrapperAlias |
| c_unicode_wrapper_alias = Wrap() # type: CUnicodeWrapperAlias |
| |
| AStrWrapperAlias = Wrap["Literal[u'foo']"] |
| BStrWrapperAlias = Wrap["Literal['foo']"] |
| CStrWrapperAlias = Wrap["Literal[b'foo']"] |
| a_str_wrapper_alias = Wrap() # type: AStrWrapperAlias |
| b_str_wrapper_alias = Wrap() # type: BStrWrapperAlias |
| c_str_wrapper_alias = Wrap() # type: CStrWrapperAlias |
| |
| ABytesWrapperAlias = Wrap[b"Literal[u'foo']"] |
| BBytesWrapperAlias = Wrap[b"Literal['foo']"] |
| CBytesWrapperAlias = Wrap[b"Literal[b'foo']"] |
| a_bytes_wrapper_alias = Wrap() # type: ABytesWrapperAlias |
| b_bytes_wrapper_alias = Wrap() # type: BBytesWrapperAlias |
| c_bytes_wrapper_alias = Wrap() # type: CBytesWrapperAlias |
| |
| # This example is almost identical to the previous one, except that we're using |
| # unicode literals. The first and last examples remain the same, but the middle |
| # one changes: |
| reveal_type(a_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(b_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(c_unicode_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| |
| # Since unicode_literals is enabled, the "outer" string in Wrap["Literal['foo']"] is now |
| # a unicode string, so we end up treating Literal['foo'] as the same as Literal[u'foo']. |
| reveal_type(a_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(b_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(c_str_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| |
| reveal_type(a_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal[u'foo']]" |
| reveal_type(b_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| reveal_type(c_bytes_wrapper_alias) # N: Revealed type is "__main__.Wrap[Literal['foo']]" |
| [out] |
| |
| [case testLiteralMixingUnicodeAndBytesInconsistentUnicodeLiterals] |
| # flags: --python-version 2.7 |
| import mod_unicode as u |
| import mod_bytes as b |
| |
| reveal_type(u.func) # N: Revealed type is "def (x: Literal[u'foo'])" |
| reveal_type(u.var) # N: Revealed type is "Literal[u'foo']" |
| reveal_type(b.func) # N: Revealed type is "def (x: Literal['foo'])" |
| reveal_type(b.var) # N: Revealed type is "Literal['foo']" |
| |
| from_u = u"foo" # type: u.Alias |
| from_b = "foo" # type: b.Alias |
| |
| u.func(u.var) |
| u.func(from_u) |
| u.func(b.var) # E: Argument 1 to "func" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| u.func(from_b) # E: Argument 1 to "func" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" |
| |
| b.func(u.var) # E: Argument 1 to "func" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| b.func(from_u) # E: Argument 1 to "func" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" |
| b.func(b.var) |
| b.func(from_b) |
| |
| [file mod_unicode.py] |
| from __future__ import unicode_literals |
| from typing_extensions import Literal |
| |
| def func(x): |
| # type: (Literal["foo"]) -> None |
| pass |
| |
| Alias = Literal["foo"] |
| var = "foo" # type: Alias |
| |
| [file mod_bytes.py] |
| from typing_extensions import Literal |
| |
| def func(x): |
| # type: (Literal["foo"]) -> None |
| pass |
| |
| Alias = Literal["foo"] |
| var = "foo" # type: Alias |
| [out] |
| |
| [case testLiteralUnicodeWeirdCharacters] |
| from typing import Any |
| from typing_extensions import Literal |
| |
| a1: Literal["\x00\xAC\x62 \u2227 \u03bb(p)"] |
| b1: Literal["\x00¬b ∧ λ(p)"] |
| c1: Literal["¬b ∧ λ(p)"] |
| d1: Literal["\U0001F600"] |
| e1: Literal["😀"] |
| |
| Alias1 = Literal["\x00\xAC\x62 \u2227 \u03bb(p)"] |
| Alias2 = Literal["\x00¬b ∧ λ(p)"] |
| Alias3 = Literal["¬b ∧ λ(p)"] |
| Alias4 = Literal["\U0001F600"] |
| Alias5 = Literal["😀"] |
| a2: Alias1 |
| b2: Alias2 |
| c2: Alias3 |
| d2: Alias4 |
| e2: Alias5 |
| |
| blah: Any |
| a3 = blah # type: Literal["\x00\xAC\x62 \u2227 \u03bb(p)"] |
| b3 = blah # type: Literal["\x00¬b ∧ λ(p)"] |
| c3 = blah # type: Literal["¬b ∧ λ(p)"] |
| d3 = blah # type: Literal["\U0001F600"] |
| e3 = blah # type: Literal["😀"] |
| |
| reveal_type(a1) # N: Revealed type is "Literal['\x00¬b ∧ λ(p)']" |
| reveal_type(b1) # N: Revealed type is "Literal['\x00¬b ∧ λ(p)']" |
| reveal_type(c1) # N: Revealed type is "Literal['¬b ∧ λ(p)']" |
| reveal_type(d1) # N: Revealed type is "Literal['😀']" |
| reveal_type(e1) # N: Revealed type is "Literal['😀']" |
| |
| reveal_type(a2) # N: Revealed type is "Literal['\x00¬b ∧ λ(p)']" |
| reveal_type(b2) # N: Revealed type is "Literal['\x00¬b ∧ λ(p)']" |
| reveal_type(c2) # N: Revealed type is "Literal['¬b ∧ λ(p)']" |
| reveal_type(d2) # N: Revealed type is "Literal['😀']" |
| reveal_type(e2) # N: Revealed type is "Literal['😀']" |
| |
| reveal_type(a3) # N: Revealed type is "Literal['\x00¬b ∧ λ(p)']" |
| reveal_type(b3) # N: Revealed type is "Literal['\x00¬b ∧ λ(p)']" |
| reveal_type(c3) # N: Revealed type is "Literal['¬b ∧ λ(p)']" |
| reveal_type(d3) # N: Revealed type is "Literal['😀']" |
| reveal_type(e3) # N: Revealed type is "Literal['😀']" |
| |
| a1 = b1 |
| a1 = c1 # E: Incompatible types in assignment (expression has type "Literal['¬b ∧ λ(p)']", variable has type "Literal['\x00¬b ∧ λ(p)']") |
| a1 = a2 |
| a1 = b2 |
| a1 = c2 # E: Incompatible types in assignment (expression has type "Literal['¬b ∧ λ(p)']", variable has type "Literal['\x00¬b ∧ λ(p)']") |
| a1 = a3 |
| a1 = b3 |
| a1 = c3 # E: Incompatible types in assignment (expression has type "Literal['¬b ∧ λ(p)']", variable has type "Literal['\x00¬b ∧ λ(p)']") |
| [builtins fixtures/tuple.pyi] |
| |
| [out skip-path-normalization] |
| |
| [case testLiteralRenamingImportWorks] |
| from typing_extensions import Literal as Foo |
| |
| x: Foo[3] |
| reveal_type(x) # N: Revealed type is "Literal[3]" |
| |
| y: Foo["hello"] |
| reveal_type(y) # N: Revealed type is "Literal['hello']" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralRenamingImportViaAnotherImportWorks] |
| from other_module import Foo, Bar |
| |
| x: Foo[3] |
| y: Bar |
| |
| reveal_type(x) # N: Revealed type is "Literal[3]" |
| reveal_type(y) # N: Revealed type is "Literal[4]" |
| |
| [file other_module.py] |
| from typing_extensions import Literal as Foo |
| Bar = Foo[4] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralRenamingImportNameConfusion] |
| from typing_extensions import Literal as Foo |
| |
| x: Foo["Foo"] |
| reveal_type(x) # N: Revealed type is "Literal['Foo']" |
| |
| y: Foo[Foo] # E: Literal[...] must have at least one parameter |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralBadRawExpressionWithBadType] |
| |
| NotAType = 3 |
| def f() -> NotAType['also' + 'not' + 'a' + 'type']: ... # E: Variable "__main__.NotAType" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases \ |
| # E: Invalid type comment or annotation |
| |
| # Note: this makes us re-inspect the type (e.g. via '_patch_indirect_dependencies' |
| # in build.py) so we can confirm the RawExpressionType did not leak out. |
| indirect = f() |
| [out] |
| |
| -- |
| -- Check to make sure we can construct the correct range of literal |
| -- types (and correctly reject invalid literal types) |
| -- |
| -- Note: the assignment tests exercise the logic in 'fastparse.py'; |
| -- the type alias tests exercise the logic in 'exprtotype.py'. |
| -- |
| |
| [case testLiteralBasicIntUsage] |
| from typing_extensions import Literal |
| |
| a1: Literal[4] |
| b1: Literal[0x2a] |
| c1: Literal[-300] |
| |
| reveal_type(a1) # N: Revealed type is "Literal[4]" |
| reveal_type(b1) # N: Revealed type is "Literal[42]" |
| reveal_type(c1) # N: Revealed type is "Literal[-300]" |
| |
| a2t = Literal[4] |
| b2t = Literal[0x2a] |
| c2t = Literal[-300] |
| a2: a2t |
| b2: b2t |
| c2: c2t |
| |
| reveal_type(a2) # N: Revealed type is "Literal[4]" |
| reveal_type(b2) # N: Revealed type is "Literal[42]" |
| reveal_type(c2) # N: Revealed type is "Literal[-300]" |
| |
| def f1(x: Literal[4]) -> Literal[4]: pass |
| def f2(x: Literal[0x2a]) -> Literal[0x2a]: pass |
| def f3(x: Literal[-300]) -> Literal[-300]: pass |
| |
| reveal_type(f1) # N: Revealed type is "def (x: Literal[4]) -> Literal[4]" |
| reveal_type(f2) # N: Revealed type is "def (x: Literal[42]) -> Literal[42]" |
| reveal_type(f3) # N: Revealed type is "def (x: Literal[-300]) -> Literal[-300]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralBasicBoolUsage] |
| from typing_extensions import Literal |
| |
| a1: Literal[True] |
| b1: Literal[False] |
| |
| reveal_type(a1) # N: Revealed type is "Literal[True]" |
| reveal_type(b1) # N: Revealed type is "Literal[False]" |
| |
| a2t = Literal[True] |
| b2t = Literal[False] |
| a2: a2t |
| b2: b2t |
| |
| reveal_type(a2) # N: Revealed type is "Literal[True]" |
| reveal_type(b2) # N: Revealed type is "Literal[False]" |
| |
| def f1(x: Literal[True]) -> Literal[True]: pass |
| def f2(x: Literal[False]) -> Literal[False]: pass |
| |
| reveal_type(f1) # N: Revealed type is "def (x: Literal[True]) -> Literal[True]" |
| reveal_type(f2) # N: Revealed type is "def (x: Literal[False]) -> Literal[False]" |
| [builtins fixtures/bool.pyi] |
| [out] |
| |
| [case testLiteralBasicStrUsage] |
| from typing_extensions import Literal |
| |
| a: Literal[""] |
| b: Literal[" foo bar "] |
| c: Literal[' foo bar '] |
| d: Literal["foo"] |
| e: Literal['foo'] |
| |
| reveal_type(a) # N: Revealed type is "Literal['']" |
| reveal_type(b) # N: Revealed type is "Literal[' foo bar ']" |
| reveal_type(c) # N: Revealed type is "Literal[' foo bar ']" |
| reveal_type(d) # N: Revealed type is "Literal['foo']" |
| reveal_type(e) # N: Revealed type is "Literal['foo']" |
| |
| def f1(x: Literal[""]) -> Literal[""]: pass |
| def f2(x: Literal[" foo bar "]) -> Literal[" foo bar "]: pass |
| def f3(x: Literal[' foo bar ']) -> Literal[' foo bar ']: pass |
| def f4(x: Literal["foo"]) -> Literal["foo"]: pass |
| def f5(x: Literal['foo']) -> Literal['foo']: pass |
| |
| reveal_type(f1) # N: Revealed type is "def (x: Literal['']) -> Literal['']" |
| reveal_type(f2) # N: Revealed type is "def (x: Literal[' foo bar ']) -> Literal[' foo bar ']" |
| reveal_type(f3) # N: Revealed type is "def (x: Literal[' foo bar ']) -> Literal[' foo bar ']" |
| reveal_type(f4) # N: Revealed type is "def (x: Literal['foo']) -> Literal['foo']" |
| reveal_type(f5) # N: Revealed type is "def (x: Literal['foo']) -> Literal['foo']" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralBasicStrUsageSlashes] |
| from typing_extensions import Literal |
| |
| a: Literal[r"foo\nbar"] |
| b: Literal["foo\nbar"] |
| |
| reveal_type(a) |
| reveal_type(b) |
| [builtins fixtures/tuple.pyi] |
| [out skip-path-normalization] |
| main:6: note: Revealed type is "Literal['foo\\nbar']" |
| main:7: note: Revealed type is "Literal['foo\nbar']" |
| |
| [case testLiteralBasicNoneUsage] |
| # Note: Literal[None] and None are equivalent |
| from typing_extensions import Literal |
| a: Literal[None] |
| reveal_type(a) # N: Revealed type is "None" |
| |
| def f1(x: Literal[None]) -> None: pass |
| def f2(x: None) -> Literal[None]: pass |
| def f3(x: Literal[None]) -> Literal[None]: pass |
| |
| reveal_type(f1) # N: Revealed type is "def (x: None)" |
| reveal_type(f2) # N: Revealed type is "def (x: None)" |
| reveal_type(f3) # N: Revealed type is "def (x: None)" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralCallingUnionFunction] |
| from typing_extensions import Literal |
| |
| def func(x: Literal['foo', 'bar', ' foo ']) -> None: ... |
| |
| func('foo') |
| func('bar') |
| func(' foo ') |
| func('baz') # E: Argument 1 to "func" has incompatible type "Literal['baz']"; expected "Literal['foo', 'bar', ' foo ']" |
| |
| a: Literal['foo'] |
| b: Literal['bar'] |
| c: Literal[' foo '] |
| d: Literal['foo', 'bar'] |
| e: Literal['foo', 'bar', ' foo '] |
| f: Literal['foo', 'bar', 'baz'] |
| |
| func(a) |
| func(b) |
| func(c) |
| func(d) |
| func(e) |
| func(f) # E: Argument 1 to "func" has incompatible type "Literal['foo', 'bar', 'baz']"; expected "Literal['foo', 'bar', ' foo ']" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralDisallowAny] |
| from typing import Any |
| from typing_extensions import Literal |
| from missing_module import BadAlias # E: Cannot find implementation or library stub for module named "missing_module" \ |
| # N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports |
| |
| a: Literal[Any] # E: Parameter 1 of Literal[...] cannot be of type "Any" |
| b: Literal[BadAlias] # E: Parameter 1 of Literal[...] cannot be of type "Any" |
| |
| reveal_type(a) # N: Revealed type is "Any" |
| reveal_type(b) # N: Revealed type is "Any" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralDisallowActualTypes] |
| from typing_extensions import Literal |
| |
| a: Literal[int] # E: Parameter 1 of Literal[...] is invalid |
| b: Literal[float] # E: Parameter 1 of Literal[...] is invalid |
| c: Literal[bool] # E: Parameter 1 of Literal[...] is invalid |
| d: Literal[str] # E: Parameter 1 of Literal[...] is invalid |
| |
| reveal_type(a) # N: Revealed type is "Any" |
| reveal_type(b) # N: Revealed type is "Any" |
| reveal_type(c) # N: Revealed type is "Any" |
| reveal_type(d) # N: Revealed type is "Any" |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralDisallowFloatsAndComplex] |
| |
| from typing_extensions import Literal |
| a1: Literal[3.14] # E: Parameter 1 of Literal[...] cannot be of type "float" |
| b1: 3.14 # E: Invalid type: float literals cannot be used as a type |
| c1: Literal[3j] # E: Parameter 1 of Literal[...] cannot be of type "complex" |
| d1: 3j # E: Invalid type: complex literals cannot be used as a type |
| |
| a2t = Literal[3.14] # E: Parameter 1 of Literal[...] cannot be of type "float" |
| b2t = 3.14 |
| c2t = Literal[3j] # E: Parameter 1 of Literal[...] cannot be of type "complex" |
| d2t = 3j |
| |
| a2: a2t |
| reveal_type(a2) # N: Revealed type is "Any" |
| b2: b2t # E: Variable "__main__.b2t" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| c2: c2t |
| reveal_type(c2) # N: Revealed type is "Any" |
| d2: d2t # E: Variable "__main__.d2t" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| [builtins fixtures/complex_tuple.pyi] |
| [out] |
| |
| [case testLiteralDisallowComplexExpressions] |
| from typing_extensions import Literal |
| def dummy() -> int: return 3 |
| a: Literal[3 + 4] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| b: Literal[" foo ".trim()] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| c: Literal[+42] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| d: Literal[~12] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| e: Literal[dummy()] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralDisallowCollections] |
| from typing_extensions import Literal |
| a: Literal[{"a": 1, "b": 2}] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| b: Literal[{1, 2, 3}] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| c: {"a": 1, "b": 2} # E: Invalid type comment or annotation |
| d: {1, 2, 3} # E: Invalid type comment or annotation |
| [builtins fixtures/tuple.pyi] |
| |
| [case testLiteralDisallowCollections2] |
| |
| from typing_extensions import Literal |
| a: (1, 2, 3) # E: Syntax error in type annotation \ |
| # N: Suggestion: Use Tuple[T1, ..., Tn] instead of (T1, ..., Tn) |
| b: Literal[[1, 2, 3]] # E: Parameter 1 of Literal[...] is invalid |
| c: [1, 2, 3] # E: Bracketed expression "[...]" is not valid as a type \ |
| # N: Did you mean "List[...]"? |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralDisallowCollectionsTypeAlias] |
| |
| from typing_extensions import Literal |
| at = Literal[{"a": 1, "b": 2}] # E: Invalid type alias: expression is not a valid type |
| bt = {"a": 1, "b": 2} |
| a: at # E: Variable "__main__.at" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| b: bt # E: Variable "__main__.bt" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testLiteralDisallowCollectionsTypeAlias2] |
| |
| from typing_extensions import Literal |
| at = Literal[{1, 2, 3}] # E: Invalid type alias: expression is not a valid type |
| bt = {1, 2, 3} |
| a: at # E: Variable "__main__.at" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| b: bt # E: Variable "__main__.bt" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| [builtins fixtures/set.pyi] |
| [out] |
| |
| [case testLiteralDisallowTypeVar] |
| from typing import TypeVar |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| |
| at = Literal[T] # E: Parameter 1 of Literal[...] is invalid |
| a: at |
| |
| def foo(b: Literal[T]) -> T: pass # E: Parameter 1 of Literal[...] is invalid |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| |
| -- |
| -- Test mixing and matching literals with other types |
| -- |
| |
| [case testLiteralMultipleValues] |
| # flags: --strict-optional |
| from typing_extensions import Literal |
| a: Literal[1, 2, 3] |
| b: Literal["a", "b", "c"] |
| c: Literal[1, "b", True, None] |
| d: Literal[1, 1, 1] |
| e: Literal[None, None, None] |
| reveal_type(a) # N: Revealed type is "Union[Literal[1], Literal[2], Literal[3]]" |
| reveal_type(b) # N: Revealed type is "Union[Literal['a'], Literal['b'], Literal['c']]" |
| reveal_type(c) # N: Revealed type is "Union[Literal[1], Literal['b'], Literal[True], None]" |
| |
| # Note: I was thinking these should be simplified, but it seems like |
| # mypy doesn't simplify unions with duplicate values with other types. |
| reveal_type(d) # N: Revealed type is "Union[Literal[1], Literal[1], Literal[1]]" |
| reveal_type(e) # N: Revealed type is "Union[None, None, None]" |
| [builtins fixtures/bool.pyi] |
| [out] |
| |
| [case testLiteralMultipleValuesExplicitTuple] |
| from typing_extensions import Literal |
| # Unfortunately, it seems like typed_ast is unable to distinguish this from |
| # Literal[1, 2, 3]. So we treat the two as being equivalent for now. |
| a: Literal[1, 2, 3] |
| b: Literal[(1, 2, 3)] |
| reveal_type(a) # N: Revealed type is "Union[Literal[1], Literal[2], Literal[3]]" |
| reveal_type(b) # N: Revealed type is "Union[Literal[1], Literal[2], Literal[3]]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralNestedUsage] |
| # flags: --strict-optional |
| |
| from typing_extensions import Literal |
| a: Literal[Literal[3], 4, Literal["foo"]] |
| reveal_type(a) # N: Revealed type is "Union[Literal[3], Literal[4], Literal['foo']]" |
| |
| alias_for_literal = Literal[5] |
| b: Literal[alias_for_literal] |
| reveal_type(b) # N: Revealed type is "Literal[5]" |
| |
| another_alias = Literal[1, None] |
| c: Literal[alias_for_literal, another_alias, "r"] |
| reveal_type(c) # N: Revealed type is "Union[Literal[5], Literal[1], None, Literal['r']]" |
| |
| basic_mode = Literal["r", "w", "a"] |
| basic_with_plus = Literal["r+", "w+", "a+"] |
| combined: Literal[basic_mode, basic_with_plus] |
| reveal_type(combined) # N: Revealed type is "Union[Literal['r'], Literal['w'], Literal['a'], Literal['r+'], Literal['w+'], Literal['a+']]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralBiasTowardsAssumingForwardReference] |
| from typing_extensions import Literal |
| |
| a: "Foo" |
| reveal_type(a) # N: Revealed type is "__main__.Foo" |
| |
| b: Literal["Foo"] |
| reveal_type(b) # N: Revealed type is "Literal['Foo']" |
| |
| c: "Literal[Foo]" # E: Parameter 1 of Literal[...] is invalid |
| |
| d: "Literal['Foo']" |
| reveal_type(d) # N: Revealed type is "Literal['Foo']" |
| |
| class Foo: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralBiasTowardsAssumingForwardReferenceForTypeAliases] |
| from typing_extensions import Literal |
| |
| a: "Foo" |
| reveal_type(a) # N: Revealed type is "Literal[5]" |
| |
| b: Literal["Foo"] |
| reveal_type(b) # N: Revealed type is "Literal['Foo']" |
| |
| c: "Literal[Foo]" |
| reveal_type(c) # N: Revealed type is "Literal[5]" |
| |
| d: "Literal['Foo']" |
| reveal_type(d) # N: Revealed type is "Literal['Foo']" |
| |
| e: Literal[Foo, 'Foo'] |
| reveal_type(e) # N: Revealed type is "Union[Literal[5], Literal['Foo']]" |
| |
| Foo = Literal[5] |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralBiasTowardsAssumingForwardReferencesForTypeComments] |
| from typing_extensions import Literal |
| |
| a = None # type: Foo |
| reveal_type(a) # N: Revealed type is "__main__.Foo" |
| |
| b = None # type: "Foo" |
| reveal_type(b) # N: Revealed type is "__main__.Foo" |
| |
| c = None # type: Literal["Foo"] |
| reveal_type(c) # N: Revealed type is "Literal['Foo']" |
| |
| d = None # type: Literal[Foo] # E: Parameter 1 of Literal[...] is invalid |
| |
| class Foo: pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| |
| -- |
| -- Check how we handle very basic subtyping and other useful things |
| -- |
| |
| [case testLiteralCallingFunction] |
| from typing_extensions import Literal |
| def foo(x: Literal[3]) -> None: pass |
| |
| a: Literal[1] |
| b: Literal[2] |
| c: int |
| |
| foo(a) # E: Argument 1 to "foo" has incompatible type "Literal[1]"; expected "Literal[3]" |
| foo(b) # E: Argument 1 to "foo" has incompatible type "Literal[2]"; expected "Literal[3]" |
| foo(c) # E: Argument 1 to "foo" has incompatible type "int"; expected "Literal[3]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralCallingFunctionWithUnionLiteral] |
| from typing_extensions import Literal |
| def foo(x: Literal[1, 2, 3]) -> None: pass |
| |
| a: Literal[1] |
| b: Literal[2, 3] |
| c: Literal[4, 5] |
| d: int |
| |
| foo(a) |
| foo(b) |
| foo(c) # E: Argument 1 to "foo" has incompatible type "Literal[4, 5]"; expected "Literal[1, 2, 3]" |
| foo(d) # E: Argument 1 to "foo" has incompatible type "int"; expected "Literal[1, 2, 3]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralCallingFunctionWithStandardBase] |
| from typing_extensions import Literal |
| def foo(x: int) -> None: pass |
| |
| a: Literal[1] |
| b: Literal[1, -4] |
| c: Literal[4, 'foo'] |
| |
| foo(a) |
| foo(b) |
| foo(c) # E: Argument 1 to "foo" has incompatible type "Literal[4, 'foo']"; expected "int" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralCheckSubtypingStrictOptional] |
| # flags: --strict-optional |
| from typing import Any, NoReturn |
| from typing_extensions import Literal |
| |
| lit: Literal[1] |
| def f_lit(x: Literal[1]) -> None: pass |
| |
| def fa(x: Any) -> None: pass |
| def fb(x: NoReturn) -> None: pass |
| def fc(x: None) -> None: pass |
| |
| a: Any |
| b: NoReturn |
| c: None |
| |
| fa(lit) |
| fb(lit) # E: Argument 1 to "fb" has incompatible type "Literal[1]"; expected "NoReturn" |
| fc(lit) # E: Argument 1 to "fc" has incompatible type "Literal[1]"; expected "None" |
| |
| f_lit(a) |
| f_lit(b) |
| f_lit(c) # E: Argument 1 to "f_lit" has incompatible type "None"; expected "Literal[1]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralCheckSubtypingNoStrictOptional] |
| # flags: --no-strict-optional |
| from typing import Any, NoReturn |
| from typing_extensions import Literal |
| |
| lit: Literal[1] |
| def f_lit(x: Literal[1]) -> None: pass |
| |
| def fa(x: Any) -> None: pass |
| def fb(x: NoReturn) -> None: pass |
| def fc(x: None) -> None: pass |
| |
| a: Any |
| b: NoReturn |
| c: None |
| |
| fa(lit) |
| fb(lit) # E: Argument 1 to "fb" has incompatible type "Literal[1]"; expected "NoReturn" |
| fc(lit) # E: Argument 1 to "fc" has incompatible type "Literal[1]"; expected "None" |
| |
| f_lit(a) |
| f_lit(b) |
| f_lit(c) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralCallingOverloadedFunction] |
| from typing import overload, Generic, TypeVar, Any |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| class IOLike(Generic[T]): pass |
| |
| @overload |
| def foo(x: Literal[1]) -> IOLike[int]: ... |
| @overload |
| def foo(x: Literal[2]) -> IOLike[str]: ... |
| @overload |
| def foo(x: int) -> IOLike[Any]: ... |
| def foo(x: int) -> IOLike[Any]: |
| if x == 1: |
| return IOLike[int]() |
| elif x == 2: |
| return IOLike[str]() |
| else: |
| return IOLike() |
| |
| a: Literal[1] |
| b: Literal[2] |
| c: int |
| d: Literal[3] |
| |
| reveal_type(foo(a)) # N: Revealed type is "__main__.IOLike[builtins.int]" |
| reveal_type(foo(b)) # N: Revealed type is "__main__.IOLike[builtins.str]" |
| reveal_type(foo(c)) # N: Revealed type is "__main__.IOLike[Any]" |
| foo(d) |
| [builtins fixtures/ops.pyi] |
| [out] |
| |
| [case testLiteralVariance] |
| from typing import Generic, TypeVar |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| T_co = TypeVar('T_co', covariant=True) |
| T_contra = TypeVar('T_contra', contravariant=True) |
| |
| class Invariant(Generic[T]): pass |
| class Covariant(Generic[T_co]): pass |
| class Contravariant(Generic[T_contra]): pass |
| |
| a1: Invariant[Literal[1]] |
| a2: Invariant[Literal[1, 2]] |
| a3: Invariant[Literal[1, 2, 3]] |
| a2 = a1 # E: Incompatible types in assignment (expression has type "Invariant[Literal[1]]", variable has type "Invariant[Literal[1, 2]]") |
| a2 = a3 # E: Incompatible types in assignment (expression has type "Invariant[Literal[1, 2, 3]]", variable has type "Invariant[Literal[1, 2]]") |
| |
| b1: Covariant[Literal[1]] |
| b2: Covariant[Literal[1, 2]] |
| b3: Covariant[Literal[1, 2, 3]] |
| b2 = b1 |
| b2 = b3 # E: Incompatible types in assignment (expression has type "Covariant[Literal[1, 2, 3]]", variable has type "Covariant[Literal[1, 2]]") |
| |
| c1: Contravariant[Literal[1]] |
| c2: Contravariant[Literal[1, 2]] |
| c3: Contravariant[Literal[1, 2, 3]] |
| c2 = c1 # E: Incompatible types in assignment (expression has type "Contravariant[Literal[1]]", variable has type "Contravariant[Literal[1, 2]]") |
| c2 = c3 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInListAndSequence] |
| from typing import List, Sequence |
| from typing_extensions import Literal |
| |
| def foo(x: List[Literal[1, 2]]) -> None: pass |
| def bar(x: Sequence[Literal[1, 2]]) -> None: pass |
| |
| a: List[Literal[1]] |
| b: List[Literal[1, 2, 3]] |
| |
| foo(a) # E: Argument 1 to "foo" has incompatible type "List[Literal[1]]"; expected "List[Literal[1, 2]]" \ |
| # N: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ |
| # N: Consider using "Sequence" instead, which is covariant |
| foo(b) # E: Argument 1 to "foo" has incompatible type "List[Literal[1, 2, 3]]"; expected "List[Literal[1, 2]]" |
| bar(a) |
| bar(b) # E: Argument 1 to "bar" has incompatible type "List[Literal[1, 2, 3]]"; expected "Sequence[Literal[1, 2]]" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testLiteralRenamingDoesNotChangeTypeChecking] |
| from typing_extensions import Literal as Foo |
| from other_module import Bar1, Bar2, c |
| |
| def func(x: Foo[15]) -> None: pass |
| |
| a: Bar1 |
| b: Bar2 |
| func(a) |
| func(b) # E: Argument 1 to "func" has incompatible type "Literal[14]"; expected "Literal[15]" |
| func(c) |
| |
| [file other_module.py] |
| from typing_extensions import Literal |
| |
| Bar1 = Literal[15] |
| Bar2 = Literal[14] |
| c: Literal[15] |
| [builtins fixtures/tuple.pyi] |
| |
| |
| -- |
| -- Check to make sure we handle inference of literal values correctly, |
| -- especially when doing assignments or calls |
| -- |
| |
| [case testLiteralInferredInAssignment] |
| from typing_extensions import Literal |
| |
| int1: Literal[1] = 1 |
| int2 = 1 |
| int3: int = 1 |
| |
| str1: Literal["foo"] = "foo" |
| str2 = "foo" |
| str3: str = "foo" |
| |
| bool1: Literal[True] = True |
| bool2 = True |
| bool3: bool = True |
| |
| none1: Literal[None] = None |
| none2 = None |
| none3: None = None |
| |
| reveal_type(int1) # N: Revealed type is "Literal[1]" |
| reveal_type(int2) # N: Revealed type is "builtins.int" |
| reveal_type(int3) # N: Revealed type is "builtins.int" |
| reveal_type(str1) # N: Revealed type is "Literal['foo']" |
| reveal_type(str2) # N: Revealed type is "builtins.str" |
| reveal_type(str3) # N: Revealed type is "builtins.str" |
| reveal_type(bool1) # N: Revealed type is "Literal[True]" |
| reveal_type(bool2) # N: Revealed type is "builtins.bool" |
| reveal_type(bool3) # N: Revealed type is "builtins.bool" |
| reveal_type(none1) # N: Revealed type is "None" |
| reveal_type(none2) # N: Revealed type is "None" |
| reveal_type(none3) # N: Revealed type is "None" |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralInferredOnlyForActualLiterals] |
| from typing_extensions import Literal |
| |
| w: Literal[1] |
| x: Literal["foo"] |
| y: Literal[True] |
| z: Literal[None] |
| combined: Literal[1, "foo", True, None] |
| |
| a = 1 |
| b = "foo" |
| c = True |
| d = None |
| |
| w = a # E: Incompatible types in assignment (expression has type "int", variable has type "Literal[1]") |
| x = b # E: Incompatible types in assignment (expression has type "str", variable has type "Literal['foo']") |
| y = c # E: Incompatible types in assignment (expression has type "bool", variable has type "Literal[True]") |
| z = d # This is ok: Literal[None] and None are equivalent. |
| |
| combined = a # E: Incompatible types in assignment (expression has type "int", variable has type "Optional[Literal[1, 'foo', True]]") |
| combined = b # E: Incompatible types in assignment (expression has type "str", variable has type "Optional[Literal[1, 'foo', True]]") |
| combined = c # E: Incompatible types in assignment (expression has type "bool", variable has type "Optional[Literal[1, 'foo', True]]") |
| combined = d # Also ok, for similar reasons. |
| |
| e: Literal[1] = 1 |
| f: Literal["foo"] = "foo" |
| g: Literal[True] = True |
| h: Literal[None] = None |
| |
| w = e |
| x = f |
| y = g |
| z = h |
| combined = e |
| combined = f |
| combined = g |
| combined = h |
| |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralInferredTypeMustMatchExpected] |
| from typing_extensions import Literal |
| |
| a: Literal[1] = 2 # E: Incompatible types in assignment (expression has type "Literal[2]", variable has type "Literal[1]") |
| b: Literal["foo"] = "bar" # E: Incompatible types in assignment (expression has type "Literal['bar']", variable has type "Literal['foo']") |
| c: Literal[True] = False # E: Incompatible types in assignment (expression has type "Literal[False]", variable has type "Literal[True]") |
| |
| d: Literal[1, 2] = 3 # E: Incompatible types in assignment (expression has type "Literal[3]", variable has type "Literal[1, 2]") |
| e: Literal["foo", "bar"] = "baz" # E: Incompatible types in assignment (expression has type "Literal['baz']", variable has type "Literal['foo', 'bar']") |
| f: Literal[True, 4] = False # E: Incompatible types in assignment (expression has type "Literal[False]", variable has type "Literal[True, 4]") |
| |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralInferredInCall] |
| from typing_extensions import Literal |
| |
| def f_int_lit(x: Literal[1]) -> None: pass |
| def f_int(x: int) -> None: pass |
| |
| def f_str_lit(x: Literal["foo"]) -> None: pass |
| def f_str(x: str) -> None: pass |
| |
| def f_bool_lit(x: Literal[True]) -> None: pass |
| def f_bool(x: bool) -> None: pass |
| |
| def f_none_lit(x: Literal[None]) -> None: pass |
| def f_none(x: None) -> None: pass |
| |
| i1: Literal[1] |
| i2: Literal[2] |
| f_int_lit(1) |
| f_int_lit(2) # E: Argument 1 to "f_int_lit" has incompatible type "Literal[2]"; expected "Literal[1]" |
| f_int(1) |
| f_int_lit(i1) |
| f_int_lit(i2) # E: Argument 1 to "f_int_lit" has incompatible type "Literal[2]"; expected "Literal[1]" |
| |
| s1: Literal["foo"] |
| s2: Literal["bar"] |
| f_str_lit("foo") |
| f_str_lit("bar") # E: Argument 1 to "f_str_lit" has incompatible type "Literal['bar']"; expected "Literal['foo']" |
| f_str("baz") |
| f_str_lit(s1) |
| f_str_lit(s2) # E: Argument 1 to "f_str_lit" has incompatible type "Literal['bar']"; expected "Literal['foo']" |
| |
| b1: Literal[True] |
| b2: Literal[False] |
| f_bool_lit(True) |
| f_bool_lit(False) # E: Argument 1 to "f_bool_lit" has incompatible type "Literal[False]"; expected "Literal[True]" |
| f_bool(True) |
| f_bool_lit(b1) |
| f_bool_lit(b2) # E: Argument 1 to "f_bool_lit" has incompatible type "Literal[False]"; expected "Literal[True]" |
| |
| n1: Literal[None] |
| f_none_lit(None) |
| f_none(None) |
| f_none_lit(n1) |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralInferredInReturnContext] |
| from typing_extensions import Literal |
| |
| def f1() -> int: |
| return 1 |
| |
| def f2() -> Literal[1]: |
| return 1 |
| |
| def f3() -> Literal[1]: |
| return 2 # E: Incompatible return value type (got "Literal[2]", expected "Literal[1]") |
| |
| def f4(x: Literal[1]) -> Literal[1]: |
| return x |
| |
| def f5(x: Literal[2]) -> Literal[1]: |
| return x # E: Incompatible return value type (got "Literal[2]", expected "Literal[1]") |
| [builtins fixtures/tuple.pyi] |
| |
| [out] |
| |
| [case testLiteralInferredInListContext] |
| from typing import List |
| from typing_extensions import Literal |
| |
| a: List[Literal[1]] = [1, 1, 1] |
| b = [1, 1, 1] |
| c: List[Literal[1, 2, 3]] = [1, 2, 3] |
| d = [1, 2, 3] |
| e: List[Literal[1, "x"]] = [1, "x"] |
| f = [1, "x"] |
| g: List[List[List[Literal[1, 2, 3]]]] = [[[1, 2, 3], [3]]] |
| h: List[Literal[1]] = [] |
| |
| reveal_type(a) # N: Revealed type is "builtins.list[Literal[1]]" |
| reveal_type(b) # N: Revealed type is "builtins.list[builtins.int]" |
| reveal_type(c) # N: Revealed type is "builtins.list[Union[Literal[1], Literal[2], Literal[3]]]" |
| reveal_type(d) # N: Revealed type is "builtins.list[builtins.int]" |
| reveal_type(e) # N: Revealed type is "builtins.list[Union[Literal[1], Literal['x']]]" |
| reveal_type(f) # N: Revealed type is "builtins.list[builtins.object]" |
| reveal_type(g) # N: Revealed type is "builtins.list[builtins.list[builtins.list[Union[Literal[1], Literal[2], Literal[3]]]]]" |
| reveal_type(h) # N: Revealed type is "builtins.list[Literal[1]]" |
| |
| lit1: Literal[1] |
| lit2: Literal[2] |
| lit3: Literal["foo"] |
| |
| arr1 = [lit1, lit1, lit1] |
| arr2 = [lit1, lit2] |
| arr3 = [lit1, 4, 5] |
| arr4 = [lit1, lit2, lit3] |
| arr5 = [object(), lit1] |
| |
| reveal_type(arr1) # N: Revealed type is "builtins.list[Literal[1]]" |
| reveal_type(arr2) # N: Revealed type is "builtins.list[builtins.int]" |
| reveal_type(arr3) # N: Revealed type is "builtins.list[builtins.int]" |
| reveal_type(arr4) # N: Revealed type is "builtins.list[builtins.object]" |
| reveal_type(arr5) # N: Revealed type is "builtins.list[builtins.object]" |
| |
| bad: List[Literal[1, 2]] = [1, 2, 3] # E: List item 2 has incompatible type "Literal[3]"; expected "Literal[1, 2]" |
| |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testLiteralInferredInTupleContext] |
| # Note: most of the 'are we handling context correctly' tests should have been |
| # handled up above, so we keep things comparatively simple for tuples and dicts. |
| from typing import Tuple |
| from typing_extensions import Literal |
| |
| a: Tuple[Literal[1], Literal[2]] = (1, 2) |
| b: Tuple[int, Literal[1, 2], Literal[3], Tuple[Literal["foo"]]] = (1, 2, 3, ("foo",)) |
| c: Tuple[Literal[1], Literal[2]] = (2, 1) # E: Incompatible types in assignment (expression has type "Tuple[Literal[2], Literal[1]]", variable has type "Tuple[Literal[1], Literal[2]]") |
| d = (1, 2) |
| |
| reveal_type(d) # N: Revealed type is "Tuple[builtins.int, builtins.int]" |
| |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInferredInDictContext] |
| from typing import Dict |
| from typing_extensions import Literal |
| |
| a = {"x": 1, "y": 2} |
| b: Dict[str, Literal[1, 2]] = {"x": 1, "y": 2} |
| c: Dict[Literal["x", "y"], int] = {"x": 1, "y": 2} |
| |
| reveal_type(a) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]" |
| |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testLiteralInferredInOverloadContextBasic] |
| from typing import overload |
| from typing_extensions import Literal |
| |
| @overload |
| def func(x: Literal[1]) -> str: ... |
| @overload |
| def func(x: Literal[2]) -> int: ... |
| @overload |
| def func(x: int) -> object: ... |
| def func(x: int) -> object: pass |
| |
| a: Literal[1] |
| b: Literal[2] |
| c: Literal[1, 2] |
| |
| reveal_type(func(1)) # N: Revealed type is "builtins.str" |
| reveal_type(func(2)) # N: Revealed type is "builtins.int" |
| reveal_type(func(3)) # N: Revealed type is "builtins.object" |
| reveal_type(func(a)) # N: Revealed type is "builtins.str" |
| reveal_type(func(b)) # N: Revealed type is "builtins.int" |
| |
| # Note: the fact that we don't do union math here is consistent |
| # with the output we would have gotten if we replaced int and the |
| # Literal types here with regular classes/subclasses. |
| reveal_type(func(c)) # N: Revealed type is "builtins.object" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralOverloadProhibitUnsafeOverlaps] |
| from typing import overload |
| from typing_extensions import Literal |
| |
| @overload |
| def func1(x: Literal[1]) -> str: ... # E: Overloaded function signatures 1 and 2 overlap with incompatible return types |
| @overload |
| def func1(x: int) -> int: ... |
| def func1(x): pass |
| |
| @overload |
| def func2(x: Literal['a']) -> int: ... # E: Overloaded function signatures 1 and 2 overlap with incompatible return types |
| @overload |
| def func2(x: str) -> Literal[2]: ... |
| def func2(x): pass |
| |
| # This one is typesafe |
| @overload |
| def func3(x: Literal['a']) -> Literal[2]: ... |
| @overload |
| def func3(x: str) -> int: ... |
| def func3(x): pass |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInferredInOverloadContextUnionMath] |
| from typing import overload, Union |
| from typing_extensions import Literal |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| |
| @overload |
| def func(x: Literal[-40]) -> A: ... |
| @overload |
| def func(x: Literal[3, 4, 5, 6]) -> B: ... |
| @overload |
| def func(x: Literal["foo"]) -> C: ... |
| def func(x: Union[int, str]) -> Union[A, B, C]: pass |
| |
| a: Literal[-40, "foo"] |
| b: Literal[3] |
| c: Literal[3, -40] |
| d: Literal[6, 7] |
| e: int |
| f: Literal[7, "bar"] |
| |
| reveal_type(func(a)) # N: Revealed type is "Union[__main__.A, __main__.C]" |
| reveal_type(func(b)) # N: Revealed type is "__main__.B" |
| reveal_type(func(c)) # N: Revealed type is "Union[__main__.B, __main__.A]" |
| reveal_type(func(d)) # N: Revealed type is "__main__.B" \ |
| # E: Argument 1 to "func" has incompatible type "Literal[6, 7]"; expected "Literal[3, 4, 5, 6]" |
| |
| reveal_type(func(e)) # E: No overload variant of "func" matches argument type "int" \ |
| # N: Possible overload variants: \ |
| # N: def func(x: Literal[-40]) -> A \ |
| # N: def func(x: Literal[3, 4, 5, 6]) -> B \ |
| # N: def func(x: Literal['foo']) -> C \ |
| # N: Revealed type is "Any" |
| |
| reveal_type(func(f)) # E: No overload variant of "func" matches argument type "Literal[7, 'bar']" \ |
| # N: Possible overload variants: \ |
| # N: def func(x: Literal[-40]) -> A \ |
| # N: def func(x: Literal[3, 4, 5, 6]) -> B \ |
| # N: def func(x: Literal['foo']) -> C \ |
| # N: Revealed type is "Any" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInferredInOverloadContextUnionMathOverloadingReturnsBestType] |
| # This test is a transliteration of check-overloading::testUnionMathOverloadingReturnsBestType |
| from typing import overload |
| from typing_extensions import Literal |
| |
| @overload |
| def f(x: Literal[1, 2]) -> int: ... |
| @overload |
| def f(x: int) -> object: ... |
| def f(x): |
| pass |
| |
| x: Literal[1, 2] |
| y: Literal[1, 2, 3] |
| z: Literal[1, 2, "three"] |
| reveal_type(f(x)) # N: Revealed type is "builtins.int" |
| reveal_type(f(1)) # N: Revealed type is "builtins.int" |
| reveal_type(f(2)) # N: Revealed type is "builtins.int" |
| reveal_type(f(y)) # N: Revealed type is "builtins.object" |
| reveal_type(f(z)) # N: Revealed type is "builtins.int" \ |
| # E: Argument 1 to "f" has incompatible type "Literal[1, 2, 'three']"; expected "Literal[1, 2]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInferredInOverloadContextWithTypevars] |
| from typing import TypeVar, overload, Union |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| |
| @overload |
| def f1(x: T, y: int) -> T: ... |
| @overload |
| def f1(x: T, y: str) -> Union[T, str]: ... |
| def f1(x, y): pass |
| |
| a: Literal[1] |
| reveal_type(f1(1, 1)) # N: Revealed type is "builtins.int" |
| reveal_type(f1(a, 1)) # N: Revealed type is "Literal[1]" |
| |
| @overload |
| def f2(x: T, y: Literal[3]) -> T: ... |
| @overload |
| def f2(x: T, y: str) -> Union[T]: ... |
| def f2(x, y): pass |
| |
| reveal_type(f2(1, 3)) # N: Revealed type is "builtins.int" |
| reveal_type(f2(a, 3)) # N: Revealed type is "Literal[1]" |
| |
| @overload |
| def f3(x: Literal[3]) -> Literal[3]: ... |
| @overload |
| def f3(x: T) -> T: ... |
| def f3(x): pass |
| |
| reveal_type(f3(1)) # N: Revealed type is "builtins.int" |
| reveal_type(f3(a)) # N: Revealed type is "Literal[1]" |
| |
| @overload |
| def f4(x: str) -> str: ... |
| @overload |
| def f4(x: T) -> T: ... |
| def f4(x): pass |
| |
| b: Literal['foo'] |
| reveal_type(f4(1)) # N: Revealed type is "builtins.int" |
| reveal_type(f4(a)) # N: Revealed type is "Literal[1]" |
| reveal_type(f4("foo")) # N: Revealed type is "builtins.str" |
| |
| # Note: first overload is selected and prevents the typevar from |
| # ever inferring a Literal["something"]. |
| reveal_type(f4(b)) # N: Revealed type is "builtins.str" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralInferredInOverloadContextUnionMathTrickyOverload] |
| # This test is a transliteration of check-overloading::testUnionMathTrickyOverload1 |
| from typing import overload |
| from typing_extensions import Literal |
| |
| @overload |
| def f(x: Literal['a'], y: Literal['a']) -> int: ... |
| @overload |
| def f(x: str, y: Literal['b']) -> str: ... |
| def f(x): |
| pass |
| |
| x: Literal['a', 'b'] |
| y: Literal['a', 'b'] |
| f(x, y) # E: Argument 1 to "f" has incompatible type "Literal['a', 'b']"; expected "Literal['a']" \ |
| # E: Argument 2 to "f" has incompatible type "Literal['a', 'b']"; expected "Literal['a']" \ |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| |
| --- |
| --- Tests that make sure we're correctly using the fallback |
| --- |
| |
| [case testLiteralFallbackOperatorsWorkCorrectly] |
| from typing_extensions import Literal |
| |
| a: Literal[3] |
| b: int |
| c: Literal[4] |
| d: Literal['foo'] |
| e: str |
| |
| reveal_type(a + a) # N: Revealed type is "builtins.int" |
| reveal_type(a + b) # N: Revealed type is "builtins.int" |
| reveal_type(b + a) # N: Revealed type is "builtins.int" |
| reveal_type(a + 1) # N: Revealed type is "builtins.int" |
| reveal_type(1 + a) # N: Revealed type is "builtins.int" |
| reveal_type(a + c) # N: Revealed type is "builtins.int" |
| reveal_type(c + a) # N: Revealed type is "builtins.int" |
| |
| reveal_type(d + d) # N: Revealed type is "builtins.str" |
| reveal_type(d + e) # N: Revealed type is "builtins.str" |
| reveal_type(e + d) # N: Revealed type is "builtins.str" |
| reveal_type(d + 'foo') # N: Revealed type is "builtins.str" |
| reveal_type('foo' + d) # N: Revealed type is "builtins.str" |
| |
| reveal_type(a.__add__(b)) # N: Revealed type is "builtins.int" |
| reveal_type(b.__add__(a)) # N: Revealed type is "builtins.int" |
| |
| a *= b # E: Incompatible types in assignment (expression has type "int", variable has type "Literal[3]") |
| b *= a |
| |
| reveal_type(b) # N: Revealed type is "builtins.int" |
| [builtins fixtures/primitives.pyi] |
| |
| [case testLiteralFallbackInheritedMethodsWorkCorrectly] |
| from typing_extensions import Literal |
| a: Literal['foo'] |
| b: str |
| |
| reveal_type(a.startswith(a)) # N: Revealed type is "builtins.bool" |
| reveal_type(b.startswith(a)) # N: Revealed type is "builtins.bool" |
| reveal_type(a.startswith(b)) # N: Revealed type is "builtins.bool" |
| reveal_type(a.strip()) # N: Revealed type is "builtins.str" |
| [builtins fixtures/ops.pyi] |
| [out] |
| |
| [case testLiteralFallbackMethodsDoNotCoerceToLiteral] |
| from typing_extensions import Literal |
| |
| a: Literal[3] |
| b: int |
| c: Literal["foo"] |
| |
| if int(): |
| a = a * a # E: Incompatible types in assignment (expression has type "int", variable has type "Literal[3]") |
| a = a * b # E: Incompatible types in assignment (expression has type "int", variable has type "Literal[3]") |
| a = b * a # E: Incompatible types in assignment (expression has type "int", variable has type "Literal[3]") |
| |
| b = a * a |
| b = a * b |
| b = b * a |
| |
| c = c.strip() # E: Incompatible types in assignment (expression has type "str", variable has type "Literal['foo']") |
| [builtins fixtures/ops.pyi] |
| [out] |
| |
| |
| -- |
| -- Tests that check we report errors when we try using Literal[...] |
| -- in invalid places. |
| -- |
| |
| [case testLiteralErrorsWithIsInstanceAndIsSubclass] |
| from typing_extensions import Literal |
| from typing_extensions import Literal as Renamed |
| import typing_extensions as indirect |
| |
| Alias = Literal[3] |
| |
| isinstance(3, Literal[3]) # E: Cannot use isinstance() with Literal type |
| isinstance(3, Alias) # E: Cannot use isinstance() with Literal type \ |
| # E: Argument 2 to "isinstance" has incompatible type "object"; expected "Union[type, Tuple[Any, ...]]" |
| isinstance(3, Renamed[3]) # E: Cannot use isinstance() with Literal type |
| isinstance(3, indirect.Literal[3]) # E: Cannot use isinstance() with Literal type |
| |
| issubclass(int, Literal[3]) # E: Cannot use issubclass() with Literal type |
| issubclass(int, Alias) # E: Cannot use issubclass() with Literal type \ |
| # E: Argument 2 to "issubclass" has incompatible type "object"; expected "Union[type, Tuple[Any, ...]]" |
| issubclass(int, Renamed[3]) # E: Cannot use issubclass() with Literal type |
| issubclass(int, indirect.Literal[3]) # E: Cannot use issubclass() with Literal type |
| [builtins fixtures/isinstancelist.pyi] |
| [out] |
| |
| [case testLiteralErrorsWhenSubclassed] |
| |
| from typing_extensions import Literal |
| from typing_extensions import Literal as Renamed |
| import typing_extensions as indirect |
| |
| Alias = Literal[3] |
| |
| class Bad1(Literal[3]): pass # E: Invalid base class "Literal" |
| class Bad2(Renamed[3]): pass # E: Invalid base class "Renamed" |
| class Bad3(indirect.Literal[3]): pass # E: Invalid base class "indirect.Literal" |
| class Bad4(Alias): pass # E: Invalid base class "Alias" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralErrorsWhenInvoked-skip] |
| # TODO: We don't seem to correctly handle invoking types like |
| # 'Final' and 'Protocol' as well. When fixing this, also fix |
| # those types? |
| from typing_extensions import Literal |
| from typing_extensions import Literal as Renamed |
| import typing_extensions as indirect |
| |
| Alias = Literal[3] |
| |
| Literal[3]() # E: The type "Type[Literal]" is not generic and not indexable |
| Renamed[3]() # E: The type "Type[Literal]" is not generic and not indexable |
| indirect.Literal[3]() # E: The type "Type[Literal]" is not generic and not indexable |
| Alias() # E: "object" not callable |
| |
| # TODO: Add appropriate error messages to the following lines |
| Literal() |
| Renamed() |
| indirect.Literal() |
| [builtins fixtures/isinstancelist.pyi] |
| [out] |
| |
| |
| -- |
| -- Test to make sure literals interact with generics as expected |
| -- |
| |
| [case testLiteralAndGenericsWithSimpleFunctions] |
| from typing import TypeVar |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| def foo(x: T) -> T: pass |
| def expects_literal(x: Literal[3]) -> None: pass |
| def expects_int(x: int) -> None: pass |
| |
| a: Literal[3] |
| reveal_type(foo(3)) # N: Revealed type is "builtins.int" |
| reveal_type(foo(a)) # N: Revealed type is "Literal[3]" |
| |
| expects_literal(3) |
| expects_literal(foo(3)) |
| expects_literal(foo(foo(3))) |
| |
| expects_literal(a) |
| expects_literal(foo(a)) |
| expects_literal(foo(foo(a))) |
| |
| expects_literal(5) # E: Argument 1 to "expects_literal" has incompatible type "Literal[5]"; expected "Literal[3]" |
| expects_literal(foo(5)) # E: Argument 1 to "foo" has incompatible type "Literal[5]"; expected "Literal[3]" |
| expects_literal(foo(foo(5))) # E: Argument 1 to "foo" has incompatible type "Literal[5]"; expected "Literal[3]" |
| |
| expects_int(a) |
| expects_int(foo(a)) |
| expects_int(foo(foo(a))) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralAndGenericWithUnion] |
| from typing import TypeVar, Union |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| def identity(x: T) -> T: return x |
| |
| a: Union[int, Literal['foo']] = identity('foo') |
| b: Union[int, Literal['foo']] = identity('bar') # E: Argument 1 to "identity" has incompatible type "Literal['bar']"; expected "Union[int, Literal['foo']]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralAndGenericsNoMatch] |
| from typing import TypeVar, Union, List |
| from typing_extensions import Literal |
| |
| def identity(x: T) -> T: |
| return x |
| |
| Ok1 = Union[List[int], Literal['bad']] |
| Ok2 = Union[List[Literal[42]], Literal['bad']] |
| Bad = Union[List[Literal[43]], Literal['bad']] |
| |
| x: Ok1 = identity([42]) |
| y: Ok2 = identity([42]) |
| z: Bad = identity([42]) # E: List item 0 has incompatible type "Literal[42]"; expected "Literal[43]" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testLiteralAndGenericsWithSimpleClasses] |
| from typing import TypeVar, Generic |
| from typing_extensions import Literal |
| |
| T = TypeVar('T') |
| class Wrapper(Generic[T]): |
| def __init__(self, val: T) -> None: |
| self.val = val |
| def inner(self) -> T: |
| return self.val |
| |
| def expects_literal(a: Literal[3]) -> None: pass |
| def expects_literal_wrapper(x: Wrapper[Literal[3]]) -> None: pass |
| |
| a: Literal[3] |
| reveal_type(Wrapper(3)) # N: Revealed type is "__main__.Wrapper[builtins.int]" |
| reveal_type(Wrapper[Literal[3]](3)) # N: Revealed type is "__main__.Wrapper[Literal[3]]" |
| reveal_type(Wrapper(a)) # N: Revealed type is "__main__.Wrapper[Literal[3]]" |
| |
| expects_literal(Wrapper(a).inner()) |
| |
| # Note: the following probably ought to type-check: it's reasonable to infer |
| # Wrapper[Literal[3]] here. |
| # TODO: Consider finding a way to handle this edge case better |
| expects_literal(Wrapper(3).inner()) # E: Argument 1 to "expects_literal" has incompatible type "int"; expected "Literal[3]" |
| |
| # Note: if we handle the edge case above, we should make sure this error |
| # message switches to warning about an incompatible type 'Literal[5]' rather |
| # then an incompatible type 'int' |
| expects_literal(Wrapper(5).inner()) # E: Argument 1 to "expects_literal" has incompatible type "int"; expected "Literal[3]" |
| |
| expects_literal_wrapper(Wrapper(a)) |
| expects_literal_wrapper(Wrapper(3)) |
| expects_literal_wrapper(Wrapper(5)) # E: Argument 1 to "Wrapper" has incompatible type "Literal[5]"; expected "Literal[3]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralAndGenericsRespectsUpperBound] |
| from typing import TypeVar |
| from typing_extensions import Literal |
| |
| TLiteral = TypeVar('TLiteral', bound=Literal[3]) |
| TInt = TypeVar('TInt', bound=int) |
| |
| def func1(x: TLiteral) -> TLiteral: pass |
| def func2(x: TInt) -> TInt: pass |
| |
| def func3(x: TLiteral) -> TLiteral: |
| y = func2(x) |
| return y |
| def func4(x: TInt) -> TInt: |
| y = func1(x) # E: Value of type variable "TLiteral" of "func1" cannot be "TInt" |
| return y |
| |
| a: Literal[3] |
| b: Literal[4] |
| c: int |
| |
| reveal_type(func1) # N: Revealed type is "def [TLiteral <: Literal[3]] (x: TLiteral`-1) -> TLiteral`-1" |
| |
| reveal_type(func1(3)) # N: Revealed type is "Literal[3]" |
| reveal_type(func1(a)) # N: Revealed type is "Literal[3]" |
| reveal_type(func1(4)) # E: Value of type variable "TLiteral" of "func1" cannot be "Literal[4]" \ |
| # N: Revealed type is "Literal[4]" |
| reveal_type(func1(b)) # E: Value of type variable "TLiteral" of "func1" cannot be "Literal[4]" \ |
| # N: Revealed type is "Literal[4]" |
| reveal_type(func1(c)) # E: Value of type variable "TLiteral" of "func1" cannot be "int" \ |
| # N: Revealed type is "builtins.int" |
| |
| reveal_type(func2(3)) # N: Revealed type is "builtins.int" |
| reveal_type(func2(a)) # N: Revealed type is "Literal[3]" |
| reveal_type(func2(4)) # N: Revealed type is "builtins.int" |
| reveal_type(func2(b)) # N: Revealed type is "Literal[4]" |
| reveal_type(func2(c)) # N: Revealed type is "builtins.int" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralAndGenericsRespectsValueRestriction] |
| from typing import TypeVar |
| from typing_extensions import Literal |
| |
| TLiteral = TypeVar('TLiteral', Literal[3], Literal['foo']) |
| TNormal = TypeVar('TNormal', int, str) |
| |
| def func1(x: TLiteral) -> TLiteral: pass |
| def func2(x: TNormal) -> TNormal: pass |
| |
| def func3(x: TLiteral) -> TLiteral: |
| y = func2(x) |
| return y # E: Incompatible return value type (got "int", expected "Literal[3]") \ |
| # E: Incompatible return value type (got "str", expected "Literal['foo']") |
| def func4(x: TNormal) -> TNormal: |
| y = func1(x) # E: Value of type variable "TLiteral" of "func1" cannot be "int" \ |
| # E: Value of type variable "TLiteral" of "func1" cannot be "str" |
| return y |
| |
| i1: Literal[3] |
| i2: Literal[4] |
| i: int |
| |
| s1: Literal['foo'] |
| s2: Literal['bar'] |
| s: str |
| |
| reveal_type(func1) # N: Revealed type is "def [TLiteral in (Literal[3], Literal['foo'])] (x: TLiteral`-1) -> TLiteral`-1" |
| |
| reveal_type(func1(3)) # N: Revealed type is "Literal[3]" |
| reveal_type(func1(i1)) # N: Revealed type is "Literal[3]" |
| reveal_type(func1(4)) # E: Value of type variable "TLiteral" of "func1" cannot be "Literal[4]" \ |
| # N: Revealed type is "Literal[4]" |
| reveal_type(func1(i2)) # E: Value of type variable "TLiteral" of "func1" cannot be "Literal[4]" \ |
| # N: Revealed type is "Literal[4]" |
| reveal_type(func1(i)) # E: Value of type variable "TLiteral" of "func1" cannot be "int" \ |
| # N: Revealed type is "builtins.int" |
| reveal_type(func1("foo")) # N: Revealed type is "Literal['foo']" |
| reveal_type(func1(s1)) # N: Revealed type is "Literal['foo']" |
| reveal_type(func1("bar")) # E: Value of type variable "TLiteral" of "func1" cannot be "Literal['bar']" \ |
| # N: Revealed type is "Literal['bar']" |
| reveal_type(func1(s2)) # E: Value of type variable "TLiteral" of "func1" cannot be "Literal['bar']" \ |
| # N: Revealed type is "Literal['bar']" |
| reveal_type(func1(s)) # E: Value of type variable "TLiteral" of "func1" cannot be "str" \ |
| # N: Revealed type is "builtins.str" |
| |
| reveal_type(func2(3)) # N: Revealed type is "builtins.int" |
| reveal_type(func2(i1)) # N: Revealed type is "builtins.int" |
| reveal_type(func2(4)) # N: Revealed type is "builtins.int" |
| reveal_type(func2(i2)) # N: Revealed type is "builtins.int" |
| reveal_type(func2("foo")) # N: Revealed type is "builtins.str" |
| reveal_type(func2(s1)) # N: Revealed type is "builtins.str" |
| reveal_type(func2("bar")) # N: Revealed type is "builtins.str" |
| reveal_type(func2(s2)) # N: Revealed type is "builtins.str" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralAndGenericsWithOverloads] |
| from typing import TypeVar, overload, Union |
| from typing_extensions import Literal |
| |
| @overload |
| def func1(x: Literal[4]) -> Literal[19]: ... |
| @overload |
| def func1(x: int) -> int: ... |
| def func1(x: int) -> int: pass |
| |
| T = TypeVar('T') |
| def identity(x: T) -> T: pass |
| |
| a: Literal[4] |
| b: Literal[5] |
| |
| reveal_type(func1(identity(4))) # N: Revealed type is "Literal[19]" |
| reveal_type(func1(identity(5))) # N: Revealed type is "builtins.int" |
| reveal_type(func1(identity(a))) # N: Revealed type is "Literal[19]" |
| reveal_type(func1(identity(b))) # N: Revealed type is "builtins.int" |
| [builtins fixtures/tuple.pyi] |
| |
| -- |
| -- Interactions with meets |
| -- |
| |
| [case testLiteralMeets] |
| from typing import TypeVar, List, Callable, Union |
| from typing_extensions import Literal |
| |
| a: Callable[[Literal[1]], int] |
| b: Callable[[Literal[2]], str] |
| c: Callable[[int], str] |
| d: Callable[[object], str] |
| e: Callable[[Union[Literal[1], Literal[2]]], str] |
| |
| arr1 = [a, a] |
| arr2 = [a, b] |
| arr3 = [a, c] |
| arr4 = [a, d] |
| arr5 = [a, e] |
| |
| reveal_type(arr1) # N: Revealed type is "builtins.list[def (Literal[1]) -> builtins.int]" |
| reveal_type(arr2) # N: Revealed type is "builtins.list[builtins.function]" |
| reveal_type(arr3) # N: Revealed type is "builtins.list[def (Literal[1]) -> builtins.object]" |
| reveal_type(arr4) # N: Revealed type is "builtins.list[def (Literal[1]) -> builtins.object]" |
| reveal_type(arr5) # N: Revealed type is "builtins.list[def (Literal[1]) -> builtins.object]" |
| |
| # Inspect just only one interesting one |
| lit: Literal[1] |
| reveal_type(arr2[0](lit)) # E: Cannot call function of unknown type \ |
| # N: Revealed type is "Any" |
| |
| T = TypeVar('T') |
| def unify(func: Callable[[T, T], None]) -> T: pass |
| |
| def f1(x: Literal[1], y: Literal[1]) -> None: pass |
| def f2(x: Literal[1], y: Literal[2]) -> None: pass |
| def f3(x: Literal[1], y: int) -> None: pass |
| def f4(x: Literal[1], y: object) -> None: pass |
| def f5(x: Literal[1], y: Union[Literal[1], Literal[2]]) -> None: pass |
| |
| reveal_type(unify(f1)) # N: Revealed type is "Literal[1]" |
| reveal_type(unify(f2)) # N: Revealed type is "None" |
| reveal_type(unify(f3)) # N: Revealed type is "Literal[1]" |
| reveal_type(unify(f4)) # N: Revealed type is "Literal[1]" |
| reveal_type(unify(f5)) # N: Revealed type is "Literal[1]" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testLiteralMeetsWithStrictOptional] |
| # flags: --strict-optional |
| from typing import TypeVar, Callable, Union |
| from typing_extensions import Literal |
| |
| a: Callable[[Literal[1]], int] |
| b: Callable[[Literal[2]], str] |
| lit: Literal[1] |
| |
| arr = [a, b] |
| reveal_type(arr) # N: Revealed type is "builtins.list[builtins.function]" |
| reveal_type(arr[0](lit)) # E: Cannot call function of unknown type \ |
| # N: Revealed type is "Any" |
| |
| T = TypeVar('T') |
| def unify(func: Callable[[T, T], None]) -> T: pass |
| def func(x: Literal[1], y: Literal[2]) -> None: pass |
| |
| reveal_type(unify(func)) # N: Revealed type is "<nothing>" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| |
| -- |
| -- Checks for intelligent indexing |
| -- |
| |
| [case testLiteralIntelligentIndexingTuples] |
| from typing import Tuple, NamedTuple |
| from typing_extensions import Literal |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| class D: pass |
| class E: pass |
| |
| idx0: Literal[0] |
| idx1: Literal[1] |
| idx2: Literal[2] |
| idx3: Literal[3] |
| idx4: Literal[4] |
| idx5: Literal[5] |
| idx_neg1: Literal[-1] |
| |
| tup1: Tuple[A, B, C, D, E] |
| reveal_type(tup1[idx0]) # N: Revealed type is "__main__.A" |
| reveal_type(tup1[idx1]) # N: Revealed type is "__main__.B" |
| reveal_type(tup1[idx2]) # N: Revealed type is "__main__.C" |
| reveal_type(tup1[idx3]) # N: Revealed type is "__main__.D" |
| reveal_type(tup1[idx4]) # N: Revealed type is "__main__.E" |
| reveal_type(tup1[idx_neg1]) # N: Revealed type is "__main__.E" |
| tup1[idx5] # E: Tuple index out of range |
| reveal_type(tup1[idx2:idx4]) # N: Revealed type is "Tuple[__main__.C, __main__.D]" |
| reveal_type(tup1[::idx2]) # N: Revealed type is "Tuple[__main__.A, __main__.C, __main__.E]" |
| |
| Tup2Class = NamedTuple('Tup2Class', [('a', A), ('b', B), ('c', C), ('d', D), ('e', E)]) |
| tup2: Tup2Class |
| reveal_type(tup2[idx0]) # N: Revealed type is "__main__.A" |
| reveal_type(tup2[idx1]) # N: Revealed type is "__main__.B" |
| reveal_type(tup2[idx2]) # N: Revealed type is "__main__.C" |
| reveal_type(tup2[idx3]) # N: Revealed type is "__main__.D" |
| reveal_type(tup2[idx4]) # N: Revealed type is "__main__.E" |
| reveal_type(tup2[idx_neg1]) # N: Revealed type is "__main__.E" |
| tup2[idx5] # E: Tuple index out of range |
| reveal_type(tup2[idx2:idx4]) # N: Revealed type is "Tuple[__main__.C, __main__.D, fallback=__main__.Tup2Class]" |
| reveal_type(tup2[::idx2]) # N: Revealed type is "Tuple[__main__.A, __main__.C, __main__.E, fallback=__main__.Tup2Class]" |
| [builtins fixtures/slice.pyi] |
| [out] |
| |
| [case testLiteralIntelligentIndexingTypedDict] |
| from typing_extensions import Literal |
| from mypy_extensions import TypedDict |
| |
| class Unrelated: pass |
| u: Unrelated |
| |
| class Inner(TypedDict): |
| a: int |
| class Outer(Inner, total=False): |
| b: str |
| |
| a_key: Literal["a"] |
| b_key: Literal["b"] |
| c_key: Literal["c"] |
| |
| d: Outer |
| |
| reveal_type(d[a_key]) # N: Revealed type is "builtins.int" |
| reveal_type(d[b_key]) # N: Revealed type is "builtins.str" |
| d[c_key] # E: TypedDict "Outer" has no key "c" |
| |
| reveal_type(d.get(a_key, u)) # N: Revealed type is "Union[builtins.int, __main__.Unrelated]" |
| reveal_type(d.get(b_key, u)) # N: Revealed type is "Union[builtins.str, __main__.Unrelated]" |
| reveal_type(d.get(c_key, u)) # N: Revealed type is "builtins.object" |
| |
| reveal_type(d.pop(a_key)) # E: Key "a" of TypedDict "Outer" cannot be deleted \ |
| # N: Revealed type is "builtins.int" |
| reveal_type(d.pop(b_key)) # N: Revealed type is "builtins.str" |
| d.pop(c_key) # E: TypedDict "Outer" has no key "c" |
| |
| del d[a_key] # E: Key "a" of TypedDict "Outer" cannot be deleted |
| del d[b_key] |
| del d[c_key] # E: TypedDict "Outer" has no key "c" |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-typeddict.pyi] |
| [out] |
| |
| [case testLiteralIntelligentIndexingUsingFinal] |
| from typing import Tuple, NamedTuple |
| from typing_extensions import Literal, Final |
| from mypy_extensions import TypedDict |
| |
| int_key_good: Final = 0 |
| int_key_bad: Final = 3 |
| str_key_good: Final = "foo" |
| str_key_bad: Final = "missing" |
| |
| class Unrelated: pass |
| |
| MyTuple = NamedTuple('MyTuple', [ |
| ('foo', int), |
| ('bar', str), |
| ]) |
| |
| class MyDict(TypedDict): |
| foo: int |
| bar: str |
| |
| a: Tuple[int, str] |
| b: MyTuple |
| c: MyDict |
| u: Unrelated |
| |
| reveal_type(a[int_key_good]) # N: Revealed type is "builtins.int" |
| reveal_type(b[int_key_good]) # N: Revealed type is "builtins.int" |
| reveal_type(c[str_key_good]) # N: Revealed type is "builtins.int" |
| reveal_type(c.get(str_key_good, u)) # N: Revealed type is "Union[builtins.int, __main__.Unrelated]" |
| reveal_type(c.get(str_key_bad, u)) # N: Revealed type is "builtins.object" |
| |
| a[int_key_bad] # E: Tuple index out of range |
| b[int_key_bad] # E: Tuple index out of range |
| c[str_key_bad] # E: TypedDict "MyDict" has no key "missing" |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-typeddict.pyi] |
| [out] |
| |
| [case testLiteralIntelligentIndexingTupleUnions] |
| from typing import Tuple, NamedTuple |
| from typing_extensions import Literal |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| class D: pass |
| class E: pass |
| |
| idx1: Literal[1, 2] |
| idx2: Literal[3, 4] |
| idx_bad: Literal[1, 20] |
| |
| tup1: Tuple[A, B, C, D, E] |
| Tup2Class = NamedTuple('Tup2Class', [('a', A), ('b', B), ('c', C), ('d', D), ('e', E)]) |
| tup2: Tup2Class |
| |
| reveal_type(tup1[idx1]) # N: Revealed type is "Union[__main__.B, __main__.C]" |
| reveal_type(tup1[idx1:idx2]) # N: Revealed type is "Union[Tuple[__main__.B, __main__.C], Tuple[__main__.B, __main__.C, __main__.D], Tuple[__main__.C], Tuple[__main__.C, __main__.D]]" |
| reveal_type(tup1[0::idx1]) # N: Revealed type is "Union[Tuple[__main__.A, __main__.B, __main__.C, __main__.D, __main__.E], Tuple[__main__.A, __main__.C, __main__.E]]" |
| tup1[idx_bad] # E: Tuple index out of range |
| |
| reveal_type(tup2[idx1]) # N: Revealed type is "Union[__main__.B, __main__.C]" |
| reveal_type(tup2[idx1:idx2]) # N: Revealed type is "Union[Tuple[__main__.B, __main__.C, fallback=__main__.Tup2Class], Tuple[__main__.B, __main__.C, __main__.D, fallback=__main__.Tup2Class], Tuple[__main__.C, fallback=__main__.Tup2Class], Tuple[__main__.C, __main__.D, fallback=__main__.Tup2Class]]" |
| reveal_type(tup2[0::idx1]) # N: Revealed type is "Union[Tuple[__main__.A, __main__.B, __main__.C, __main__.D, __main__.E, fallback=__main__.Tup2Class], Tuple[__main__.A, __main__.C, __main__.E, fallback=__main__.Tup2Class]]" |
| tup2[idx_bad] # E: Tuple index out of range |
| [builtins fixtures/slice.pyi] |
| [out] |
| |
| [case testLiteralIntelligentIndexingTypedDictUnions] |
| from typing_extensions import Literal, Final |
| from mypy_extensions import TypedDict |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| class D: pass |
| class E: pass |
| |
| class Base(TypedDict): |
| a: A |
| b: B |
| c: C |
| |
| class Test(Base, total=False): |
| d: D |
| e: E |
| |
| class AAndB(A, B): pass |
| |
| test: Test |
| good_keys: Literal["a", "b"] |
| optional_keys: Literal["d", "e"] |
| bad_keys: Literal["a", "bad"] |
| |
| reveal_type(test[good_keys]) # N: Revealed type is "Union[__main__.A, __main__.B]" |
| reveal_type(test.get(good_keys)) # N: Revealed type is "Union[__main__.A, __main__.B]" |
| reveal_type(test.get(good_keys, 3)) # N: Revealed type is "Union[__main__.A, Literal[3]?, __main__.B]" |
| reveal_type(test.pop(optional_keys)) # N: Revealed type is "Union[__main__.D, __main__.E]" |
| reveal_type(test.pop(optional_keys, 3)) # N: Revealed type is "Union[__main__.D, __main__.E, Literal[3]?]" |
| reveal_type(test.setdefault(good_keys, AAndB())) # N: Revealed type is "Union[__main__.A, __main__.B]" |
| reveal_type(test.get(bad_keys)) # N: Revealed type is "builtins.object" |
| reveal_type(test.get(bad_keys, 3)) # N: Revealed type is "builtins.object" |
| del test[optional_keys] |
| |
| |
| test[bad_keys] # E: TypedDict "Test" has no key "bad" |
| test.pop(good_keys) # E: Key "a" of TypedDict "Test" cannot be deleted \ |
| # E: Key "b" of TypedDict "Test" cannot be deleted |
| test.pop(bad_keys) # E: Key "a" of TypedDict "Test" cannot be deleted \ |
| # E: TypedDict "Test" has no key "bad" |
| test.setdefault(good_keys, 3) # E: Argument 2 to "setdefault" of "TypedDict" has incompatible type "int"; expected "A" |
| test.setdefault(bad_keys, 3 ) # E: Argument 2 to "setdefault" of "TypedDict" has incompatible type "int"; expected "A" |
| del test[good_keys] # E: Key "a" of TypedDict "Test" cannot be deleted \ |
| # E: Key "b" of TypedDict "Test" cannot be deleted |
| del test[bad_keys] # E: Key "a" of TypedDict "Test" cannot be deleted \ |
| # E: TypedDict "Test" has no key "bad" |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-typeddict.pyi] |
| [out] |
| |
| [case testLiteralIntelligentIndexingTypedDictPython2-skip] |
| # flags: --python-version 2.7 |
| from normal_mod import NormalDict |
| from unicode_mod import UnicodeDict |
| |
| from typing_extensions import Literal |
| |
| normal_dict = NormalDict(key=4) |
| unicode_dict = UnicodeDict(key=4) |
| |
| normal_key = "key" # type: Literal["key"] |
| unicode_key = u"key" # type: Literal[u"key"] |
| |
| # TODO: Make the runtime and mypy behaviors here consistent |
| # |
| # At runtime, all eight of the below operations will successfully return |
| # the int because b"key" == u"key" in Python 2. |
| # |
| # Mypy, in contrast, will accept all the four calls to `some_dict[...]` |
| # but will reject `normal_dict.get(unicode_key)` and `unicode_dict.get(unicode_key)` |
| # because the signature of `.get(...)` accepts only a str, not unicode. |
| # |
| # We get the same behavior if we replace all of the Literal[...] types for |
| # actual string literals. |
| # |
| # See https://github.com/python/mypy/issues/6123 for more details. |
| reveal_type(normal_dict[normal_key]) # N: Revealed type is "builtins.int" |
| reveal_type(normal_dict[unicode_key]) # N: Revealed type is "builtins.int" |
| reveal_type(unicode_dict[normal_key]) # N: Revealed type is "builtins.int" |
| reveal_type(unicode_dict[unicode_key]) # N: Revealed type is "builtins.int" |
| |
| reveal_type(normal_dict.get(normal_key)) # N: Revealed type is "builtins.int" |
| reveal_type(normal_dict.get(unicode_key)) # N: Revealed type is "builtins.int" |
| reveal_type(unicode_dict.get(normal_key)) # N: Revealed type is "builtins.int" |
| reveal_type(unicode_dict.get(unicode_key)) # N: Revealed type is "builtins.int" |
| |
| [file normal_mod.py] |
| from mypy_extensions import TypedDict |
| NormalDict = TypedDict('NormalDict', {'key': int}) |
| |
| [file unicode_mod.py] |
| from __future__ import unicode_literals |
| from mypy_extensions import TypedDict |
| UnicodeDict = TypedDict(b'UnicodeDict', {'key': int}) |
| |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-medium.pyi] |
| |
| [case testLiteralIntelligentIndexingMultiTypedDict] |
| from typing import Union |
| from typing_extensions import Literal |
| from mypy_extensions import TypedDict |
| |
| class A: pass |
| class B: pass |
| class C: pass |
| class D: pass |
| |
| class D1(TypedDict): |
| a: A |
| b: B |
| c: C |
| |
| class D2(TypedDict): |
| b: B |
| c: C |
| d: D |
| |
| x: Union[D1, D2] |
| bad_keys: Literal['a', 'b', 'c', 'd'] |
| good_keys: Literal['b', 'c'] |
| |
| x[bad_keys] # E: TypedDict "D1" has no key "d" \ |
| # E: TypedDict "D2" has no key "a" |
| |
| reveal_type(x[good_keys]) # N: Revealed type is "Union[__main__.B, __main__.C]" |
| reveal_type(x.get(good_keys)) # N: Revealed type is "Union[__main__.B, __main__.C]" |
| reveal_type(x.get(good_keys, 3)) # N: Revealed type is "Union[__main__.B, Literal[3]?, __main__.C]" |
| reveal_type(x.get(bad_keys)) # N: Revealed type is "builtins.object" |
| reveal_type(x.get(bad_keys, 3)) # N: Revealed type is "builtins.object" |
| |
| [builtins fixtures/dict.pyi] |
| [typing fixtures/typing-typeddict.pyi] |
| |
| -- |
| -- Interactions with 'Final' |
| -- |
| |
| [case testLiteralFinalInferredAsLiteral] |
| from typing_extensions import Final, Literal |
| |
| var1: Final = 1 |
| var2: Final = "foo" |
| var3: Final = True |
| var4: Final = None |
| |
| class Foo: |
| classvar1: Final = 1 |
| classvar2: Final = "foo" |
| classvar3: Final = True |
| classvar4: Final = None |
| |
| def __init__(self) -> None: |
| self.instancevar1: Final = 1 |
| self.instancevar2: Final = "foo" |
| self.instancevar3: Final = True |
| self.instancevar4: Final = None |
| |
| def force1(x: Literal[1]) -> None: pass |
| def force2(x: Literal["foo"]) -> None: pass |
| def force3(x: Literal[True]) -> None: pass |
| def force4(x: Literal[None]) -> None: pass |
| |
| reveal_type(var1) # N: Revealed type is "Literal[1]?" |
| reveal_type(var2) # N: Revealed type is "Literal['foo']?" |
| reveal_type(var3) # N: Revealed type is "Literal[True]?" |
| reveal_type(var4) # N: Revealed type is "None" |
| force1(reveal_type(var1)) # N: Revealed type is "Literal[1]" |
| force2(reveal_type(var2)) # N: Revealed type is "Literal['foo']" |
| force3(reveal_type(var3)) # N: Revealed type is "Literal[True]" |
| force4(reveal_type(var4)) # N: Revealed type is "None" |
| |
| reveal_type(Foo.classvar1) # N: Revealed type is "Literal[1]?" |
| reveal_type(Foo.classvar2) # N: Revealed type is "Literal['foo']?" |
| reveal_type(Foo.classvar3) # N: Revealed type is "Literal[True]?" |
| reveal_type(Foo.classvar4) # N: Revealed type is "None" |
| force1(reveal_type(Foo.classvar1)) # N: Revealed type is "Literal[1]" |
| force2(reveal_type(Foo.classvar2)) # N: Revealed type is "Literal['foo']" |
| force3(reveal_type(Foo.classvar3)) # N: Revealed type is "Literal[True]" |
| force4(reveal_type(Foo.classvar4)) # N: Revealed type is "None" |
| |
| f = Foo() |
| reveal_type(f.instancevar1) # N: Revealed type is "Literal[1]?" |
| reveal_type(f.instancevar2) # N: Revealed type is "Literal['foo']?" |
| reveal_type(f.instancevar3) # N: Revealed type is "Literal[True]?" |
| reveal_type(f.instancevar4) # N: Revealed type is "None" |
| force1(reveal_type(f.instancevar1)) # N: Revealed type is "Literal[1]" |
| force2(reveal_type(f.instancevar2)) # N: Revealed type is "Literal['foo']" |
| force3(reveal_type(f.instancevar3)) # N: Revealed type is "Literal[True]" |
| force4(reveal_type(f.instancevar4)) # N: Revealed type is "None" |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralFinalDirectInstanceTypesSupercedeInferredLiteral] |
| from typing_extensions import Final, Literal |
| |
| var1: Final[int] = 1 |
| var2: Final[str] = "foo" |
| var3: Final[bool] = True |
| var4: Final[None] = None |
| |
| class Foo: |
| classvar1: Final[int] = 1 |
| classvar2: Final[str] = "foo" |
| classvar3: Final[bool] = True |
| classvar4: Final[None] = None |
| |
| def __init__(self) -> None: |
| self.instancevar1: Final[int] = 1 |
| self.instancevar2: Final[str] = "foo" |
| self.instancevar3: Final[bool] = True |
| self.instancevar4: Final[None] = None |
| |
| def force1(x: Literal[1]) -> None: pass |
| def force2(x: Literal["foo"]) -> None: pass |
| def force3(x: Literal[True]) -> None: pass |
| def force4(x: Literal[None]) -> None: pass |
| |
| reveal_type(var1) # N: Revealed type is "builtins.int" |
| reveal_type(var2) # N: Revealed type is "builtins.str" |
| reveal_type(var3) # N: Revealed type is "builtins.bool" |
| reveal_type(var4) # N: Revealed type is "None" |
| force1(var1) # E: Argument 1 to "force1" has incompatible type "int"; expected "Literal[1]" |
| force2(var2) # E: Argument 1 to "force2" has incompatible type "str"; expected "Literal['foo']" |
| force3(var3) # E: Argument 1 to "force3" has incompatible type "bool"; expected "Literal[True]" |
| force4(var4) |
| |
| reveal_type(Foo.classvar1) # N: Revealed type is "builtins.int" |
| reveal_type(Foo.classvar2) # N: Revealed type is "builtins.str" |
| reveal_type(Foo.classvar3) # N: Revealed type is "builtins.bool" |
| reveal_type(Foo.classvar4) # N: Revealed type is "None" |
| force1(Foo.classvar1) # E: Argument 1 to "force1" has incompatible type "int"; expected "Literal[1]" |
| force2(Foo.classvar2) # E: Argument 1 to "force2" has incompatible type "str"; expected "Literal['foo']" |
| force3(Foo.classvar3) # E: Argument 1 to "force3" has incompatible type "bool"; expected "Literal[True]" |
| force4(Foo.classvar4) |
| |
| f = Foo() |
| reveal_type(f.instancevar1) # N: Revealed type is "builtins.int" |
| reveal_type(f.instancevar2) # N: Revealed type is "builtins.str" |
| reveal_type(f.instancevar3) # N: Revealed type is "builtins.bool" |
| reveal_type(f.instancevar4) # N: Revealed type is "None" |
| force1(f.instancevar1) # E: Argument 1 to "force1" has incompatible type "int"; expected "Literal[1]" |
| force2(f.instancevar2) # E: Argument 1 to "force2" has incompatible type "str"; expected "Literal['foo']" |
| force3(f.instancevar3) # E: Argument 1 to "force3" has incompatible type "bool"; expected "Literal[True]" |
| force4(f.instancevar4) |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralFinalDirectLiteralTypesForceLiteral] |
| from typing_extensions import Final, Literal |
| |
| var1: Final[Literal[1]] = 1 |
| var2: Final[Literal["foo"]] = "foo" |
| var3: Final[Literal[True]] = True |
| var4: Final[Literal[None]] = None |
| |
| class Foo: |
| classvar1: Final[Literal[1]] = 1 |
| classvar2: Final[Literal["foo"]] = "foo" |
| classvar3: Final[Literal[True]] = True |
| classvar4: Final[Literal[None]] = None |
| |
| def __init__(self) -> None: |
| self.instancevar1: Final[Literal[1]] = 1 |
| self.instancevar2: Final[Literal["foo"]] = "foo" |
| self.instancevar3: Final[Literal[True]] = True |
| self.instancevar4: Final[Literal[None]] = None |
| |
| def force1(x: Literal[1]) -> None: pass |
| def force2(x: Literal["foo"]) -> None: pass |
| def force3(x: Literal[True]) -> None: pass |
| def force4(x: Literal[None]) -> None: pass |
| |
| reveal_type(var1) # N: Revealed type is "Literal[1]" |
| reveal_type(var2) # N: Revealed type is "Literal['foo']" |
| reveal_type(var3) # N: Revealed type is "Literal[True]" |
| reveal_type(var4) # N: Revealed type is "None" |
| force1(reveal_type(var1)) # N: Revealed type is "Literal[1]" |
| force2(reveal_type(var2)) # N: Revealed type is "Literal['foo']" |
| force3(reveal_type(var3)) # N: Revealed type is "Literal[True]" |
| force4(reveal_type(var4)) # N: Revealed type is "None" |
| |
| reveal_type(Foo.classvar1) # N: Revealed type is "Literal[1]" |
| reveal_type(Foo.classvar2) # N: Revealed type is "Literal['foo']" |
| reveal_type(Foo.classvar3) # N: Revealed type is "Literal[True]" |
| reveal_type(Foo.classvar4) # N: Revealed type is "None" |
| force1(reveal_type(Foo.classvar1)) # N: Revealed type is "Literal[1]" |
| force2(reveal_type(Foo.classvar2)) # N: Revealed type is "Literal['foo']" |
| force3(reveal_type(Foo.classvar3)) # N: Revealed type is "Literal[True]" |
| force4(reveal_type(Foo.classvar4)) # N: Revealed type is "None" |
| |
| f = Foo() |
| reveal_type(f.instancevar1) # N: Revealed type is "Literal[1]" |
| reveal_type(f.instancevar2) # N: Revealed type is "Literal['foo']" |
| reveal_type(f.instancevar3) # N: Revealed type is "Literal[True]" |
| reveal_type(f.instancevar4) # N: Revealed type is "None" |
| force1(reveal_type(f.instancevar1)) # N: Revealed type is "Literal[1]" |
| force2(reveal_type(f.instancevar2)) # N: Revealed type is "Literal['foo']" |
| force3(reveal_type(f.instancevar3)) # N: Revealed type is "Literal[True]" |
| force4(reveal_type(f.instancevar4)) # N: Revealed type is "None" |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralFinalErasureInMutableDatastructures1] |
| # flags: --strict-optional |
| from typing_extensions import Final |
| |
| var1: Final = [0, None] |
| var2: Final = (0, None) |
| |
| reveal_type(var1) # N: Revealed type is "builtins.list[Union[builtins.int, None]]" |
| reveal_type(var2) # N: Revealed type is "Tuple[Literal[0]?, None]" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testLiteralFinalErasureInMutableDatastructures2] |
| from typing_extensions import Final, Literal |
| |
| var1: Final = [] |
| var1.append(0) |
| reveal_type(var1) # N: Revealed type is "builtins.list[builtins.int]" |
| |
| var2 = [] |
| var2.append(0) |
| reveal_type(var2) # N: Revealed type is "builtins.list[builtins.int]" |
| |
| x: Literal[0] = 0 |
| var3 = [] |
| var3.append(x) |
| reveal_type(var3) # N: Revealed type is "builtins.list[Literal[0]]" |
| |
| [builtins fixtures/list.pyi] |
| |
| [case testLiteralFinalMismatchCausesError] |
| from typing_extensions import Final, Literal |
| |
| var1: Final[Literal[4]] = 1 # E: Incompatible types in assignment (expression has type "Literal[1]", variable has type "Literal[4]") |
| var2: Final[Literal['bad']] = "foo" # E: Incompatible types in assignment (expression has type "Literal['foo']", variable has type "Literal['bad']") |
| var3: Final[Literal[False]] = True # E: Incompatible types in assignment (expression has type "Literal[True]", variable has type "Literal[False]") |
| |
| class Foo: |
| classvar1: Final[Literal[4]] = 1 # E: Incompatible types in assignment (expression has type "Literal[1]", variable has type "Literal[4]") |
| classvar2: Final[Literal['bad']] = "foo" # E: Incompatible types in assignment (expression has type "Literal['foo']", variable has type "Literal['bad']") |
| classvar3: Final[Literal[False]] = True # E: Incompatible types in assignment (expression has type "Literal[True]", variable has type "Literal[False]") |
| |
| def __init__(self) -> None: |
| self.instancevar1: Final[Literal[4]] = 1 # E: Incompatible types in assignment (expression has type "Literal[1]", variable has type "Literal[4]") |
| self.instancevar2: Final[Literal['bad']] = "foo" # E: Incompatible types in assignment (expression has type "Literal['foo']", variable has type "Literal['bad']") |
| self.instancevar3: Final[Literal[False]] = True # E: Incompatible types in assignment (expression has type "Literal[True]", variable has type "Literal[False]") |
| |
| # TODO: Fix the order in which these error messages are shown to be more consistent. |
| var1 = 10 # E: Cannot assign to final name "var1" \ |
| # E: Incompatible types in assignment (expression has type "Literal[10]", variable has type "Literal[4]") |
| |
| |
| Foo.classvar1 = 10 # E: Cannot assign to final attribute "classvar1" \ |
| # E: Incompatible types in assignment (expression has type "Literal[10]", variable has type "Literal[4]") |
| |
| Foo().instancevar1 = 10 # E: Cannot assign to final attribute "instancevar1" \ |
| # E: Incompatible types in assignment (expression has type "Literal[10]", variable has type "Literal[4]") |
| [builtins fixtures/primitives.pyi] |
| [out] |
| |
| [case testLiteralFinalGoesOnlyOneLevelDown] |
| from typing import Tuple |
| from typing_extensions import Final, Literal |
| |
| a: Final = 1 |
| b: Final = (1, 2) |
| |
| def force1(x: Literal[1]) -> None: pass |
| def force2(x: Tuple[Literal[1], Literal[2]]) -> None: pass |
| |
| reveal_type(a) # N: Revealed type is "Literal[1]?" |
| reveal_type(b) # N: Revealed type is "Tuple[Literal[1]?, Literal[2]?]" |
| |
| force1(a) # ok |
| force2(b) # ok |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralFinalCollectionPropagation] |
| from typing import List |
| from typing_extensions import Final, Literal |
| |
| a: Final = 1 |
| implicit = [a] |
| explicit: List[Literal[1]] = [a] |
| direct = [1] |
| |
| def force1(x: List[Literal[1]]) -> None: pass |
| def force2(x: Literal[1]) -> None: pass |
| |
| reveal_type(implicit) # N: Revealed type is "builtins.list[builtins.int]" |
| force1(reveal_type(implicit)) # E: Argument 1 to "force1" has incompatible type "List[int]"; expected "List[Literal[1]]" \ |
| # N: Revealed type is "builtins.list[builtins.int]" |
| force2(reveal_type(implicit[0])) # E: Argument 1 to "force2" has incompatible type "int"; expected "Literal[1]" \ |
| # N: Revealed type is "builtins.int" |
| |
| reveal_type(explicit) # N: Revealed type is "builtins.list[Literal[1]]" |
| force1(reveal_type(explicit)) # N: Revealed type is "builtins.list[Literal[1]]" |
| force2(reveal_type(explicit[0])) # N: Revealed type is "Literal[1]" |
| |
| reveal_type(direct) # N: Revealed type is "builtins.list[builtins.int]" |
| force1(reveal_type(direct)) # E: Argument 1 to "force1" has incompatible type "List[int]"; expected "List[Literal[1]]" \ |
| # N: Revealed type is "builtins.list[builtins.int]" |
| force2(reveal_type(direct[0])) # E: Argument 1 to "force2" has incompatible type "int"; expected "Literal[1]" \ |
| # N: Revealed type is "builtins.int" |
| [builtins fixtures/list.pyi] |
| [out] |
| |
| [case testLiteralFinalStringTypesPython3] |
| from typing_extensions import Final, Literal |
| |
| a: Final = u"foo" |
| b: Final = "foo" |
| c: Final = b"foo" |
| |
| def force_unicode(x: Literal[u"foo"]) -> None: pass |
| def force_bytes(x: Literal[b"foo"]) -> None: pass |
| |
| force_unicode(reveal_type(a)) # N: Revealed type is "Literal['foo']" |
| force_unicode(reveal_type(b)) # N: Revealed type is "Literal['foo']" |
| force_unicode(reveal_type(c)) # E: Argument 1 to "force_unicode" has incompatible type "Literal[b'foo']"; expected "Literal['foo']" \ |
| # N: Revealed type is "Literal[b'foo']" |
| |
| force_bytes(reveal_type(a)) # E: Argument 1 to "force_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" \ |
| # N: Revealed type is "Literal['foo']" |
| force_bytes(reveal_type(b)) # E: Argument 1 to "force_bytes" has incompatible type "Literal['foo']"; expected "Literal[b'foo']" \ |
| # N: Revealed type is "Literal['foo']" |
| force_bytes(reveal_type(c)) # N: Revealed type is "Literal[b'foo']" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralFinalStringTypesPython2UnicodeLiterals] |
| # flags: --python-version 2.7 |
| from __future__ import unicode_literals |
| from typing_extensions import Final, Literal |
| |
| a = u"foo" # type: Final |
| b = "foo" # type: Final |
| c = b"foo" # type: Final |
| |
| def force_unicode(x): |
| # type: (Literal[u"foo"]) -> None |
| pass |
| def force_bytes(x): |
| # type: (Literal[b"foo"]) -> None |
| pass |
| |
| force_unicode(reveal_type(a)) # N: Revealed type is "Literal[u'foo']" |
| force_unicode(reveal_type(b)) # N: Revealed type is "Literal[u'foo']" |
| force_unicode(reveal_type(c)) # E: Argument 1 to "force_unicode" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" \ |
| # N: Revealed type is "Literal['foo']" |
| |
| force_bytes(reveal_type(a)) # E: Argument 1 to "force_bytes" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" \ |
| # N: Revealed type is "Literal[u'foo']" |
| force_bytes(reveal_type(b)) # E: Argument 1 to "force_bytes" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" \ |
| # N: Revealed type is "Literal[u'foo']" |
| force_bytes(reveal_type(c)) # N: Revealed type is "Literal['foo']" |
| [out] |
| |
| [case testLiteralFinalStringTypesPython2] |
| # flags: --python-version 2.7 |
| from typing_extensions import Final, Literal |
| |
| a = u"foo" # type: Final |
| b = "foo" # type: Final |
| c = b"foo" # type: Final |
| |
| def force_unicode(x): |
| # type: (Literal[u"foo"]) -> None |
| pass |
| def force_bytes(x): |
| # type: (Literal[b"foo"]) -> None |
| pass |
| |
| force_unicode(reveal_type(a)) # N: Revealed type is "Literal[u'foo']" |
| force_unicode(reveal_type(b)) # E: Argument 1 to "force_unicode" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" \ |
| # N: Revealed type is "Literal['foo']" |
| force_unicode(reveal_type(c)) # E: Argument 1 to "force_unicode" has incompatible type "Literal['foo']"; expected "Literal[u'foo']" \ |
| # N: Revealed type is "Literal['foo']" |
| |
| force_bytes(reveal_type(a)) # E: Argument 1 to "force_bytes" has incompatible type "Literal[u'foo']"; expected "Literal['foo']" \ |
| # N: Revealed type is "Literal[u'foo']" |
| force_bytes(reveal_type(b)) # N: Revealed type is "Literal['foo']" |
| force_bytes(reveal_type(c)) # N: Revealed type is "Literal['foo']" |
| [out] |
| |
| [case testLiteralFinalPropagatesThroughGenerics] |
| from typing import TypeVar, Generic |
| from typing_extensions import Final, Literal |
| |
| |
| T = TypeVar('T') |
| |
| class WrapperClass(Generic[T]): |
| def __init__(self, data: T) -> None: |
| self.data = data |
| |
| def wrapper_func(x: T) -> T: |
| return x |
| |
| def force(x: Literal[99]) -> None: pass |
| def over_int(x: WrapperClass[int]) -> None: pass |
| def over_literal(x: WrapperClass[Literal[99]]) -> None: pass |
| |
| var1: Final = 99 |
| w1 = WrapperClass(var1) |
| force(reveal_type(w1.data)) # E: Argument 1 to "force" has incompatible type "int"; expected "Literal[99]" \ |
| # N: Revealed type is "builtins.int" |
| force(reveal_type(WrapperClass(var1).data)) # E: Argument 1 to "force" has incompatible type "int"; expected "Literal[99]" \ |
| # N: Revealed type is "builtins.int" |
| force(reveal_type(wrapper_func(var1))) # N: Revealed type is "Literal[99]" |
| over_int(reveal_type(w1)) # N: Revealed type is "__main__.WrapperClass[builtins.int]" |
| over_literal(reveal_type(w1)) # E: Argument 1 to "over_literal" has incompatible type "WrapperClass[int]"; expected "WrapperClass[Literal[99]]" \ |
| # N: Revealed type is "__main__.WrapperClass[builtins.int]" |
| over_int(reveal_type(WrapperClass(var1))) # N: Revealed type is "__main__.WrapperClass[builtins.int]" |
| over_literal(reveal_type(WrapperClass(var1))) # N: Revealed type is "__main__.WrapperClass[Literal[99]]" |
| |
| w2 = WrapperClass(99) |
| force(reveal_type(w2.data)) # E: Argument 1 to "force" has incompatible type "int"; expected "Literal[99]" \ |
| # N: Revealed type is "builtins.int" |
| force(reveal_type(WrapperClass(99).data)) # E: Argument 1 to "force" has incompatible type "int"; expected "Literal[99]" \ |
| # N: Revealed type is "builtins.int" |
| force(reveal_type(wrapper_func(99))) # N: Revealed type is "Literal[99]" |
| over_int(reveal_type(w2)) # N: Revealed type is "__main__.WrapperClass[builtins.int]" |
| over_literal(reveal_type(w2)) # E: Argument 1 to "over_literal" has incompatible type "WrapperClass[int]"; expected "WrapperClass[Literal[99]]" \ |
| # N: Revealed type is "__main__.WrapperClass[builtins.int]" |
| over_int(reveal_type(WrapperClass(99))) # N: Revealed type is "__main__.WrapperClass[builtins.int]" |
| over_literal(reveal_type(WrapperClass(99))) # N: Revealed type is "__main__.WrapperClass[Literal[99]]" |
| |
| var3: Literal[99] = 99 |
| w3 = WrapperClass(var3) |
| force(reveal_type(w3.data)) # N: Revealed type is "Literal[99]" |
| force(reveal_type(WrapperClass(var3).data)) # N: Revealed type is "Literal[99]" |
| force(reveal_type(wrapper_func(var3))) # N: Revealed type is "Literal[99]" |
| over_int(reveal_type(w3)) # E: Argument 1 to "over_int" has incompatible type "WrapperClass[Literal[99]]"; expected "WrapperClass[int]" \ |
| # N: Revealed type is "__main__.WrapperClass[Literal[99]]" |
| over_literal(reveal_type(w3)) # N: Revealed type is "__main__.WrapperClass[Literal[99]]" |
| over_int(reveal_type(WrapperClass(var3))) # N: Revealed type is "__main__.WrapperClass[builtins.int]" |
| over_literal(reveal_type(WrapperClass(var3))) # N: Revealed type is "__main__.WrapperClass[Literal[99]]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralFinalUsedInLiteralType] |
| |
| from typing_extensions import Literal, Final |
| a: Final[int] = 3 |
| b: Final = 3 |
| c: Final[Literal[3]] = 3 |
| d: Literal[3] |
| |
| # TODO: Consider if we want to support cases 'b' and 'd' or not. |
| # Probably not: we want to mostly keep the 'types' and 'value' worlds distinct. |
| # However, according to final semantics, we ought to be able to substitute "b" with |
| # "3" wherever it's used and get the same behavior -- so maybe we do need to support |
| # at least case "b" for consistency? |
| a_wrap: Literal[4, a] # E: Parameter 2 of Literal[...] is invalid \ |
| # E: Variable "__main__.a" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| b_wrap: Literal[4, b] # E: Parameter 2 of Literal[...] is invalid \ |
| # E: Variable "__main__.b" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| c_wrap: Literal[4, c] # E: Parameter 2 of Literal[...] is invalid \ |
| # E: Variable "__main__.c" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| d_wrap: Literal[4, d] # E: Parameter 2 of Literal[...] is invalid \ |
| # E: Variable "__main__.d" is not valid as a type \ |
| # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralWithFinalPropagation] |
| from typing_extensions import Final, Literal |
| |
| a: Final = 3 |
| b: Final = a |
| c = a |
| |
| def expect_3(x: Literal[3]) -> None: pass |
| expect_3(a) |
| expect_3(b) |
| expect_3(c) # E: Argument 1 to "expect_3" has incompatible type "int"; expected "Literal[3]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralWithFinalPropagationIsNotLeaking] |
| from typing_extensions import Final, Literal |
| |
| final_tuple_direct: Final = (2, 3) |
| final_tuple_indirect: Final = final_tuple_direct |
| mutable_tuple = final_tuple_direct |
| final_list_1: Final = [2] |
| final_list_2: Final = [2, 2] |
| final_dict: Final = {"foo": 2} |
| final_set_1: Final = {2} |
| final_set_2: Final = {2, 2} |
| |
| def expect_2(x: Literal[2]) -> None: pass |
| |
| expect_2(final_tuple_direct[0]) |
| expect_2(final_tuple_indirect[0]) |
| |
| expect_2(mutable_tuple[0]) # E: Argument 1 to "expect_2" has incompatible type "int"; expected "Literal[2]" |
| expect_2(final_list_1[0]) # E: Argument 1 to "expect_2" has incompatible type "int"; expected "Literal[2]" |
| expect_2(final_list_2[0]) # E: Argument 1 to "expect_2" has incompatible type "int"; expected "Literal[2]" |
| expect_2(final_dict["foo"]) # E: Argument 1 to "expect_2" has incompatible type "int"; expected "Literal[2]" |
| expect_2(final_set_1.pop()) # E: Argument 1 to "expect_2" has incompatible type "int"; expected "Literal[2]" |
| expect_2(final_set_2.pop()) # E: Argument 1 to "expect_2" has incompatible type "int"; expected "Literal[2]" |
| [builtins fixtures/isinstancelist.pyi] |
| [typing fixtures/typing-medium.pyi] |
| |
| -- |
| -- Tests for Literals and enums |
| -- |
| |
| [case testLiteralWithEnumsBasic] |
| |
| from typing_extensions import Literal |
| from enum import Enum |
| |
| class Color(Enum): |
| RED = 1 |
| GREEN = 2 |
| BLUE = 3 |
| |
| def func(self) -> int: pass |
| |
| r: Literal[Color.RED] |
| g: Literal[Color.GREEN] |
| b: Literal[Color.BLUE] |
| bad1: Literal[Color] # E: Parameter 1 of Literal[...] is invalid |
| bad2: Literal[Color.func] # E: Function "__main__.Color.func" is not valid as a type \ |
| # N: Perhaps you need "Callable[...]" or a callback protocol? \ |
| # E: Parameter 1 of Literal[...] is invalid |
| bad3: Literal[Color.func()] # E: Invalid type: Literal[...] cannot contain arbitrary expressions |
| |
| def expects_color(x: Color) -> None: pass |
| def expects_red(x: Literal[Color.RED]) -> None: pass |
| def bad_func(x: Color.RED) -> None: pass # E: Invalid type: try using Literal[Color.RED] instead? |
| |
| expects_color(r) |
| expects_color(g) |
| expects_color(b) |
| expects_red(r) |
| expects_red(g) # E: Argument 1 to "expects_red" has incompatible type "Literal[Color.GREEN]"; expected "Literal[Color.RED]" |
| expects_red(b) # E: Argument 1 to "expects_red" has incompatible type "Literal[Color.BLUE]"; expected "Literal[Color.RED]" |
| |
| reveal_type(expects_red) # N: Revealed type is "def (x: Literal[__main__.Color.RED])" |
| reveal_type(r) # N: Revealed type is "Literal[__main__.Color.RED]" |
| reveal_type(r.func()) # N: Revealed type is "builtins.int" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralWithEnumsDefinedInClass] |
| from typing_extensions import Literal |
| from enum import Enum |
| |
| class Wrapper: |
| class Color(Enum): |
| RED = 1 |
| GREEN = 2 |
| BLUE = 3 |
| |
| def foo(x: Literal[Wrapper.Color.RED]) -> None: pass |
| |
| r: Literal[Wrapper.Color.RED] |
| g: Literal[Wrapper.Color.GREEN] |
| |
| foo(r) |
| foo(g) # E: Argument 1 to "foo" has incompatible type "Literal[Color.GREEN]"; expected "Literal[Color.RED]" |
| |
| reveal_type(foo) # N: Revealed type is "def (x: Literal[__main__.Wrapper.Color.RED])" |
| reveal_type(r) # N: Revealed type is "Literal[__main__.Wrapper.Color.RED]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralWithEnumsSimilarDefinitions] |
| from typing_extensions import Literal |
| import mod_a |
| import mod_b |
| |
| def f(x: Literal[mod_a.Test.FOO]) -> None: pass |
| |
| a: Literal[mod_a.Test.FOO] |
| b: Literal[mod_a.Test2.FOO] |
| c: Literal[mod_b.Test.FOO] |
| |
| f(a) |
| f(b) # E: Argument 1 to "f" has incompatible type "Literal[Test2.FOO]"; expected "Literal[Test.FOO]" |
| f(c) # E: Argument 1 to "f" has incompatible type "Literal[mod_b.Test.FOO]"; expected "Literal[mod_a.Test.FOO]" |
| |
| [file mod_a.py] |
| from enum import Enum |
| |
| class Test(Enum): |
| FOO = 1 |
| BAR = 2 |
| |
| class Test2(Enum): |
| FOO = 1 |
| BAR = 2 |
| |
| [file mod_b.py] |
| from enum import Enum |
| |
| class Test(Enum): |
| FOO = 1 |
| BAR = 2 |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralWithEnumsDeclaredUsingCallSyntax] |
| from typing_extensions import Literal |
| from enum import Enum |
| |
| A = Enum('A', 'FOO BAR') |
| B = Enum('B', ['FOO', 'BAR']) |
| C = Enum('C', [('FOO', 1), ('BAR', 2)]) |
| D = Enum('D', {'FOO': 1, 'BAR': 2}) |
| |
| a: Literal[A.FOO] |
| b: Literal[B.FOO] |
| c: Literal[C.FOO] |
| d: Literal[D.FOO] |
| |
| reveal_type(a) # N: Revealed type is "Literal[__main__.A.FOO]" |
| reveal_type(b) # N: Revealed type is "Literal[__main__.B.FOO]" |
| reveal_type(c) # N: Revealed type is "Literal[__main__.C.FOO]" |
| reveal_type(d) # N: Revealed type is "Literal[__main__.D.FOO]" |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testLiteralWithEnumsDerivedEnums] |
| from typing_extensions import Literal |
| from enum import Enum, IntEnum, IntFlag, Flag |
| |
| def expects_int(x: int) -> None: pass |
| |
| class A(Enum): |
| FOO = 1 |
| |
| class B(IntEnum): |
| FOO = 1 |
| |
| class C(IntFlag): |
| FOO = 1 |
| |
| class D(Flag): |
| FOO = 1 |
| |
| a: Literal[A.FOO] |
| b: Literal[B.FOO] |
| c: Literal[C.FOO] |
| d: Literal[D.FOO] |
| |
| expects_int(a) # E: Argument 1 to "expects_int" has incompatible type "Literal[A.FOO]"; expected "int" |
| expects_int(b) |
| expects_int(c) |
| expects_int(d) # E: Argument 1 to "expects_int" has incompatible type "Literal[D.FOO]"; expected "int" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralWithEnumsAliases] |
| from typing_extensions import Literal |
| from enum import Enum |
| |
| class Test(Enum): |
| FOO = 1 |
| BAR = 2 |
| |
| Alias = Test |
| |
| x: Literal[Alias.FOO] |
| reveal_type(x) # N: Revealed type is "Literal[__main__.Test.FOO]" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralUsingEnumAttributesInLiteralContexts] |
| from typing_extensions import Literal, Final |
| from enum import Enum |
| |
| class Test1(Enum): |
| FOO = 1 |
| BAR = 2 |
| Test2 = Enum('Test2', [('FOO', 1), ('BAR', 2)]) |
| |
| def expects_test1_foo(x: Literal[Test1.FOO]) -> None: ... |
| def expects_test2_foo(x: Literal[Test2.FOO]) -> None: ... |
| |
| expects_test1_foo(Test1.FOO) |
| expects_test1_foo(Test1.BAR) # E: Argument 1 to "expects_test1_foo" has incompatible type "Literal[Test1.BAR]"; expected "Literal[Test1.FOO]" |
| expects_test2_foo(Test2.FOO) |
| expects_test2_foo(Test2.BAR) # E: Argument 1 to "expects_test2_foo" has incompatible type "Literal[Test2.BAR]"; expected "Literal[Test2.FOO]" |
| |
| # Make sure the two 'FOO's are not interchangeable |
| expects_test1_foo(Test2.FOO) # E: Argument 1 to "expects_test1_foo" has incompatible type "Literal[Test2.FOO]"; expected "Literal[Test1.FOO]" |
| expects_test2_foo(Test1.FOO) # E: Argument 1 to "expects_test2_foo" has incompatible type "Literal[Test1.FOO]"; expected "Literal[Test2.FOO]" |
| |
| # Make sure enums follow the same semantics as 'x = 1' vs 'x: Final = 1' |
| var1 = Test1.FOO |
| final1: Final = Test1.FOO |
| expects_test1_foo(var1) # E: Argument 1 to "expects_test1_foo" has incompatible type "Test1"; expected "Literal[Test1.FOO]" |
| expects_test1_foo(final1) |
| |
| var2 = Test2.FOO |
| final2: Final = Test2.FOO |
| expects_test2_foo(var2) # E: Argument 1 to "expects_test2_foo" has incompatible type "Test2"; expected "Literal[Test2.FOO]" |
| expects_test2_foo(final2) |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralUsingEnumAttributeNamesInLiteralContexts] |
| from typing_extensions import Literal, Final |
| from enum import Enum |
| |
| class Test1(Enum): |
| FOO = 1 |
| BAR = 2 |
| Test2 = Enum('Test2', [('FOO', 1), ('BAR', 2)]) |
| Test3 = Enum('Test3', 'FOO BAR') |
| Test4 = Enum('Test4', ['FOO', 'BAR']) |
| Test5 = Enum('Test5', {'FOO': 1, 'BAR': 2}) |
| |
| def expects_foo(x: Literal['FOO']) -> None: ... |
| |
| expects_foo(Test1.FOO.name) |
| expects_foo(Test2.FOO.name) |
| expects_foo(Test3.FOO.name) |
| expects_foo(Test4.FOO.name) |
| expects_foo(Test5.FOO.name) |
| |
| expects_foo(Test1.BAR.name) # E: Argument 1 to "expects_foo" has incompatible type "Literal['BAR']"; expected "Literal['FOO']" |
| expects_foo(Test2.BAR.name) # E: Argument 1 to "expects_foo" has incompatible type "Literal['BAR']"; expected "Literal['FOO']" |
| expects_foo(Test3.BAR.name) # E: Argument 1 to "expects_foo" has incompatible type "Literal['BAR']"; expected "Literal['FOO']" |
| expects_foo(Test4.BAR.name) # E: Argument 1 to "expects_foo" has incompatible type "Literal['BAR']"; expected "Literal['FOO']" |
| expects_foo(Test5.BAR.name) # E: Argument 1 to "expects_foo" has incompatible type "Literal['BAR']"; expected "Literal['FOO']" |
| |
| reveal_type(Test1.FOO.name) # N: Revealed type is "Literal['FOO']?" |
| reveal_type(Test2.FOO.name) # N: Revealed type is "Literal['FOO']?" |
| reveal_type(Test3.FOO.name) # N: Revealed type is "Literal['FOO']?" |
| reveal_type(Test4.FOO.name) # N: Revealed type is "Literal['FOO']?" |
| reveal_type(Test5.FOO.name) # N: Revealed type is "Literal['FOO']?" |
| [builtins fixtures/tuple.pyi] |
| [out] |
| |
| [case testLiteralBinderLastValueErased] |
| # mypy: strict-equality |
| |
| from typing_extensions import Literal |
| |
| def takes_three(x: Literal[3]) -> None: ... |
| x: object |
| x = 3 |
| |
| takes_three(x) # E: Argument 1 to "takes_three" has incompatible type "int"; expected "Literal[3]" |
| if x == 2: # OK |
| ... |
| [builtins fixtures/bool.pyi] |
| |
| [case testLiteralBinderLastValueErasedPartialTypes] |
| # mypy: strict-equality |
| |
| def test() -> None: |
| x = None |
| if bool(): |
| x = 1 |
| |
| if x == 2: # OK |
| ... |
| [builtins fixtures/bool.pyi] |
| |
| [case testNegativeIntLiteral] |
| from typing_extensions import Literal |
| |
| a: Literal[-2] = -2 |
| b: Literal[-1] = -1 |
| c: Literal[0] = 0 |
| d: Literal[1] = 1 |
| e: Literal[2] = 2 |
| [out] |
| [builtins fixtures/float.pyi] |
| |
| [case testNegativeIntLiteralWithFinal] |
| from typing_extensions import Literal, Final |
| |
| ONE: Final = 1 |
| x: Literal[-1] = -ONE |
| |
| TWO: Final = 2 |
| THREE: Final = 3 |
| |
| err_code = -TWO |
| if bool(): |
| err_code = -THREE |
| [builtins fixtures/float.pyi] |
| |
| [case testAliasForEnumTypeAsLiteral] |
| from typing_extensions import Literal |
| from enum import Enum |
| |
| class Foo(Enum): |
| A = 1 |
| |
| F = Foo |
| |
| x: Literal[Foo.A] |
| y: Literal[F.A] |
| reveal_type(x) # N: Revealed type is "Literal[__main__.Foo.A]" |
| reveal_type(y) # N: Revealed type is "Literal[__main__.Foo.A]" |
| [builtins fixtures/tuple.pyi] |
| |
| [case testStrictEqualityLiteralTrueVsFalse] |
| # mypy: strict-equality |
| |
| class C: |
| a = True |
| |
| def update(self) -> None: |
| self.a = False |
| |
| c = C() |
| assert c.a is True |
| c.update() |
| assert c.a is False |
| [builtins fixtures/bool.pyi] |
| |
| [case testConditionalBoolLiteralUnionNarrowing] |
| # flags: --warn-unreachable |
| |
| from typing import Union |
| from typing_extensions import Literal |
| |
| class Truth: |
| def __bool__(self) -> Literal[True]: ... |
| |
| class AlsoTruth: |
| def __bool__(self) -> Literal[True]: ... |
| |
| class Lie: |
| def __bool__(self) -> Literal[False]: ... |
| |
| class AnyAnswer: |
| def __bool__(self) -> bool: ... |
| |
| class NoAnswerSpecified: |
| pass |
| |
| x: Union[Truth, Lie] |
| |
| if x: |
| reveal_type(x) # N: Revealed type is "__main__.Truth" |
| else: |
| reveal_type(x) # N: Revealed type is "__main__.Lie" |
| |
| if not x: |
| reveal_type(x) # N: Revealed type is "__main__.Lie" |
| else: |
| reveal_type(x) # N: Revealed type is "__main__.Truth" |
| |
| y: Union[Truth, AlsoTruth, Lie] |
| |
| if y: |
| reveal_type(y) # N: Revealed type is "Union[__main__.Truth, __main__.AlsoTruth]" |
| else: |
| reveal_type(y) # N: Revealed type is "__main__.Lie" |
| |
| z: Union[Truth, AnyAnswer] |
| |
| if z: |
| reveal_type(z) # N: Revealed type is "Union[__main__.Truth, __main__.AnyAnswer]" |
| else: |
| reveal_type(z) # N: Revealed type is "__main__.AnyAnswer" |
| |
| q: Union[Truth, NoAnswerSpecified] |
| |
| if q: |
| reveal_type(q) # N: Revealed type is "Union[__main__.Truth, __main__.NoAnswerSpecified]" |
| else: |
| reveal_type(q) # N: Revealed type is "__main__.NoAnswerSpecified" |
| |
| w: Union[Truth, AlsoTruth] |
| |
| if w: |
| reveal_type(w) # N: Revealed type is "Union[__main__.Truth, __main__.AlsoTruth]" |
| else: |
| reveal_type(w) # E: Statement is unreachable |
| |
| [builtins fixtures/bool.pyi] |
| |
| [case testLiteralAndInstanceSubtyping] |
| # https://github.com/python/mypy/issues/7399 |
| # https://github.com/python/mypy/issues/11232 |
| from typing import Tuple, Union |
| from typing_extensions import Literal, Final |
| |
| x: bool |
| |
| def f() -> Union[Tuple[Literal[True], int], Tuple[Literal[False], str]]: |
| if x: |
| return (True, 5) |
| else: |
| return (False, 'oops') |
| |
| reveal_type(f()) # N: Revealed type is "Union[Tuple[Literal[True], builtins.int], Tuple[Literal[False], builtins.str]]" |
| |
| def does_work() -> Tuple[Literal[1]]: |
| x: Final = (1,) |
| return x |
| |
| def also_works() -> Tuple[Literal[1]]: |
| x: Tuple[Literal[1]] = (1,) |
| return x |
| |
| def invalid_literal_value() -> Tuple[Literal[1]]: |
| x: Final = (2,) |
| return x # E: Incompatible return value type (got "Tuple[int]", expected "Tuple[Literal[1]]") |
| |
| def invalid_literal_type() -> Tuple[Literal[1]]: |
| x: Final = (True,) |
| return x # E: Incompatible return value type (got "Tuple[bool]", expected "Tuple[Literal[1]]") |
| |
| def incorrect_return1() -> Union[Tuple[Literal[True], int], Tuple[Literal[False], str]]: |
| if x: |
| return (False, 5) # E: Incompatible return value type (got "Tuple[bool, int]", expected "Union[Tuple[Literal[True], int], Tuple[Literal[False], str]]") |
| else: |
| return (True, 'oops') # E: Incompatible return value type (got "Tuple[bool, str]", expected "Union[Tuple[Literal[True], int], Tuple[Literal[False], str]]") |
| |
| def incorrect_return2() -> Union[Tuple[Literal[True], int], Tuple[Literal[False], str]]: |
| if x: |
| return (bool(), 5) # E: Incompatible return value type (got "Tuple[bool, int]", expected "Union[Tuple[Literal[True], int], Tuple[Literal[False], str]]") |
| else: |
| return (bool(), 'oops') # E: Incompatible return value type (got "Tuple[bool, str]", expected "Union[Tuple[Literal[True], int], Tuple[Literal[False], str]]") |
| [builtins fixtures/bool.pyi] |