Skip to content

Conversation

robsdedude
Copy link
Contributor

@robsdedude robsdedude commented Jun 15, 2025

Summary

Make UP045 ignore Optional[NamedTuple] as NamedTuple is a function (not a proper type). Rewriting it to NamedTuple | None breaks at runtime. While type checkers currently accept NamedTuple as a type, they arguably shouldn't. Therefore, we outright ignore it and don't touch or lint on it.

For a more detailed discussion, see the linked issue.

Test Plan

Added examples to the existing tests.

Related Issues

Fixes: #18619

@robsdedude robsdedude force-pushed the fix/18619-up007-named-tuple branch from 687cd54 to ca36006 Compare June 15, 2025 11:08
Copy link
Contributor

github-actions bot commented Jun 15, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@robsdedude robsdedude marked this pull request as ready for review June 15, 2025 11:46
@ntBre ntBre added the rule Implementing or modifying a lint rule label Jun 15, 2025
@ntBre ntBre self-requested a review June 15, 2025 17:21
@robsdedude robsdedude requested a review from ntBre June 24, 2025 19:28
@robsdedude robsdedude changed the title [pyupgrade] Fix UP007: ignore Optional[NamedTuple] [pyupgrade] Fix UP045: ignore Optional[NamedTuple] Jun 24, 2025
Copy link
Contributor

@ntBre ntBre left a comment

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 for UP045. However, we have the same problem for UP007, which is actually the rule from the initial report. Maybe my earlier comments were a bit confusing, but we need to handle both UP045, which replaces Optional[NamedTuple] with NamedTuple | None and UP007, which replaces Union[NamedTuple, int] (for example) with NamedTuple | int, which is also an error.

https://play.ruff.rs/d0e71fc1-5210-4eb0-a0a5-e37b01fb6b11

Comment on lines 135 to 138
// `NamedTuple` is not a type; it's a type constructor. Using it in a type annotation doesn't
// make much sense. But since type checkers will currently (incorrectly) _not_ complain about it
// being used in a type annotation, we just ignore `Optional[typing.NamedTuple]`.
// https://github.com/astral-sh/ruff/issues/18619
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I think this might make sense as the docstring for is_optional_named_tuple instead of here in the middle of the code.

@robsdedude robsdedude requested a review from ntBre June 29, 2025 13:36
Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

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

Thanks!

@ntBre ntBre changed the title [pyupgrade] Fix UP045: ignore Optional[NamedTuple] [pyupgrade] Avoid PEP-604 unions with typing.NamedTuple (UP007, UP045) Jun 30, 2025
@ntBre ntBre merged commit 28ab61d into astral-sh:main Jun 30, 2025
35 checks passed
@robsdedude robsdedude deleted the fix/18619-up007-named-tuple branch June 30, 2025 22:18
iyakushev pushed a commit to iyakushev/ruff that referenced this pull request Jul 1, 2025
… `UP045`) (astral-sh#18682)

<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary
Make `UP045` ignore `Optional[NamedTuple]` as `NamedTuple` is a function
(not a proper type). Rewriting it to `NamedTuple | None` breaks at
runtime. While type checkers currently accept `NamedTuple` as a type,
they arguably shouldn't. Therefore, we outright ignore it and don't
touch or lint on it.

For a more detailed discussion, see the linked issue.

## Test Plan
Added examples to the existing tests.

## Related Issues
Fixes: astral-sh#18619
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rule Implementing or modifying a lint rule
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UP007 crashes with TypeError on all version of Python prior to 3.14 for Optional[typing.NamedTuple]
2 participants