Skip to content

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

Closed
coderabbit-test/mypy
#2

Description

@bzoracler

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

Activity

  1. added a commit that references this issue on Jun 5, 2025
    faac780
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-type-aliasTypeAlias and other type alias issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions