Skip to content

Commit 1bc831a

Browse files
László Vaskócsernazs
László Vaskó
andcommitted
Union types: Support narrowing to Ellipsis (...) cases of Unions
After this change, narrowing to `Ellipsis` works similarly with regards to narrowing as `None` in `Optional`s It would be a good followup refactor to delegate some of the logic from `is_singleton_type` to the actual mypy types so they could decide for themselves if they are representing singleton objects Fixes: #13117 Co-authored-by: Zsolt Cserna <[email protected]>
1 parent b13a450 commit 1bc831a

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

mypy/typeops.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,9 @@ def is_singleton_type(typ: Type) -> bool:
747747
isinstance(typ, NoneType)
748748
or (isinstance(typ, LiteralType)
749749
and (typ.is_enum_literal() or isinstance(typ.value, bool)))
750-
or (isinstance(typ, Instance) and typ.type.is_enum and len(get_enum_values(typ)) == 1)
750+
or (isinstance(typ, Instance) and (
751+
typ.type.is_enum and len(get_enum_values(typ)) == 1
752+
or typ.type.fullname == 'builtins.ellipsis'))
751753
)
752754

753755

test-data/unit/check-unions.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ def f() -> Union[int, None]: pass
137137
x = 1
138138
x = f()
139139

140+
[case testUnionWithEllipsis]
141+
from typing import Union
142+
def f(x: Union[int, EllipsisType]) -> int:
143+
if x is Ellipsis:
144+
reveal_type(x) # N: Revealed type is "builtins.ellipsis"
145+
x = 1
146+
reveal_type(x) # N: Revealed type is "builtins.int"
147+
return x
148+
[builtins fixtures/isinstancelist.pyi]
149+
140150
[case testOptional]
141151
from typing import Optional
142152
def f(x: Optional[int]) -> None: pass

test-data/unit/fixtures/isinstancelist.pyi

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ class type:
1010
def __init__(self, x) -> None: pass
1111

1212
class function: pass
13-
class ellipsis: pass
1413
class classmethod: pass
1514

15+
class ellipsis: pass
16+
EllipsisType = ellipsis
17+
Ellipsis = ellipsis()
18+
1619
def isinstance(x: object, t: Union[type, Tuple]) -> bool: pass
1720
def issubclass(x: object, t: Union[type, Tuple]) -> bool: pass
1821

0 commit comments

Comments
 (0)