Skip to content

[ruff] Ignore RUF029 when function is decorated with asynccontextmanager#24642

Merged
ntBre merged 2 commits intoastral-sh:mainfrom
augustelalande:asynccontextmanager
Apr 15, 2026
Merged

[ruff] Ignore RUF029 when function is decorated with asynccontextmanager#24642
ntBre merged 2 commits intoastral-sh:mainfrom
augustelalande:asynccontextmanager

Conversation

@augustelalande
Copy link
Copy Markdown
Contributor

Summary

Ignore RUF029 when function is decorated with asynccontextmanager. For example I ran across this when working with FastAPI lifespan https://fastapi.tiangolo.com/advanced/events/

@asynccontextmanager
async def lifespan(app: FastAPI):
    # Load the ML model
    ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model
    yield
    # Clean up the ML models and release the resources
    ml_models.clear()


app = FastAPI(lifespan=lifespan)

Test Plan

Test fixture added

@astral-sh-bot
Copy link
Copy Markdown

astral-sh-bot Bot commented Apr 14, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+4 -10 violations, +0 -0 fixes in 2 projects; 54 projects unchanged)

langchain-ai/langchain (+0 -10 violations, +0 -0 fixes)

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

- libs/core/tests/unit_tests/callbacks/test_async_callback_manager.py:89:15: RUF029 Function `set_counter_var` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py:15:11: RUF029 Function `_checkpointer_memory_aio` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py:45:11: RUF029 Function `_checkpointer_sqlite_aio` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py:51:11: RUF029 Function `_checkpointer_postgres_aio` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py:57:11: RUF029 Function `_checkpointer_postgres_aio_pipe` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_checkpointer.py:63:11: RUF029 Function `_checkpointer_postgres_aio_pool` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_store.py:15:11: RUF029 Function `_store_memory_aio` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_store.py:43:11: RUF029 Function `_store_postgres_aio` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_store.py:50:11: RUF029 Function `_store_postgres_aio_pipe` is declared `async`, but doesn't `await` or use `async` features.
- libs/langchain_v1/tests/unit_tests/agents/conftest_store.py:57:11: RUF029 Function `_store_postgres_aio_pool` is declared `async`, but doesn't `await` or use `async` features.

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

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

+ tests/integration/test_lifespan.py:34:53: RUF100 [*] Unused `noqa` directive (unused: `RUF029`)
+ tests/units/istate/test_proxy.py:56:64: RUF100 [*] Unused `noqa` directive (unused: `RUF029`)
+ tests/units/mock_redis.py:187:26: RUF100 [*] Unused `noqa` directive (unused: `RUF029`)
+ tests/units/utils/test_token_manager.py:250:30: RUF100 [*] Unused `noqa` directive (unused: `RUF029`)

Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
RUF029 10 0 10 0 0
RUF100 4 4 0 0 0

@ntBre ntBre added rule Implementing or modifying a lint rule preview Related to preview mode features labels Apr 15, 2026
Copy link
Copy Markdown
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense to me, thank you!

fn is_async_context_manager(function_def: &ast::StmtFunctionDef, semantic: &SemanticModel) -> bool {
function_def.decorator_list.iter().any(|decorator| {
semantic
.resolve_qualified_name(&decorator.expression)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that we usually use map_callable on decorators to support the case where they're called, but this doesn't seem to be supported for asynccontextmanager:

>>> from contextlib import asynccontextmanager
>>> @asynccontextmanager()
... def foo(): ...
...
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    @asynccontextmanager()
     ~~~~~~~~~~~~~~~~~~~^^
TypeError: asynccontextmanager() missing 1 required positional argument: 'func'

so this seems correct in this case.

@ntBre ntBre changed the title [ruff] Ignore RUF029 when function is decorated with asynccontextmanager [ruff] Ignore RUF029 when function is decorated with asynccontextmanager Apr 15, 2026
@ntBre ntBre merged commit 7d2d447 into astral-sh:main Apr 15, 2026
44 checks passed
@augustelalande augustelalande deleted the asynccontextmanager branch April 15, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Related to preview mode features rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants