Skip to content

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

Closed
coderabbit-test/mypy
#2
@bzoracler

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

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