blob: ab6154428343a1a1f897793a342b6acefcac9ab9 [file] [log] [blame]
--
-- 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]