Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[RUF071] Add rule for asyncio.gather#23612

Open
mosauter wants to merge 1 commit intoastral-sh:mainfrom
mosauter:main
Open

[RUF071] Add rule for asyncio.gather#23612
mosauter wants to merge 1 commit intoastral-sh:mainfrom
mosauter:main

Conversation

@mosauter
Copy link
Contributor

This MR adds a new rule, RUF071, IgnoredAsyncioGatherResultsWithException. A name which I'm not really happy with, but I cannot think of a better one. Maybe you have ideas?

Summary

The rule should help users from accidentally ignoring exceptions when using asyncio.gather(..., return_exceptions=True).

Example

async def routine(): ...

task_a = asyncio.create_task(routine())
task_b = asyncio.create_task(routine())

async def main():
    # Good
    _ = await asyncio.gather(task_a, task_b)
    # Bad
    await asyncio.gather(task_a, task_b, return_exceptions=True)  # RUF071

The rule specifically checks for return_exceptions=True (i.e. is constant True). An alternative would be !False but I think of the parameter more as a "Developer decides at implementation" and can't think of a reason why anyone would want "sometimes with exception-as-values" and sometimes not. Therefore I opted for the "less false-positives" option, I'm open for that discussion though.

Test Plan

Added snapshots for RUF071

@astral-sh-bot
Copy link

astral-sh-bot bot commented Feb 27, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+1 -0 violations, +0 -0 fixes in 1 projects; 55 projects unchanged)

reflex-dev/reflex (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ reflex/istate/manager/redis.py:1062:13: RUF071 Do not ignore potential error results

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
RUF071 1 1 0 0 0

@mosauter mosauter marked this pull request as ready for review February 27, 2026 16:34
@mosauter
Copy link
Contributor Author

Sry about the test fail. It seems with a global ruff.toml (i.e. a ~/.config/ruff/ruff.toml) available, a lot of the tests load this as a side-effect. All tests should be fixed now.

@ntBre
Copy link
Contributor

ntBre commented Feb 27, 2026

Thanks for working on this! Is this related to any open issue/discussion? We may need to decide if we want to include this rule before implementing it. I'm slightly surprised to see that flake8-async doesn't have a rule for this if it's a common async anti-pattern, but maybe Amy can speak better to that.

@mosauter
Copy link
Contributor Author

@ntBre No I don't have a discussion/issue on this. This came basically from one of my clients where they used it everywhere (without understanding it really) and the result you see in this MR.

I don't know about "common" though, I personally would be surprised if specifically return_exceptions=True gets used a lot.

@ntBre ntBre added rule Implementing or modifying a lint rule needs-decision Awaiting a decision from a maintainer labels Feb 27, 2026
@amyreese
Copy link
Member

I didn't think this would be a common pattern, but it looks 30k+ results on github search: https://github.com/search?q=%2Fgather%28.*return_exceptions%3DTrue.*%29%2F+AND+NOT+%2F%3D.*gather%2F&type=code

That said, I do believe there are many cases where this pattern would be ok, eg, when the tasks/coroutines need to finish to completion even when one of them fails, but nothing needs to explicitly check their results. return_exceptions=True changes the semantics of gather() so that won't return early after the first exception, otherwise the gather would return immediately upon the first exception, leaving an unspecified number of in-flight tasks still pending in the event loop.

What the caller does with the results is purely dependent on the context of the tasks being executed, and IMO, if it's ok to await a regular gather without checking results, then it should be equally ok to await a gather with return_exceptions=True and not check the results.

@mosauter
Copy link
Contributor Author

mosauter commented Feb 28, 2026

I agree there are situations where it's absolutely okay to ignore exceptions. My best example for this would be the shutdown of an application and finishing 15 async-tasks.

And even there one could argue that the gather hides more than you want. While you're fine with a NoneType/AttributeError you might not be fine with a NotImplementedError that you forgot to remove. But gather ignores both.

Personally I think that to enforce adding _ = ... in those situation is costing almost nothing (also in terms of a readability) and forces you to at least once actively think about it.

In situations where it shouldn't be ignored, it can be really hard to debug. Also because the syntax is nothing that stands out when skim code compared to a suppress or try-except-pass. The added # noqa or _ = gives me more of a hint that "there's something there".

For me the benefit is higher as the cost here.

Furthermore I fear that going forward vibe coded slop will become more prevalent and (also without vibe coding) there will be people who have no clue what the details of this api are.

In regards to what ruff also already has I see this rule as a extension of rules that it has regarding exceptions, especially S110/S112 which both basically amount to "don't ignore exceptions".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-decision Awaiting a decision from a maintainer rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants