|
85 | 85 | from mypy.scope import Scope |
86 | 86 | from mypy import state, errorcodes as codes |
87 | 87 | from mypy.traverser import has_return_statement, all_return_statements |
88 | | -from mypy.errorcodes import ErrorCode |
| 88 | +from mypy.errorcodes import ErrorCode, UNUSED_AWAITABLE, UNUSED_COROUTINE |
89 | 89 | from mypy.util import is_typeshed_file, is_dunder, is_sunder |
90 | 90 |
|
91 | 91 | T = TypeVar('T') |
@@ -3432,8 +3432,32 @@ def try_infer_partial_type_from_indexed_assignment( |
3432 | 3432 | [key_type, value_type]) |
3433 | 3433 | del partial_types[var] |
3434 | 3434 |
|
| 3435 | + def type_requires_usage(self, typ: Type) -> Optional[Tuple[str, ErrorCode]]: |
| 3436 | + """Some types require usage in all cases. The classic example is |
| 3437 | + an unused coroutine. |
| 3438 | +
|
| 3439 | + In the case that it does require usage, returns a note to attach |
| 3440 | + to the error message. |
| 3441 | + """ |
| 3442 | + proper_type = get_proper_type(typ) |
| 3443 | + if isinstance(proper_type, Instance): |
| 3444 | + # We use different error codes for generic awaitable vs coroutine. |
| 3445 | + # Coroutines are on by default, whereas generic awaitables are not. |
| 3446 | + if proper_type.type.fullname == "typing.Coroutine": |
| 3447 | + return ("Are you missing an await?", UNUSED_COROUTINE) |
| 3448 | + if proper_type.type.get("__await__") is not None: |
| 3449 | + return ("Are you missing an await?", UNUSED_AWAITABLE) |
| 3450 | + return None |
| 3451 | + |
3435 | 3452 | def visit_expression_stmt(self, s: ExpressionStmt) -> None: |
3436 | | - self.expr_checker.accept(s.expr, allow_none_return=True, always_allow_any=True) |
| 3453 | + expr_type = self.expr_checker.accept(s.expr, allow_none_return=True, always_allow_any=True) |
| 3454 | + error_note_and_code = self.type_requires_usage(expr_type) |
| 3455 | + if error_note_and_code: |
| 3456 | + error_note, code = error_note_and_code |
| 3457 | + self.fail( |
| 3458 | + message_registry.TYPE_MUST_BE_USED.format(format_type(expr_type)), s, code=code |
| 3459 | + ) |
| 3460 | + self.note(error_note, s, code=code) |
3437 | 3461 |
|
3438 | 3462 | def visit_return_stmt(self, s: ReturnStmt) -> None: |
3439 | 3463 | """Type check a return statement.""" |
|
0 commit comments