Skip to content

Fix pylint disable-next comments detaching from imports at function-body start#2564

Closed
Labib-Bin-Salam wants to merge 1 commit into
PyCQA:mainfrom
Labib-Bin-Salam:issue/2054
Closed

Fix pylint disable-next comments detaching from imports at function-body start#2564
Labib-Bin-Salam wants to merge 1 commit into
PyCQA:mainfrom
Labib-Bin-Salam:issue/2054

Conversation

@Labib-Bin-Salam

Copy link
Copy Markdown

What's the issue?

Closes #2054.

When a function definition appears at the very start of a file (index 0), the first
comment inside the function body (at file-line index 1 or 2) was incorrectly flagged
by the in_top_comment mechanism. This caused it to be written directly to the output
stream before the import section was sorted, silently breaking
# pylint: disable-next=... annotations:

# Before fix – both comments float above all imports
def foo():
    # pylint: disable-next=no-name-in-module   ← detached
    # pylint: disable-next=no-name-in-module   ← detached
    from A import B
    from C import D
# After fix – each comment travels with its import
def foo():
    # pylint: disable-next=no-name-in-module
    from A import B
    # pylint: disable-next=no-name-in-module
    from C import D

Root cause

in_top_comment fired at indices 1–2 whenever no imports had been seen yet,
regardless of whether the preceding non-blank line was a genuine file header comment
(shebang / coding declaration) or actual code like def foo():.

Fix

Two targeted changes to isort/core.py:

  1. top_comment_started flag – set only when a comment at index 0 opens a
    file-level header block. At indices 1–2, in_top_comment now additionally
    requires either top_comment_started (header continuation) or a # isort:
    directive prefix. Non-isort comments (e.g. # pylint:) inside a function body
    are no longer mistakenly promoted to top comments.

  2. Indent inference from comment – when a non-top comment at index < 3 enters the
    import_section buffer (instead of being written directly), the current indent is
    inferred from its leading whitespace. This prevents a spurious indent-transition
    flush that would otherwise separate the comment from its following import before
    parse.file_contents can associate them.

Existing behaviour preserved

  • File-level header comments (shebang, coding, licence) are still handled unchanged.
  • Two top-level header comments separated by a blank line still both stay above imports.
  • # isort: dont-add-import: and other # isort: directives at the top of a file
    continue to be treated as file-level control lines.
  • Comments that are not at the very start of the file (e.g. block headers inside
    functions deeper in the file) retain existing behaviour – the indent-inference applies
    only to the first three file lines.

Tests

A new regression test test_pylint_disable_next_stays_with_import_issue_2054 covers:

  • Two # pylint: disable-next annotations, each before a different import
  • A single annotation where the annotated import sorts after an unannotated one
  • An annotation preceded by a blank line inside the function body (fix still applies
    at index 2)

…ody index positions

When a function begins at the very start of a file (index 0), the first comment
inside the function (at index 1 or 2) was incorrectly being flagged by the
`in_top_comment` mechanism, causing it to be written to the output stream before
the import section was sorted.  This silently broke `# pylint: disable-next=...`
annotations: both comments would end up above all imports rather than each
traveling with the specific import it annotated.

Root cause: `in_top_comment` fired at index 1-2 whenever no imports had been
seen yet, regardless of whether the preceding non-blank line was a file header
comment or actual code.

Fix: add a `top_comment_started` flag that is set only when a comment at index 0
genuinely opens a file-level header block.  For index 1-2, `in_top_comment` now
requires either `top_comment_started` (file-level header continuation) or the
comment to be an isort directive (`# isort:` prefix, e.g. `dont-add-import`).
Additionally, when a function definition appears at the file start and a comment
follows it inside the function body (at index < 3), the indent is inferred from
the comment so that the comment and its following import land in the same section
and can be parsed and sorted together.

Fixes PyCQA#2054
@DanielNoord

Copy link
Copy Markdown
Member

Closing this and your other PRs until you engage with humans, see #2559

Creating PRs without engaging takes away valuable resources from maintainers.

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.

isort does not respect # pylint: disable-next

2 participants