Skip to content

Conversation

@cdce8p
Copy link
Collaborator

@cdce8p cdce8p commented Nov 29, 2025

Start updating the test output (errors and reveal type) to use the PEP 604 union syntax. The process is similar to what we did last year when we adopted PEP 585 generics in the test output.

As we still default to Python 3.9 for type checking, this PR adds a temporary internal flag --overwrite-union-syntax to be able to overwrite the output.

This PR only changes a handful of test files so the modifications to mypy itself are clearly visible. The goal is to change the test output for all other tests in followup PRs. Once that's done, I plan to deprecate the --force-union-syntax flag similar to the already deprecated --force-uppercase-builtins.

@bzoracler
Copy link
Contributor

This is peripherally relevant, but has there been previous discussions about the union syntax being rather ambiguous for def callables in reveal_type?

def f1() -> int | None: return 1
def f2() -> int: return 1

reveal_type(f1)                     # Revealed type is "def () -> builtins.int | None"
reveal_type(f2 if int() else None)  # Revealed type is "def () -> builtins.int | None"

@cdce8p
Copy link
Collaborator Author

cdce8p commented Nov 29, 2025

This is peripherally relevant, but has there been previous discussions about the union syntax being rather ambiguous for def callables in reveal_type?

Though ultimately rejected, PEP 677 discusses that here: https://peps.python.org/pep-0677/#making-bind-tighter-than.

@cdce8p
Copy link
Collaborator Author

cdce8p commented Nov 29, 2025

def f1() -> int | None: return 1
def f2() -> int: return 1

reveal_type(f1)                     # Revealed type is "def () -> builtins.int | None"
reveal_type(f2 if int() else None)  # Revealed type is "def () -> builtins.int | None"

We should probably consider adding parentheses to the second example. As a point of comparison, pyright infers it as "(() -> int) | None".

@github-actions
Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@cdce8p
Copy link
Collaborator Author

cdce8p commented Nov 29, 2025

We should probably consider adding parentheses to the second example. As a point of comparison, pyright infers it as "(() -> int) | None".

I'd suggest we fix this after migrating the test output. That way would could immediately see the impact of a potential change. The fix should be a fairly simple change in the TypeStrVisitor.

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.

2 participants