Skip to content

Commit d6c2c01

Browse files
authored
Support determining whether a literal is truthy (#8368)
This means types like Union[Literal[False], str] can be narrowed down more easily.
1 parent 3bd6e47 commit d6c2c01

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

mypy/test/testtypes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,10 +736,10 @@ def test_literal_type(self) -> None:
736736
self.assert_join(UnionType([lit1, lit2]), lit2, UnionType([lit1, lit2]))
737737
self.assert_join(UnionType([lit1, lit2]), a, a)
738738
self.assert_join(UnionType([lit1, lit3]), a, UnionType([a, lit3]))
739-
self.assert_join(UnionType([d, lit3]), lit3, UnionType([d, lit3]))
739+
self.assert_join(UnionType([d, lit3]), lit3, d)
740740
self.assert_join(UnionType([d, lit3]), d, UnionType([d, lit3]))
741-
self.assert_join(UnionType([a, lit1]), lit1, UnionType([a, lit1]))
742-
self.assert_join(UnionType([a, lit1]), lit2, UnionType([a, lit1]))
741+
self.assert_join(UnionType([a, lit1]), lit1, a)
742+
self.assert_join(UnionType([a, lit1]), lit2, a)
743743
self.assert_join(UnionType([lit1, lit2]),
744744
UnionType([lit1, lit2]),
745745
UnionType([lit1, lit2]))

mypy/types.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1591,10 +1591,16 @@ class LiteralType(ProperType):
15911591

15921592
def __init__(self, value: LiteralValue, fallback: Instance,
15931593
line: int = -1, column: int = -1) -> None:
1594-
super().__init__(line, column)
15951594
self.value = value
1595+
super().__init__(line, column)
15961596
self.fallback = fallback
15971597

1598+
def can_be_false_default(self) -> bool:
1599+
return not self.value
1600+
1601+
def can_be_true_default(self) -> bool:
1602+
return bool(self.value)
1603+
15981604
def accept(self, visitor: 'TypeVisitor[T]') -> T:
15991605
return visitor.visit_literal_type(self)
16001606

test-data/unit/check-narrowing.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,3 +965,22 @@ else:
965965
reveal_type(a) # E: Statement is unreachable
966966
reveal_type(b)
967967
[builtins fixtures/primitives.pyi]
968+
969+
[case testNarrowingLiteralTruthiness]
970+
from typing import Union
971+
from typing_extensions import Literal
972+
973+
str_or_false: Union[Literal[False], str]
974+
975+
if str_or_false:
976+
reveal_type(str_or_false) # N: Revealed type is 'builtins.str'
977+
else:
978+
reveal_type(str_or_false) # N: Revealed type is 'Union[Literal[False], builtins.str]'
979+
980+
true_or_false: Literal[True, False]
981+
982+
if true_or_false:
983+
reveal_type(true_or_false) # N: Revealed type is 'Literal[True]'
984+
else:
985+
reveal_type(true_or_false) # N: Revealed type is 'Literal[False]'
986+
[builtins fixtures/primitives.pyi]

0 commit comments

Comments
 (0)