mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-05 08:00:27 +00:00
![]()
Some checks are pending
CI / mkdocs (push) Waiting to run
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / Fuzz for new ty panics (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks-instrumented (push) Blocked by required conditions
CI / benchmarks-walltime (push) Blocked by required conditions
[ty Playground] Release / publish (push) Waiting to run
## Summary This PR adds a new lint, `invalid-await`, for all sorts of reasons why an object may not be `await`able, as discussed in astral-sh/ty#919. Precisely, `__await__` is guarded against being missing, possibly unbound, or improperly defined (expects additional arguments or doesn't return an iterator). Of course, diagnostics need to be fine-tuned. If `__await__` cannot be called with no extra arguments, it indicates an error (or a quirk?) in the method signature, not at the call site. Without any doubt, such an object is not `Awaitable`, but I feel like talking about arguments for an *implicit* call is a bit leaky. I didn't reference any actual diagnostic messages in the lint definition, because I want to hear feedback first. Also, there's no mention of the actual required method signature for `__await__` anywhere in the docs. The only reference I had is the `typing` stub. I basically ended up linking `[Awaitable]` to ["must implement `__await__`"](https://docs.python.org/3/library/collections.abc.html#collections.abc.Awaitable), which is insufficient on its own. ## Test Plan The following code was tested: ```python import asyncio import typing class Awaitable: def __await__(self) -> typing.Generator[typing.Any, None, int]: yield None return 5 class NoDunderMethod: pass class InvalidAwaitArgs: def __await__(self, value: int) -> int: return value class InvalidAwaitReturn: def __await__(self) -> int: return 5 class InvalidAwaitReturnImplicit: def __await__(self): pass async def main() -> None: result = await Awaitable() # valid result = await NoDunderMethod() # `__await__` is missing result = await InvalidAwaitReturn() # `__await__` returns `int`, which is not a valid iterator result = await InvalidAwaitArgs() # `__await__` expects additional arguments and cannot be called implicitly result = await InvalidAwaitReturnImplicit() # `__await__` returns `Unknown`, which is not a valid iterator asyncio.run(main()) ``` --------- Co-authored-by: Carl Meyer <carl@astral.sh> |
||
---|---|---|
.. | ||
annotations | ||
assignment | ||
binary | ||
boolean | ||
boundness_declaredness | ||
call | ||
class | ||
comparison | ||
comprehensions | ||
conditional | ||
dataclasses | ||
declaration | ||
diagnostics | ||
directives | ||
doc | ||
exception | ||
expression | ||
function | ||
generics | ||
ide_support | ||
import | ||
literal | ||
loops | ||
narrow | ||
regression | ||
scopes | ||
shadowing | ||
snapshots | ||
stubs | ||
subscript | ||
suppressions | ||
type_compendium | ||
type_of | ||
type_properties | ||
type_qualifiers | ||
unary | ||
with | ||
.mdformat.toml | ||
async.md | ||
attributes.md | ||
cycle.md | ||
decorators.md | ||
del.md | ||
deprecated.md | ||
descriptor_protocol.md | ||
enums.md | ||
exhaustiveness_checking.md | ||
final.md | ||
instance_layout_conflict.md | ||
intersection_types.md | ||
invalid_syntax.md | ||
known_constants.md | ||
mdtest_config.md | ||
mdtest_custom_typeshed.md | ||
metaclass.md | ||
mro.md | ||
named_tuple.md | ||
overloads.md | ||
pep695_type_aliases.md | ||
properties.md | ||
protocols.md | ||
public_types.md | ||
statically_known_branches.md | ||
sys_platform.md | ||
sys_version_info.md | ||
terminal_statements.md | ||
ty_extensions.md | ||
typed_dict.md | ||
union_types.md | ||
unpacking.md | ||
unreachable.md |