Skip to content

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

Open
7vignesh wants to merge 7 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 7 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)

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.31 µs -11%

✓ 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 87.00% 87.40% ↓ -0.40 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.59% 85.75% ↓ -0.16 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.

@AbirAbbas

Copy link
Copy Markdown
Contributor

@7vignesh hold off merging this — the ready-for-review push seems to have replaced the PR's content with release-bot artifacts. The diff is now: VERSION → 0.1.118-rc.1, a ~21.9k-line CHANGELOG entry (full commit bodies of #817/#820/etc.), and version bumps in the SDK manifests — and the actual ruff ASYNC changes no longer appear anywhere (the only 'ASYNC' matches in the diff are inside the changelog text). Looks like a merge or rebase pulled in a local release commit. CI is green only because version bumps don't fail tests.

Needs a rebase back to just the lint-rule changes on top of current main, then force-push.

@7vignesh
7vignesh force-pushed the fix/ruff-async-lint-620 branch from 5f9454a to 6dd8569 Compare July 29, 2026 17:11
@7vignesh

Copy link
Copy Markdown
Contributor Author

Good catch @AbirAbbas, the merge pulled in release-bot commits that polluted the diff. Just force-pushed a clean rebased branch — it's now a single commit on top of main with only the pyproject.toml ruff config change (40 lines). Should be a clean diff now.

7vignesh added 2 commits July 29, 2026 22:49
…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 29, 2026 17:20
@7vignesh
7vignesh force-pushed the fix/ruff-async-lint-620 branch from 6dd8569 to 38b4954 Compare July 29, 2026 17:20

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 29, 2026 17:31

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 30, 2026 19:14

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 30, 2026 19:53

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 30, 2026 21:42

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.

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