Skip to content

Fix new style union aliases with not ready items - #22172

Merged
ilevkivskyi merged 3 commits into
python:masterfrom
ilevkivskyi:fix-union-attr-alias
Oct 12, 2026
Merged

ilevkivskyi merged 3 commits into
python:masterfrom
ilevkivskyi:fix-union-attr-alias

Conversation

@ilevkivskyi

Copy link
Copy Markdown
Member

Fixes #21263
Fixes #11887

Old style aliases with new style unions are quite tricky, since this requires some heuristics to figure out whether this is a type alias or a regular variable. Things get even trickier when some items are not ready, because our heuristics must be robust w.r.t. to this.

I spent few hours today playing with this, and I don't think there is a fully-principled fix that doesn't involve rewriting a bunch of logic. But I think I have something that is still fairly principled. Namely, in this PR:

  • Handle becomes_typeinfo status for imported placeholders consistently.
  • Put should_wait_rhs() back in sync with can_be_type_alias() w.r.t. OpExpr.
  • Add "backtracking" logic (maybe type alias -> actually a regular variable) for one rare case that is tricky to handle otherwise.

Note, the root cause of the crash is that we normally never change a type alias back to a regular variable. Normal flow for a symbol table entry is always like this None -> PlaceholderNode -> PlaceholderNode(becomes_typeinfo=True) -> SymbolNode (where some steps may be skipped). A lot of logic depends on this, but in the relevant scenarios it is tricky to follow this principle.

cc @JukkaL

@github-actions

This comment has been minimized.

@JukkaL JukkaL left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good, but this still causes a crash (not sure if this has be same root cause though):

class Test(Missing):
    A = 1
    B = 2

AB = Test.A | Test.B
Copy = AB
reveal_type(AB)
reveal_type(Copy)

@ilevkivskyi

Copy link
Copy Markdown
Member Author

@JukkaL Oh this is funny, it was Saturday evening, and just before going to bed I remembered to remove the if isinstance(rvalue, OpExpr) when backtracking specifically because of such scenario, but then decided I will do it in the morning. As you can see I didn't (and likely would just merged it if you wouldn't notice).

@github-actions

Copy link
Copy Markdown
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/settings/context.py:29: error: Variable "prefect.settings.context.SettingKey" is not valid as a type  [valid-type]
- src/prefect/settings/context.py:29: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
- src/prefect/settings/context.py:30: error: Variable "prefect.settings.context.SettingKey" is not valid as a type  [valid-type]
- src/prefect/settings/context.py:30: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
- src/prefect/settings/context.py:31: error: Variable "prefect.settings.context.SettingKey" is not valid as a type  [valid-type]
- src/prefect/settings/context.py:31: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases

@ilevkivskyi
ilevkivskyi merged commit fe98edc into python:master Oct 12, 2026
25 checks passed
@ilevkivskyi
ilevkivskyi deleted the fix-union-attr-alias branch October 12, 2026 12:54
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.

Crash on a type alias to new-style union of unresolved types Implicit type aliases not recognised with PEP 604 + import cycles

2 participants