Skip to content

Commit

Permalink
Fix handling of NoReturn in Union return types (#11996)
Browse files Browse the repository at this point in the history
There are several discussions and comments describing the following problem 
(references can be found at the end of the PR summary):

```python
def func() -> str | NoReturn:
    ...

func().lower()
```

At the moment the code results in: `"NoReturn" of "Union[str, NoReturn]" has no 
attribute "lower"`

Make `Union[int, NoReturn]` equivalent to `int` in a return type, because in case 
the function returns it must be `int`.
  • Loading branch information
kreathon authored Jan 18, 2022
1 parent 9b31477 commit 002e309
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 0 deletions.
2 changes: 2 additions & 0 deletions mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ def visit_call_expr_inner(self, e: CallExpr, allow_none_return: bool = False) ->
if isinstance(e.callee, MemberExpr) and e.callee.name == 'format':
self.check_str_format_call(e)
ret_type = get_proper_type(ret_type)
if isinstance(ret_type, UnionType):
ret_type = make_simplified_union(ret_type.items)
if isinstance(ret_type, UninhabitedType) and not ret_type.ambiguous:
self.chk.binder.unreachable()
# Warn on calls to functions that always return None. The check
Expand Down
5 changes: 5 additions & 0 deletions test-data/unit/check-unions.test
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ f(1)
f(None)
f('') # E: Argument 1 to "f" has incompatible type "str"; expected "Optional[int]"

[case testUnionWithNoReturn]
from typing import Union, NoReturn
def f() -> Union[int, NoReturn]: ...
reveal_type(f()) # N: Revealed type is "builtins.int"

[case testUnionSimplificationGenericFunction]
from typing import TypeVar, Union, List
T = TypeVar('T')
Expand Down

0 comments on commit 002e309

Please sign in to comment.