Skip to content

Type variable defaults aren't checked properly against TypeAliasType(...) aliases #18862

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bzoracler opened this issue Mar 31, 2025 · 0 comments · Fixed by #18884 · May be fixed by coderabbit-test/mypy#2
Closed

Type variable defaults aren't checked properly against TypeAliasType(...) aliases #18862

bzoracler opened this issue Mar 31, 2025 · 0 comments · Fixed by #18884 · May be fixed by coderabbit-test/mypy#2
Labels
bug mypy got something wrong topic-type-alias TypeAlias and other type alias issues

Comments

@bzoracler
Copy link
Contributor

Bug Report, To Reproduce, & Actual Behaviour

Using K = TypeAliasType("K", int) fails here, whereas K: TypeAlias = int does not.

from typing_extensions import TypeAliasType, TypeVar

K = TypeAliasType("K", int)
KeyT = TypeVar("KeyT", str, K, default=K)  # E: TypeVar default must be one of the constraint types  [misc]

Expected Behavior

No issues

Additional information

no_args is True for K: TypeAlias = int, while it is False for K = TypeAliasType("K", int). A quick test indicates that commenting out and not pep_695 here prevents the error from occurring.

mypy/mypy/semanal.py

Lines 4048 to 4058 in 4fb187f

# Note: with the new (lazy) type alias representation we only need to set no_args to True
# if the expected number of arguments is non-zero, so that aliases like `A = List` work
# but not aliases like `A = TypeAliasType("A", List)` as these need explicit type params.
# However, eagerly expanding aliases like Text = str is a nice performance optimization.
no_args = (
isinstance(res, ProperType)
and isinstance(res, Instance)
and not res.args
and not empty_tuple_index
and not pep_695
)

The effect of no_args = False causes the constraints of KeyT to be evaluated as a TypeAliasType instead of being evaluated to an Instance,

mypy/mypy/typeanal.py

Lines 2199 to 2205 in 4fb187f

if max_tv_count == 0 and act_len == 0:
if no_args:
assert isinstance(node.target, Instance) # type: ignore[misc]
# Note: this is the only case where we use an eager expansion. See more info about
# no_args aliases like L = List in the docstring for TypeAlias class.
return Instance(node.target.type, [], line=ctx.line, column=ctx.column)
return TypeAliasType(node, [], line=ctx.line, column=ctx.column)

which then later causes the equality check p_default == value to fail:

mypy/mypy/checkexpr.py

Lines 6203 to 6204 in 4fb187f

if e.values and not any(p_default == value for value in e.values):
self.chk.fail("TypeVar default must be one of the constraint types", e)

Your Environment

  • Mypy version used: 1.15, master
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.9, 3.13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-type-alias TypeAlias and other type alias issues
Projects
None yet
2 participants