Skip to content

chore(sdk/python): enable ruff ASYNC lint rules to gate async/blocking hazards (#620) - #812

Open
7vignesh wants to merge 5 commits into
Agent-Field:mainfrom
7vignesh:fix/ruff-async-lint-620
Open

chore(sdk/python): enable ruff ASYNC lint rules to gate async/blocking hazards (#620)#812
7vignesh wants to merge 5 commits into
Agent-Field:mainfrom
7vignesh:fix/ruff-async-lint-620

Conversation

@7vignesh

@7vignesh 7vignesh commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

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-ignores so 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

  • Bug fix
  • New feature
  • Refactor / cleanup
  • Docs only
  • Tests only
  • CI / tooling
  • Breaking change

What's now enforced on new code

Rule What it catches
ASYNC210 requests.* blocking HTTP call inside an async function
ASYNC230 open() blocking file I/O inside an async function
ASYNC240 os.path.* / pathlib.Path.* blocking methods inside an async function
ASYNC110 asyncio.sleep in a while loop (use asyncio.Event instead)

Existing violations (25 total, suppressed for now)

File Violations
agentfield/agent.py ASYNC210 (1)
agentfield/agent_ai.py ASYNC230 (1), ASYNC240 (2)
agentfield/harness/_runner.py ASYNC240 (3)
agentfield/harness/providers/opencode.py ASYNC240 (1)
agentfield/memory_events.py ASYNC210 (1)
5 test files ASYNC110, ASYNC230, ASYNC240 (16)

These are documented in per-file-ignores with a comment referencing #620 and will be resolved in the subsequent behavioural slices.

Test plan

  • cd sdk/python && ruff check . passes clean
  • Verified that new ASYNC violations in fresh code are caught (tested manually with a sample file containing requests.get inside an async def)
  • Existing tests still pass (31 passed in spot check)

Test coverage

  • I ran tests for the surface(s) I changed locally.
  • New code paths are covered by tests in this PR (no bare additions).
  • N/A no code removed

Checklist

Related issues / PRs

Part of #620
Builds on #799 (loop-aware teardown fix for ResultCache / AsyncExecutionManager / ConnectionManager)

…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.
Copilot AI review requested due to automatic review settings July 22, 2026 11:06

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Performance

SDK Memory Δ Latency Δ Tests Status
Python 9.0 KB - 0.49 µs +40%
TS 358 B +2% 1.35 µs -32%

✓ No regressions detected

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

📊 Coverage gate

Thresholds from .coverage-gate.toml: per-surface ≥ 84%, aggregate ≥ 85%, max per-surface regression ≤ 1.0 pp, max aggregate regression ≤ 0.50 pp.

Surface Current Baseline Δ
control-plane 86.80% 87.40% ↓ -0.60 pp 🟡
sdk-go 92.50% 92.00% ↑ +0.50 pp 🟢
sdk-python 93.82% 93.73% ↑ +0.09 pp 🟢
sdk-typescript 91.05% 90.42% ↑ +0.63 pp 🟢
web-ui 84.76% 84.79% ↓ -0.03 pp 🟡
aggregate 85.51% 85.75% ↓ -0.24 pp 🟡

✅ Gate passed

No surface regressed past the allowed threshold and the aggregate stayed above the floor.

@github-actions

Copy link
Copy Markdown
Contributor

📐 Patch coverage gate

Threshold: 80% on lines this PR touches vs origin/main (from .coverage-gate.toml:thresholds.min_patch).

Surface Touched lines Patch coverage Status
control-plane 0 ➖ no changes
sdk-go 0 ➖ no changes
sdk-python 0 ➖ no changes
sdk-typescript 0 ➖ no changes
web-ui 0 ➖ no changes

✅ Patch gate passed

Every surface whose lines were touched by this PR has patch coverage at or above the threshold.

@AbirAbbas

Copy link
Copy Markdown
Contributor

@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.

Copilot AI review requested due to automatic review settings July 28, 2026 23:28

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 28, 2026 23:43

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@7vignesh
7vignesh marked this pull request as ready for review July 28, 2026 23:50
@7vignesh
7vignesh requested review from a team and AbirAbbas as code owners July 28, 2026 23:50
@7vignesh

Copy link
Copy Markdown
Contributor Author

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:

  • asyncio.run() inside a running loop (6 sites in agent.py / agent_serverless.py)
  • Blocking requests calls on the event loop (the sync poll path in client.py)
  • Lock timeout hygiene (the ~40 no-timeout lock acquisitions)

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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants