Skip to content

[flake8_pyi] Fix PYI041's fix causing TypeError with None | None | ... - #18637

Merged
ntBre merged 2 commits into
astral-sh:mainfrom
robsdedude:fix/18298-PYI041-fix-causing-type-error
Jun 20, 2025
Merged

ntBre merged 2 commits into
astral-sh:mainfrom
robsdedude:fix/18298-PYI041-fix-causing-type-error

Conversation

@robsdedude

@robsdedude robsdedude commented Jun 11, 2025 •

Copy link
Copy Markdown
Contributor

Summary

Fix PYI041's fix turning None | int | None | float into None | None | float, which raises a TypeError when executed.

The fix consists of making sure that the merged super-type is inserted where the first type that is merged was before.

Test Plan

Tests have been expanded with examples from the issue.

Related Issue

Fixes #18298

@github-actions

github-actions Bot commented Jun 11, 2025 •

Copy link
Copy Markdown
Contributor

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@robsdedude
robsdedude force-pushed the fix/18298-PYI041-fix-causing-type-error branch from 10a6bad to be1fde1 Compare June 11, 2025 21:58
@robsdedude
robsdedude marked this pull request as ready for review June 11, 2025 22:10
@robsdedude
robsdedude requested a review from AlexWaygood as a code owner June 11, 2025 22:10
@ntBre ntBre added bug An issue describing something that isn't working, or a PR that fixes a bug fixes Related to suggested fixes for violations labels Jun 12, 2025

@AlexWaygood AlexWaygood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Comment thread crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI041.py Outdated
Comment thread crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI041.pyi Outdated
Comment thread crates/ruff_linter/src/rules/flake8_pyi/rules/redundant_numeric_union.rs Outdated
Comment on lines +32 to +33
23 23 |
24 |-def f1(arg1: float, *, arg2: float | list[str] | type[bool] | complex) -> None: ... # PYI041
24 |+def f1(arg1: float, *, arg2: list[str] | type[bool] | complex) -> None: ... # PYI041
24 |+def f1(arg1: float, *, arg2: complex | list[str] | type[bool]) -> None: ... # PYI041

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a clever way of fixing the issue, but I'm not totally sure that users will like it if the fix ends up reordering unions like this, even when the unions don't contain None. I think that would be pretty unexpected if I were a Ruff user.

I'm leaning towards just not providing a fix for the rule if there are multiple Nones in the union. It feels easy to understand, and well-written code should never have multiple Nones in a union anyway -- we even have other lints that would already detect that!

@robsdedude robsdedude Jun 12, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Your project, your direction. I personally wouldn't be surprised. I've seen ruff fixes go beyond such changes. Further, I'd think of this more as merging elements in the union than reordering them. The PR will put the super-type in the place of the first type it's subsuming.

Anyway, I'll change the PR to just omit the fix. However, I suggest to only suppress the fix if not in a typing only context (as this is only a problem at runtime).

@robsdedude robsdedude Jun 12, 2025 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While working on this fix, I've noticed that this checker is run before deferred string type annotations are visited and resolved. This means that the lint won't trigger on those. Not sure you'd want that to be changed or whether that's a deliberate design decision. Happy to pour this into an issue to tackle it later if you're interested.

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.

Yeah I think it makes sense to follow up on this, thanks! While testing this in the playground, I noticed that PYI016 does apply to string annotations, so you may be able to copy however it handles this.

@robsdedude
robsdedude requested a review from AlexWaygood June 12, 2025 12:42
@AlexWaygood
AlexWaygood requested a review from ntBre June 17, 2025 09:51

@ntBre ntBre 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.

Thanks, I think this looks good overall. I just had a couple of questions to make sure I'm understanding what's going on.

Comment thread crates/ruff_linter/resources/test/fixtures/flake8_pyi/PYI041_1.py

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.

Yeah I think it makes sense to follow up on this, thanks! While testing this in the playground, I noticed that PYI016 does apply to string annotations, so you may be able to copy however it handles this.

@ntBre ntBre 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.

Questions resolved! I was just confused, as expected.

@ntBre
ntBre merged commit e36611c into astral-sh:main Jun 20, 2025
dcreager added a commit that referenced this pull request Jun 20, 2025
* main:
  Handle parenthesized arguments in `remove_argument` (#18805)
  Unify helpers modules (#18835)
  Normalize some docs sections (#18831)
  [`flake8_pyi`] Fix `PYI041`'s fix causing TypeError with `None | None | ...` (#18637)
@robsdedude
robsdedude deleted the fix/18298-PYI041-fix-causing-type-error branch June 24, 2025 20:52
ntBre added a commit that referenced this pull request Feb 16, 2026
## Summary

While working on #18637, I
[noticed](#18637 (comment))
that PYI041 does not properly resolve string annotations. This PR fixes
that.

## Test Plan
A whole new file with tests has been added.

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
KotlinIsland pushed a commit to KotlinIsland/basedpython that referenced this pull request May 1, 2026
## Summary

While working on astral-sh/ruff#18637, I
[noticed](astral-sh/ruff#18637 (comment))
that PYI041 does not properly resolve string annotations. This PR fixes
that.

## Test Plan
A whole new file with tests has been added.

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug An issue describing something that isn't working, or a PR that fixes a bug fixes Related to suggested fixes for violations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PYI041 fixes None | int | None | float to None | None | float

4 participants