mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 05:44:56 +00:00
[ty] Add hint if async context manager is used in non-async with statement (#18299)
# Summary Adds a subdiagnostic hint in the following scenario where a synchronous `with` is used with an async context manager: ```py class Manager: async def __aenter__(self): ... async def __aexit__(self, *args): ... # error: [invalid-context-manager] "Object of type `Manager` cannot be used with `with` because it does not implement `__enter__` and `__exit__`" # note: Objects of type `Manager` *can* be used as async context managers # note: Consider using `async with` here with Manager(): ... ``` closes https://github.com/astral-sh/ty/issues/508 ## Test Plan New MD snapshot tests --------- Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
parent
62ef96f51e
commit
1d20cf9570
3 changed files with 147 additions and 1 deletions
|
@ -6133,12 +6133,31 @@ impl<'db> ContextManagerError<'db> {
|
|||
} => format_call_dunder_errors(enter_error, "__enter__", exit_error, "__exit__"),
|
||||
};
|
||||
|
||||
builder.into_diagnostic(
|
||||
let mut diag = builder.into_diagnostic(
|
||||
format_args!(
|
||||
"Object of type `{context_expression}` cannot be used with `with` because {formatted_errors}",
|
||||
context_expression = context_expression_type.display(db)
|
||||
),
|
||||
);
|
||||
|
||||
// If `__aenter__` and `__aexit__` are available, the user may have intended to use `async with` instead of `with`:
|
||||
if let (
|
||||
Ok(_) | Err(CallDunderError::CallError(..)),
|
||||
Ok(_) | Err(CallDunderError::CallError(..)),
|
||||
) = (
|
||||
context_expression_type.try_call_dunder(db, "__aenter__", CallArgumentTypes::none()),
|
||||
context_expression_type.try_call_dunder(
|
||||
db,
|
||||
"__aexit__",
|
||||
CallArgumentTypes::positional([Type::unknown(), Type::unknown(), Type::unknown()]),
|
||||
),
|
||||
) {
|
||||
diag.info(format_args!(
|
||||
"Objects of type `{context_expression}` can be used as async context managers",
|
||||
context_expression = context_expression_type.display(db)
|
||||
));
|
||||
diag.info("Consider using `async with` here");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue