chore(sdk/python): enable ruff ASYNC lint rules to gate async/blocking hazards (#620) - #812
chore(sdk/python): enable ruff ASYNC lint rules to gate async/blocking hazards (#620)#8127vignesh wants to merge 5 commits into
Conversation
…g hazards (Agent-Field#620) Enable ruff's flake8-async (ASYNC) ruleset in pyproject.toml to catch blocking calls inside async functions at lint time. This prevents new violations from landing while documenting the 25 existing findings as per-file-ignores to be fixed in follow-up slices. Rules now enforced on new code: - ASYNC210: blocking HTTP calls (requests.*) in async functions - ASYNC230: blocking open() in async functions - ASYNC240: blocking os.path / pathlib in async functions - ASYNC110: asyncio.sleep in while loop (use asyncio.Event) Existing violations (5 production files, 5 test files) are suppressed via per-file-ignores with a comment referencing Agent-Field#620. Each will be resolved in dedicated follow-up PRs covering the behavioural slices (blocking requests offload, asyncio.run guards, lock timeouts). Part of Agent-Field#620.
Performance
✓ No regressions detected |
📊 Coverage gateThresholds from
✅ Gate passedNo surface regressed past the allowed threshold and the aggregate stayed above the floor. |
📐 Patch coverage gateThreshold: 80% on lines this PR touches vs
✅ Patch gate passedEvery surface whose lines were touched by this PR has patch coverage at or above the threshold. |
|
@7vignesh CI has been green on this since the 22nd but it's still marked draft — is it ready for review? If you're still iterating, no rush. If you'd rather hand it off, say so and we'll take it from here. |
|
Hey @AbirAbbas! Sorry about that, was waiting on the scoping questions I asked on #620 but the PR itself has been good to go. Marked it ready now. Quick context: this is slice 1 from my breakdown on #620, just the lint gate. It doesn't fix the existing 25 violations, they're documented as per-file-ignores so we can burn them down in follow-ups without blocking new code from being gated. For the follow-up work, I'm planning to tackle the remaining slices as separate PRs:
Are you good with those as standalone PRs referencing #620, or would you prefer a tracked epic with sub-issues? Happy either way, just want to match how you'd like to review them. |
Summary
Enables ruff's
flake8-async(ASYNC) ruleset so blocking calls inside async functions are caught at lint time. This is slice 1 of the work on #620 the non-behavioural, preventive fix that gates new code immediately while documenting the existing debt.No runtime behaviour changes. Existing violations are suppressed via
per-file-ignoresso CI passes right away; each will be fixed in follow-up slices covering the blocking-requests offload,asyncio.run()guards, and lock timeouts.Type of change
What's now enforced on new code
requests.*blocking HTTP call inside an async functionopen()blocking file I/O inside an async functionos.path.*/pathlib.Path.*blocking methods inside an async functionasyncio.sleepin awhileloop (useasyncio.Eventinstead)Existing violations (25 total, suppressed for now)
agentfield/agent.pyagentfield/agent_ai.pyagentfield/harness/_runner.pyagentfield/harness/providers/opencode.pyagentfield/memory_events.pyThese are documented in
per-file-ignoreswith a comment referencing #620 and will be resolved in the subsequent behavioural slices.Test plan
cd sdk/python && ruff check .passes cleanrequests.getinside anasync def)Test coverage
Checklist
Related issues / PRs
Part of #620
Builds on #799 (loop-aware teardown fix for ResultCache / AsyncExecutionManager / ConnectionManager)