Skip to content

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

Draft
7vignesh wants to merge 1 commit into
Agent-Field:mainfrom
7vignesh:fix/ruff-async-lint-620
Draft

chore(sdk/python): enable ruff ASYNC lint rules to gate async/blocking hazards (#620)#812
7vignesh wants to merge 1 commit 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

Copy link
Copy Markdown
Contributor

Performance

SDK Memory Δ Latency Δ Tests Status
Python 9.5 KB +5% 0.36 µs +3%

✓ No regressions detected

@github-actions

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.90% 87.40% ↓ -0.50 pp 🟡
sdk-go 92.40% 92.00% ↑ +0.40 pp 🟢
sdk-python 93.82% 93.73% ↑ +0.09 pp 🟢
sdk-typescript 91.05% 90.42% ↑ +0.63 pp 🟢
web-ui 84.75% 84.79% ↓ -0.04 pp 🟡
aggregate 85.54% 85.75% ↓ -0.21 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.

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.

2 participants