-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Improve consistency of NoReturn #12043
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1952,7 +1952,8 @@ class UnionType(ProperType): | |
def __init__(self, items: Sequence[Type], line: int = -1, column: int = -1, | ||
is_evaluated: bool = True, uses_pep604_syntax: bool = False) -> None: | ||
super().__init__(line, column) | ||
self.items = flatten_nested_unions(items) | ||
items = flatten_nested_unions(items) | ||
self.items = reduce_proper_noreturn_types(items) | ||
self.can_be_true = any(item.can_be_true for item in items) | ||
self.can_be_false = any(item.can_be_false for item in items) | ||
# is_evaluated should be set to false for type comments and string literals | ||
|
@@ -2575,6 +2576,17 @@ def flatten_nested_unions(types: Iterable[Type], | |
return flat_items | ||
|
||
|
||
def reduce_proper_noreturn_types(types: Iterable[Type]) -> List[Type]: | ||
"""Remove one or multiple NoReturn types if there is at least one other type. | ||
|
||
Assumes the union was flattened (except for possible union type aliases). The | ||
implementation CANNOT handle type aliases, because they might not yet be expanded. | ||
""" | ||
filtered: List[Type] = [tp for tp in types if not is_proper_noreturn_type(tp)] | ||
# If nothing is left, we know there was at least one NoReturn. | ||
return filtered if filtered else [UninhabitedType(is_noreturn=True)] | ||
|
||
|
||
def union_items(typ: Type) -> List[ProperType]: | ||
"""Return the flattened items of a union type. | ||
|
||
|
@@ -2611,6 +2623,11 @@ def is_optional(t: Type) -> bool: | |
for e in t.items) | ||
|
||
|
||
def is_proper_noreturn_type(t: Type) -> bool: | ||
return isinstance(t, ProperType) and \ | ||
isinstance(t, UninhabitedType) and t.is_noreturn | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I guess what we should do here is:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is related to the problem of the "Limitation" section.
here Therefore, I limited the implementation to not handle type aliases and added the |
||
|
||
|
||
def remove_optional(typ: Type) -> Type: | ||
typ = get_proper_type(typ) | ||
if isinstance(typ, UnionType): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -385,7 +385,7 @@ from mypy_extensions import NoReturn | |
def no_return() -> NoReturn: pass | ||
def f() -> int: | ||
return 0 | ||
reveal_type(f() or no_return()) # N: Revealed type is "builtins.int" | ||
reveal_type(f() or no_return()) # N: Revealed type is "Union[builtins.int]" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not happen, |
||
[builtins fixtures/dict.pyi] | ||
|
||
[case testNoReturnVariable] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or we can have an empty
types[]
iterable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assumed this cannot happen, because in the call context of this method (constructor of Union) there must be at least one item in the Union.
So are you fine if I just add an
assert len(types) >= 1
and chaning the type oftypes
toList
(instead ofIterable
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be
Sequence
, the same as__init__
has