Skip to content

UP045 fixes None | Optional[None | int] to None | None | int | None #23429

@dscorbett

Description

@dscorbett

Summary

The underlying issue behind #18508 still exists. The following example is contrived, but it implies that the implementation of non-pep604-annotation-optional (UP045) doesn’t properly model the rules of None and |, instead special-casing specific patterns.

$ cat >up045.py <<'# EOF'
from typing import Optional
foo: None | Optional[None | int] = None
# EOF

$ ruff --isolated check --select UP045 up045.py --target-version py313 --fix
Found 1 error (1 fixed, 0 remaining).

$ cat up045.py
from typing import Optional
foo: None | None | int | None = None

$ python3.13 up045.py 2>&1 | tail -n 1
TypeError: unsupported operand type(s) for |: 'NoneType' and 'NoneType'

Version

ruff 0.15.1 (a2f11d2 2026-02-12)

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingfixesRelated to suggested fixes for violations

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions