Skip to content

Enforce top-level imports via ruff PLC0415#1349

Merged
bdraco merged 1 commit into
aio-libs:masterfrom
bdraco:ruff-enforce-top-level-imports
May 17, 2026
Merged

Enforce top-level imports via ruff PLC0415#1349
bdraco merged 1 commit into
aio-libs:masterfrom
bdraco:ruff-enforce-top-level-imports

Conversation

@bdraco
Copy link
Copy Markdown
Member

@bdraco bdraco commented May 17, 2026

What do these changes do?

Adds PLC0415 (import-outside-top-level) to [tool.ruff.lint]
select alongside the existing I and UP groups. Function-scoped
imports must now opt in with # noqa: PLC0415 plus a comment
explaining why (typically avoiding a heavy optional dependency at
import time). This catches a pattern that LLM contributors frequently
introduce.

There are no opt-outs needed in the tree today: ruff check --select PLC0415 against multidict/, tests/, and benchmarks/
passes as-is. Conditional top-level imports under if TYPE_CHECKING: / if sys.version_info >= ...: / try / except ImportError are not flagged by the rule.

Mirrors the approach taken in yarl PR
#1697, which added the
same rule there for the same reason. Following the AGENTS.md
guidance that each new ruff lint group should be its own PR.

Are there changes in behavior for the user?

No, contributor tooling only.

Is it a substantial burden for the maintainers to support this?

No. The rule has zero opt-outs in the current tree. Future function-
scoped imports must be justified inline with # noqa: PLC0415 and
a comment, which is the explicit intent.

Related issue number

N/A; mirrors the approach taken in yarl #1697.

Checklist

  • I think the code is well written
  • Unit tests for the changes exist: N/A (lint-config-only change; verified by running ruff check and the pre-commit suite against the tree)
  • Documentation reflects the changes: N/A (no user-visible API change)
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt: N/A (no such file in this repo)
  • Add a new news fragment into the CHANGES/ folder (CHANGES/1349.contrib.rst)
Agent run details (optional, for reviewers)

Drafted with Claude Code (Opus 4.7); reviewed by @bdraco.

Verified:

$ ruff check --select PLC0415 multidict/ tests/ benchmarks/
All checks passed!
$ ruff check multidict/ tests/ benchmarks/
All checks passed!
$ ruff format --check multidict/ tests/ benchmarks/
31 files already formatted
$ python3 -m pytest tests/test_circular_imports.py tests/test_mutable_multidict.py --no-cov -q -W ignore::UserWarning
137 passed in 0.33s
$ pre-commit run --all-files
all hooks passed (including mypy py311 + py313)
$ make doc-spelling
5 pre-existing CHANGES.rst misspellings only; the new CHANGES/1349.contrib.rst fragment was checked through the towncrier-fragments preview (with sphinxcontrib-towncrier installed locally) and is clean.

Adds ``PLC0415`` to ``[tool.ruff.lint]`` select. Function-scoped
imports must now opt in with ``# noqa: PLC0415`` plus an inline
comment justifying the reason. Catches a pattern that LLM
contributors frequently introduce. No opt-outs needed in the tree
today; the rule is clean against ``ruff check`` as-is.

Mirrors the approach taken in yarl PR aio-libs/yarl#1697.
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label May 17, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 17, 2026

Merging this PR will not alter performance

✅ 244 untouched benchmarks


Comparing bdraco:ruff-enforce-top-level-imports (75fd49a) with master (d208851)

Open in CodSpeed

@codecov
Copy link
Copy Markdown

codecov Bot commented May 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.86%. Comparing base (5cbcd56) to head (75fd49a).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1349   +/-   ##
=======================================
  Coverage   99.86%   99.86%           
=======================================
  Files          28       28           
  Lines        3627     3627           
  Branches      265      265           
=======================================
  Hits         3622     3622           
  Misses          3        3           
  Partials        2        2           
Flag Coverage Δ
CI-GHA 99.86% <ø> (ø)
pytest 99.86% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bdraco bdraco marked this pull request as ready for review May 17, 2026 20:35
@bdraco bdraco requested review from asvetlov and webknjaz as code owners May 17, 2026 20:35
@bdraco bdraco merged commit 2ffbd51 into aio-libs:master May 17, 2026
55 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant