Skip to content

Commit ef446ea

Browse files
author
Guido van Rossum
committed
Vast strides in accuracy for visit_await_expr().
1 parent 58b0feb commit ef446ea

File tree

2 files changed

+53
-22
lines changed

2 files changed

+53
-22
lines changed

mypy/checker.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,30 +2019,24 @@ def visit_yield_expr(self, e: YieldExpr) -> Type:
20192019
return self.get_generator_receive_type(return_type)
20202020

20212021
def visit_await_expr(self, e: AwaitExpr) -> Type:
2022-
any_type = AnyType()
2023-
awaitable_type = self.named_generic_type('typing.Awaitable', [any_type])
2024-
generator_type = self.named_generic_type('typing.Generator', [any_type] * 3)
2025-
expected_type = UnionType([awaitable_type, generator_type])
2022+
expected_type = self.type_context[-1]
2023+
if expected_type is not None:
2024+
expected_type = self.named_generic_type('typing.Awaitable', [expected_type])
20262025
actual_type = self.accept(e.expr, expected_type)
20272026
if isinstance(actual_type, AnyType):
2028-
return any_type
2029-
if is_subtype(actual_type, generator_type):
2030-
if (isinstance(actual_type, Instance) and len(actual_type.args) == 3
2031-
and actual_type.type.fullname() == 'typing.Generator'):
2032-
return actual_type.args[2]
2033-
else:
2034-
return any_type # Must've been unparameterized Generator.
2035-
elif is_subtype(actual_type, awaitable_type):
2027+
return AnyType()
2028+
awaitable_type = self.named_generic_type('typing.Awaitable', [AnyType()])
2029+
if is_subtype(actual_type, awaitable_type):
20362030
if (isinstance(actual_type, Instance) and len(actual_type.args) == 1
20372031
and actual_type.type.fullname() == 'typing.Awaitable'):
20382032
return actual_type.args[0]
20392033
else:
2040-
return any_type # Must've been unparameterized Awaitable.
2041-
msg = "{} (actual type {}, expected Awaitable or Generator)".format(
2034+
return AnyType() # Must've been unparameterized Awaitable.
2035+
msg = "{} (actual type {}, expected Awaitable)".format(
20422036
messages.INCOMPATIBLE_TYPES_IN_AWAIT,
20432037
self.msg.format(actual_type))
20442038
self.fail(msg, e)
2045-
return any_type
2039+
return AnyType()
20462040

20472041
#
20482042
# Helpers

test-data/unit/check-async-await.test

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,53 @@ async def f() -> int:
2121
return x
2222
[builtins fixtures/async_await.py]
2323

24-
[case testAwaitGenerator]
24+
[case testAwaitDefaultContext]
2525
# options: fast_parser
26-
from typing import Any, Generator
27-
def g() -> Generator[int, int, int]:
28-
x = yield 0
29-
return x
26+
from typing import Any, TypeVar
27+
T = TypeVar('T')
28+
async def f(x: T) -> T:
29+
y = await f(x)
30+
reveal_type(y)
31+
return y
32+
[out]
33+
main: note: In function "f":
34+
main:6: error: Revealed type is 'T`-1'
35+
36+
[case testAwaitAnyContext]
37+
# options: fast_parser
38+
from typing import Any, TypeVar
39+
T = TypeVar('T')
40+
async def f(x: T) -> T:
41+
y = await f(x) # type: Any
42+
reveal_type(y)
43+
return y
44+
[out]
45+
main: note: In function "f":
46+
main:6: error: Revealed type is 'Any'
47+
48+
[case testAwaitExplicitContext]
49+
# options: fast_parser
50+
from typing import Any, TypeVar
51+
T = TypeVar('T')
52+
async def f(x: T) -> T:
53+
y = await f(x) # type: int
54+
reveal_type(y)
55+
[out]
56+
main: note: In function "f":
57+
main:5: error: Argument 1 to "f" has incompatible type "T"; expected "int"
58+
main:6: error: Revealed type is 'builtins.int'
59+
60+
[case testAwaitGeneratorError]
61+
# options: fast_parser
62+
from typing import Any, Iterator
63+
def g() -> Iterator[Any]:
64+
yield
3065
async def f() -> int:
3166
x = await g()
3267
return x
33-
[builtins fixtures/async_await.py]
68+
[out]
69+
main: note: In function "f":
70+
main: error: Incompatible types in await (actual type Iterator[Any], expected Awaitable)
3471

3572
[case testAwaitArgumentError]
3673
# options: fast_parser
@@ -42,7 +79,7 @@ async def f() -> int:
4279
[builtins fixtures/async_await.py]
4380
[out]
4481
main: note: In function "f":
45-
main: error: Incompatible types in await (actual type "int", expected Awaitable or Generator)
82+
main: error: Incompatible types in await (actual type "int", expected Awaitable)
4683

4784
[case testAwaitResultError]
4885
# options: fast_parser

0 commit comments

Comments
 (0)