Honor # isort: skip when a __future__ import is present (#2092) - #2574
Merged
DanielNoord merged 1 commit intoJul 4, 2026
Merged
Conversation
DanielNoord
reviewed
Jul 4, 2026
DanielNoord
left a comment
Member
There was a problem hiding this comment.
Please remove the changelog line :)
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2574 +/- ##
=======================================
Coverage 99.25% 99.26%
=======================================
Files 41 41
Lines 3108 3111 +3
Branches 674 674
=======================================
+ Hits 3085 3088 +3
Misses 13 13
Partials 10 10 🚀 New features to boost your workflow:
|
apoorvdarshan
force-pushed
the
fix-isort-skip-with-future-import-2092
branch
from
July 4, 2026 07:58
6bd05dc to
0a9778d
Compare
Contributor
Author
|
Done — removed the changelog line. Thanks for the review! |
A per-line `# isort: skip` directive was ignored when a `__future__` import was present in the same block. Because `__future__` imports are always floated to the top, isort spliced the sorted import block ahead of the skipped line and relocated it below the block, silently violating the directive. Treat a skipped import as a section boundary when earlier imports have already been collected: flush those imports and emit the skipped statement in place so nothing can be sorted above it. Adds a regression test.
apoorvdarshan
force-pushed
the
fix-isort-skip-with-future-import-2092
branch
from
July 4, 2026 08:01
0a9778d to
793a91e
Compare
DanielNoord
approved these changes
Jul 4, 2026
mergify Bot
added a commit
to ArcadeData/arcadedb
that referenced
this pull request
Aug 30, 2026
…[skip ci] Bumps [https://github.com/pycqa/isort](https://github.com/pycqa/isort) from 8.0.1 to 9.0.0. Release notes *Sourced from [https://github.com/pycqa/isort's releases](https://github.com/pycqa/isort/releases).* > 9.0.0 > ----- > > `isort` `9.0.0` is the result of several alpha and beta releases, as well as a small number of fixes added after the last beta. For release notes for the individual alphas and betas we would like to refer to: > > * [9.0.0a2](https://github.com/PyCQA/isort/releases/tag/9.0.0a2) > * [9.0.0a3](https://github.com/PyCQA/isort/releases/tag/9.0.0a3) > * [9.0.0b1](https://github.com/PyCQA/isort/releases/tag/9.0.0b1) > * [9.0.0b2](https://github.com/PyCQA/isort/releases/tag/9.0.0b2) > * [9.0.0b5](https://github.com/PyCQA/isort/releases/tag/9.0.0b5) > > *Skipped version numbers are the result of changes to our release infrastructure that broke while creating the actual releases.* > > Please find below the full release notes for version `9.0.0`, the newest release of `isort` after version `8.0.1`. > > --- > > `isort` `9.0.0` contains some significant changes and improvements. Most notably there is now support for Python 3.15 and its `lazy` imports and we have included several performance improvements as well as providing `mypyc` compiled wheels for all major platforms and supported versions of Python. In our own tests we saw speeds ups of more than 2x and 3x times, but this is highly dependent on the codebase `isort` needs to inspect. > > The full list of changes is as follows: > > 💥 Breaking Changes > ----------------------- > > * Remove logic for deprecated options ([#2498](https://redirect.github.com/pycqa/isort/issues/2498)) [`@DanielNoord`](https://github.com/DanielNoord) > > 🚀 Features > ----------------- > > * Sort lazy import statements ([#2503](https://redirect.github.com/pycqa/isort/issues/2503)) [`@DanielNoord`](https://github.com/DanielNoord) > * Add initial support for Python 3.15 ([#2466](https://redirect.github.com/pycqa/isort/issues/2466)) [`@DanielNoord`](https://github.com/DanielNoord) > * Compile with `mypyc` by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2586](https://redirect.github.com/PyCQA/isort/pull/2586) > * Cache calls to `posixpath.abspath` by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2606](https://redirect.github.com/PyCQA/isort/pull/2606) > * Consider private `stdlib` modules to be `stdlib` ([#2295](https://redirect.github.com/pycqa/isort/issues/2295)) [`@devdanzin`](https://github.com/devdanzin) > * Add CLI Flag for --forced-separate ([PyCQA/isort#2367](https://redirect.github.com/PyCQA/isort/pull/2367)) [`@hirak99`](https://github.com/hirak99) > * Add separate\_packages option ([#2313](https://redirect.github.com/pycqa/isort/issues/2313)) [`@alex-liang3`](https://github.com/alex-liang3) > > 🪲 Fixes > -------------- > > * Fix inline comment duplication across merged `from X import` lines ([#2499](https://redirect.github.com/pycqa/isort/issues/2499)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix src glob patterns passed via CLI ([#2497](https://redirect.github.com/pycqa/isort/issues/2497)) [`@ReinerBRO`](https://github.com/ReinerBRO) > * Fix opening-line comment moving to alias attribute line on wrapped imports ([#2491](https://redirect.github.com/pycqa/isort/issues/2491)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix multi\_line\_output=3/5 ignored when wrapping single imports with inline comments ([#2474](https://redirect.github.com/pycqa/isort/issues/2474)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix false positive in `check_code` when using `float_to_top` + `add_imports` ([#2492](https://redirect.github.com/pycqa/isort/issues/2492)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix: preserve bare `#` inline comments on imports ([#2488](https://redirect.github.com/pycqa/isort/issues/2488)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix grouping of non-aliased imports when mixed with aliased imports from the same module ([#2470](https://redirect.github.com/pycqa/isort/issues/2470)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix [PyCQA/isort#2500](https://redirect.github.com/PyCQA/isort/issues/2500): trusted publishing by [`@staticdev`](https://github.com/staticdev) in [PyCQA/isort#2521](https://redirect.github.com/PyCQA/isort/pull/2521) > * Fix git\_hook lazy=True option by [`@sparrowt`](https://github.com/sparrowt) in [PyCQA/isort#2542](https://redirect.github.com/PyCQA/isort/pull/2542) > * Honor `# isort: off/on/split` during `float_to_top` preprocessing with CRLF input by [`@DanielNoord`](https://github.com/DanielNoord) with [`@Copilot`](https://github.com/Copilot) in [PyCQA/isort#2553](https://redirect.github.com/PyCQA/isort/pull/2553) > * Fix --sort-reexports crash with non-seekable streams (e.g. stdin) by [`@Abdu-Ahmed`](https://github.com/Abdu-Ahmed) in [PyCQA/isort#2547](https://redirect.github.com/PyCQA/isort/pull/2547) > * Fix non-idempotent output with split\_on\_trailing\_comma and a non-default wrap mode by [`@sarathfrancis90`](https://github.com/sarathfrancis90) in [PyCQA/isort#2554](https://redirect.github.com/PyCQA/isort/pull/2554) > * Fix non-idempotent NOQA wrap mode with imports that carry their own comment by [`@sarathfrancis90`](https://github.com/sarathfrancis90) in [PyCQA/isort#2556](https://redirect.github.com/PyCQA/isort/pull/2556) > * Fix NOQA wrap mode accumulating spaces before the comment on each run by [`@sarathfrancis90`](https://github.com/sarathfrancis90) in [PyCQA/isort#2558](https://redirect.github.com/PyCQA/isort/pull/2558) > * Fix NOQA not added to long imports in several output paths by [`@urayoru113`](https://github.com/urayoru113) in [PyCQA/isort#2568](https://redirect.github.com/PyCQA/isort/pull/2568) > * Honor `# isort: skip` when a `__future__` import is present ([#2092](https://redirect.github.com/pycqa/isort/issues/2092)) by [`@apoorvdarshan`](https://github.com/apoorvdarshan) in [PyCQA/isort#2574](https://redirect.github.com/PyCQA/isort/pull/2574) ... (truncated) Changelog *Sourced from [https://github.com/pycqa/isort's changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md).* > ### 9.0.0 August 26 2026 > > * Remove logic for deprecated options ([#2498](https://redirect.github.com/pycqa/isort/issues/2498)) [`@DanielNoord`](https://github.com/DanielNoord) > * Sort lazy import statements ([#2503](https://redirect.github.com/pycqa/isort/issues/2503)) [`@DanielNoord`](https://github.com/DanielNoord) > * Add initial support for Python 3.15 ([#2466](https://redirect.github.com/pycqa/isort/issues/2466)) [`@DanielNoord`](https://github.com/DanielNoord) > * Compile with `mypyc` by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2586](https://redirect.github.com/PyCQA/isort/pull/2586) > * Cache calls to `posixpath.abspath` by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2606](https://redirect.github.com/PyCQA/isort/pull/2606) > * Consider private `stdlib` modules to be `stdlib` ([#2295](https://redirect.github.com/pycqa/isort/issues/2295)) [`@devdanzin`](https://github.com/devdanzin) > * Add CLI Flag for --forced-separate ([PyCQA/isort#2367](https://redirect.github.com/PyCQA/isort/pull/2367)) [`@hirak99`](https://github.com/hirak99) > * Add separate\_packages option ([#2313](https://redirect.github.com/pycqa/isort/issues/2313)) [`@alex-liang3`](https://github.com/alex-liang3) > * Fix inline comment duplication across merged `from X import` lines ([#2499](https://redirect.github.com/pycqa/isort/issues/2499)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix src glob patterns passed via CLI ([#2497](https://redirect.github.com/pycqa/isort/issues/2497)) [`@ReinerBRO`](https://github.com/ReinerBRO) > * Fix opening-line comment moving to alias attribute line on wrapped imports ([#2491](https://redirect.github.com/pycqa/isort/issues/2491)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix multi\_line\_output=3/5 ignored when wrapping single imports with inline comments ([#2474](https://redirect.github.com/pycqa/isort/issues/2474)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix false positive in `check_code` when using `float_to_top` + `add_imports` ([#2492](https://redirect.github.com/pycqa/isort/issues/2492)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix: preserve bare `#` inline comments on imports ([#2488](https://redirect.github.com/pycqa/isort/issues/2488)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix grouping of non-aliased imports when mixed with aliased imports from the same module ([#2470](https://redirect.github.com/pycqa/isort/issues/2470)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix [PyCQA/isort#2500](https://redirect.github.com/PyCQA/isort/issues/2500): trusted publishing by [`@staticdev`](https://github.com/staticdev) in [PyCQA/isort#2521](https://redirect.github.com/PyCQA/isort/pull/2521) > * Fix git\_hook lazy=True option by [`@sparrowt`](https://github.com/sparrowt) in [PyCQA/isort#2542](https://redirect.github.com/PyCQA/isort/pull/2542) > * Honor `# isort: off/on/split` during `float_to_top` preprocessing with CRLF input by [`@DanielNoord`](https://github.com/DanielNoord) with [`@Copilot`](https://github.com/Copilot) in [PyCQA/isort#2553](https://redirect.github.com/PyCQA/isort/pull/2553) > * Fix --sort-reexports crash with non-seekable streams (e.g. stdin) by [`@Abdu-Ahmed`](https://github.com/Abdu-Ahmed) in [PyCQA/isort#2547](https://redirect.github.com/PyCQA/isort/pull/2547) > * Fix non-idempotent output with split\_on\_trailing\_comma and a non-default wrap mode by [`@sarathfrancis90`](https://github.com/sarathfrancis90) in [PyCQA/isort#2554](https://redirect.github.com/PyCQA/isort/pull/2554) > * Fix non-idempotent NOQA wrap mode with imports that carry their own comment by [`@sarathfrancis90`](https://github.com/sarathfrancis90) in [PyCQA/isort#2556](https://redirect.github.com/PyCQA/isort/pull/2556) > * Fix NOQA wrap mode accumulating spaces before the comment on each run by [`@sarathfrancis90`](https://github.com/sarathfrancis90) in [PyCQA/isort#2558](https://redirect.github.com/PyCQA/isort/pull/2558) > * Fix NOQA not added to long imports in several output paths by [`@urayoru113`](https://github.com/urayoru113) in [PyCQA/isort#2568](https://redirect.github.com/PyCQA/isort/pull/2568) > * Honor `# isort: skip` when a `__future__` import is present ([#2092](https://redirect.github.com/pycqa/isort/issues/2092)) by [`@apoorvdarshan`](https://github.com/apoorvdarshan) in [PyCQA/isort#2574](https://redirect.github.com/PyCQA/isort/pull/2574) > * fix: make sorted `__all__` and literals black-compatible ([#2280](https://redirect.github.com/pycqa/isort/issues/2280)) by [`@lord-haffi`](https://github.com/lord-haffi) in [PyCQA/isort#2576](https://redirect.github.com/PyCQA/isort/pull/2576) > * Honor skip comments when sorting reexports by [`@sakshichitnis27`](https://github.com/sakshichitnis27) in [PyCQA/isort#2581](https://redirect.github.com/PyCQA/isort/pull/2581) > * Keep aliased import when the plain name carries a comment by [`@sarathfrancis90`](https://github.com/sarathfrancis90) in [PyCQA/isort#2567](https://redirect.github.com/PyCQA/isort/pull/2567) > * fix: don't crash on --config-root without --resolve-all-configs by [`@Gooh456`](https://github.com/Gooh456) in [PyCQA/isort#2597](https://redirect.github.com/PyCQA/isort/pull/2597) > * fix: check\_code misses lines\_before\_imports-only changes ([#2242](https://redirect.github.com/pycqa/isort/issues/2242)) by [`@gaoflow`](https://github.com/gaoflow) in [PyCQA/isort#2563](https://redirect.github.com/PyCQA/isort/pull/2563) > * Fix preservation of form-feed blank lines by [`@utkarshalpha`](https://github.com/utkarshalpha) in [PyCQA/isort#2599](https://redirect.github.com/PyCQA/isort/pull/2599) > * Small clean up and fix inconsistency in handling of `*` imports by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2619](https://redirect.github.com/PyCQA/isort/pull/2619) > * Fix word-wrapping of 'from ... import \*' into invalid Python ([#2267](https://redirect.github.com/pycqa/isort/issues/2267)) by [`@sudorm-rf0`](https://github.com/sudorm-rf0) in [PyCQA/isort#2624](https://redirect.github.com/PyCQA/isort/pull/2624) > * Fix pylint disable-next comments at the start of imports by [`@Neallin-917`](https://github.com/Neallin-917) in [PyCQA/isort#2628](https://redirect.github.com/PyCQA/isort/pull/2628) > * Keep add\_imports below a prefixed module docstring by [`@Eljees`](https://github.com/Eljees) in [PyCQA/isort#2626](https://redirect.github.com/PyCQA/isort/pull/2626) > * Add read the docs configuration ([#2504](https://redirect.github.com/pycqa/isort/issues/2504)) [`@DanielNoord`](https://github.com/DanielNoord) > * Remove unused and broken dependencies ([#2517](https://redirect.github.com/pycqa/isort/issues/2517)) [`@DanielNoord`](https://github.com/DanielNoord) > * Remove `Any` from `parse.py` ([#2516](https://redirect.github.com/pycqa/isort/issues/2516)) [`@DanielNoord`](https://github.com/DanielNoord) > * Bring documentation in line with old documentation ([#2507](https://redirect.github.com/pycqa/isort/issues/2507)) [`@DanielNoord`](https://github.com/DanielNoord) > * Sync profile docs with implementation ([#2495](https://redirect.github.com/pycqa/isort/issues/2495)) [`@copilot-swe-agent`](https://github.com/copilot-swe-agent) > * Fix the playground ([#2494](https://redirect.github.com/pycqa/isort/issues/2494)) [`@DanielNoord7`](https://github.com/DanielNoord7)) [`@hirak99`](https://github.com/hirak99) > * Remove unused \_ENCODING\_PATTERN regex and re import by [`@duriantaco`](https://github.com/duriantaco) in [PyCQA/isort#2525](https://redirect.github.com/PyCQA/isort/pull/2525) > * Remove references to defunct `git_ignore` config by [`@sparrowt`](https://github.com/sparrowt) in [PyCQA/isort#2531](https://redirect.github.com/PyCQA/isort/pull/2531) > * Fix broken relative links in README and CHANGELOG for both GitHub and Sphinx by [`@rohitshinde08`](https://github.com/rohitshinde08) in [PyCQA/isort#2530](https://redirect.github.com/PyCQA/isort/pull/2530) > * Bump vendored `tomli` by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2579](https://redirect.github.com/PyCQA/isort/pull/2579) > * Document temporary .isorted files by [`@sapunyangkut`](https://github.com/sapunyangkut) in [PyCQA/isort#2580](https://redirect.github.com/PyCQA/isort/pull/2580) > * Remove `cruft` by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2610](https://redirect.github.com/PyCQA/isort/pull/2610) > * Small fixes in preparation for `mypyc` compiled wheels by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2623](https://redirect.github.com/PyCQA/isort/pull/2623) > * Small fixes in preparation for compiling with `mypyc` by [`@DanielNoord`](https://github.com/DanielNoord) in [PyCQA/isort#2625](https://redirect.github.com/PyCQA/isort/pull/2625) ... (truncated) Commits * [`727d119`](PyCQA/isort@727d119) Name the predicate and drive the prefix test off STRING\_PREFIXES * [`dec76bc`](PyCQA/isort@dec76bc) Fix multiline docstring style * [`cb179db`](PyCQA/isort@cb179db) Keep add\_imports below a prefixed module docstring * [`7542f76`](PyCQA/isort@7542f76) test: distinguish pylint disable-next comments * [`9f56767`](PyCQA/isort@9f56767) Fix pylint disable-next comments at top of imports * [`0cba6f6`](PyCQA/isort@0cba6f6) Delete .cruft.json * [`dcdda58`](PyCQA/isort@dcdda58) Remove `if` completely * [`03d3878`](PyCQA/isort@03d3878) Fix check in CI * [`926a147`](PyCQA/isort@926a147) Run less Builds * [`c4ab2e9`](PyCQA/isort@c4ab2e9) Fix `test_importable` for local dev * Additional commits viewable in [compare view](PyCQA/isort@8.0.1...9.0.0) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
netbsd-srcmastr
pushed a commit
to NetBSD/pkgsrc
that referenced
this pull request
Aug 30, 2026
### 9.0.0 August 26 2026 - Remove logic for deprecated options (#2498) @DanielNoord - Sort lazy import statements (#2503) @DanielNoord - Add initial support for Python 3.15 (#2466) @DanielNoord - Compile with `mypyc` by @DanielNoord in PyCQA/isort#2586 - Cache calls to `posixpath.abspath` by @DanielNoord in PyCQA/isort#2606 - Consider private `stdlib` modules to be `stdlib` (#2295) @devdanzin - Add CLI Flag for --forced-separate (PyCQA/isort#2367) @hirak99 - Add separate_packages option (#2313) @alex-liang3 - Fix inline comment duplication across merged `from X import` lines (#2499) @copilot-swe-agent - Fix src glob patterns passed via CLI (#2497) @ReinerBRO - Fix opening-line comment moving to alias attribute line on wrapped imports (#2491) @copilot-swe-agent - Fix multi_line_output=3/5 ignored when wrapping single imports with inline comments (#2474) @copilot-swe-agent - Fix false positive in `check_code` when using `float_to_top` + `add_imports` (#2492) @copilot-swe-agent - Fix: preserve bare `#` inline comments on imports (#2488) @copilot-swe-agent - Fix grouping of non-aliased imports when mixed with aliased imports from the same module (#2470) @copilot-swe-agent - Fix PyCQA/isort#2500: trusted publishing by @staticdev in PyCQA/isort#2521 - Fix git_hook lazy=True option by @sparrowt in PyCQA/isort#2542 - Honor `# isort: off/on/split` during `float_to_top` preprocessing with CRLF input by @DanielNoord with @Copilot in PyCQA/isort#2553 - Fix --sort-reexports crash with non-seekable streams (e.g. stdin) by @Abdu-Ahmed in PyCQA/isort#2547 - Fix non-idempotent output with split_on_trailing_comma and a non-default wrap mode by @sarathfrancis90 in PyCQA/isort#2554 - Fix non-idempotent NOQA wrap mode with imports that carry their own comment by @sarathfrancis90 in PyCQA/isort#2556 - Fix NOQA wrap mode accumulating spaces before the comment on each run by @sarathfrancis90 in PyCQA/isort#2558 - Fix NOQA not added to long imports in several output paths by @urayoru113 in PyCQA/isort#2568 - Honor `# isort: skip` when a `__future__` import is present (#2092) by @apoorvdarshan in PyCQA/isort#2574 - fix: make sorted `__all__` and literals black-compatible (#2280) by @lord-haffi in PyCQA/isort#2576 - Honor skip comments when sorting reexports by @sakshichitnis27 in PyCQA/isort#2581 - Keep aliased import when the plain name carries a comment by @sarathfrancis90 in PyCQA/isort#2567 - fix: don't crash on --config-root without --resolve-all-configs by @Gooh456 in PyCQA/isort#2597 - fix: check_code misses lines_before_imports-only changes (#2242) by @gaoflow in PyCQA/isort#2563 - Fix preservation of form-feed blank lines by @utkarshalpha in PyCQA/isort#2599 - Small clean up and fix inconsistency in handling of `*` imports by @DanielNoord in PyCQA/isort#2619 - Fix word-wrapping of 'from ... import *' into invalid Python (#2267) by @sudorm-rf0 in PyCQA/isort#2624 - Fix pylint disable-next comments at the start of imports by @Neallin-917 in PyCQA/isort#2628 - Keep add_imports below a prefixed module docstring by @Eljees in PyCQA/isort#2626 - Add read the docs configuration (#2504) @DanielNoord - Remove unused and broken dependencies (#2517) @DanielNoord - Remove `Any` from `parse.py` (#2516) @DanielNoord - Bring documentation in line with old documentation (#2507) @DanielNoord - Sync profile docs with implementation (#2495) @copilot-swe-agent - Fix the playground (#2494) @DanielNoord7) @hirak99 - Remove unused _ENCODING_PATTERN regex and re import by @duriantaco in PyCQA/isort#2525 - Remove references to defunct `git_ignore` config by @sparrowt in PyCQA/isort#2531 - Fix broken relative links in README and CHANGELOG for both GitHub and Sphinx by @rohitshinde08 in PyCQA/isort#2530 - Bump vendored `tomli` by @DanielNoord in PyCQA/isort#2579 - Document temporary .isorted files by @sapunyangkut in PyCQA/isort#2580 - Remove `cruft` by @DanielNoord in PyCQA/isort#2610 - Small fixes in preparation for `mypyc` compiled wheels by @DanielNoord in PyCQA/isort#2623 - Small fixes in preparation for compiling with `mypyc` by @DanielNoord in PyCQA/isort#2625 - Fix `test_importable` for local dev by @DanielNoord in PyCQA/isort#2635
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2092.
Problem
A per-line
# isort: skipdirective was silently ignored when a__future__import was present in the same block:became
The skipped import is relocated below the block, violating the directive.
Root cause
__future__imports are always floated to the very top of the file. Internally, isort collapses each contiguous run of imports into a single sorted block that is spliced back in at the position of the first import in the run (parse.pyimport_index). A# isort: skipline is kept out of the sort and re-emitted as a plain "out line", so it can only ever land before or after the whole block — never in the middle.When the skipped import is the first line of its section (the common case), the block is inserted after it and it stays put. But as soon as any real import precedes it — most naturally a floated
__future__import — the block is inserted ahead of the skipped line, pushing it below.Fix
Treat a per-line
isort: skipimport as an implicit section boundary when earlier imports have already been collected into the current section: flush those imports and emit the skipped statement in place, so nothing can be sorted above it. This mirrors isort's existing# isort: splitbehavior and keeps the skipped line exactly where the user put it.The
contains_importsguard is important — it means a skipped import that is already alone in its section (e.g. after a non-import statement) keeps flowing through the existing path unchanged, so trailing-whitespace normalization and other established behaviors are untouched.Verification
test_isort_skip_is_honored_with_future_import_issue_2092totests/unit/test_regressions.py. It fails onmain(the skipped line is relocated) and passes with this change. It also covers an interleaved skip (import/ skip /import) and asserts idempotency.isort.check_code(...)passes).pytest tests/unit/—576 passed(the only non-passing tests are pre-existing and environment-specific: test-ordering pollution intest_importable, which passes in isolation, and tests that shell out to theisortCLI / require the example plugins).ruff checkandruff format --checkclean on the changed files (theprocessmccabe complexity stays within the configured limit — the new predicate is folded into the existing branch), andmypy isort/core.pyreports no issues.CHANGELOG.mdentry.Disclosure: this change was prepared with the assistance of an AI tool (Claude Code). I reproduced the issue, reviewed and verified the fix, the test, and the full test run, and take responsibility for the contribution and will respond to review feedback personally.