Skip to content

(🎁) Support TypeVars in the bounds of other TypeVars #1226

@KotlinIsland

Description

@KotlinIsland
from typing import _T as T, TypeVar

L = TypeVar("L", bound=list[T])  # error: Type variable "typing._T" is unbound

def foo(l: L) -> L | T:  # error: A function returning TypeVar should receive at least one argument containing the same Typevar
    res = l[0]
    if res:
        return res
    return l

a: list[int] | list[str]

reveal_type(foo)  # "def [L <: list[T?], T] (l: L) -> L | T"
reveal_type(foo(a))  # list[int] | list[str]

Expected:

reveal_type(foo)  # "def [T, L <: list[T]] (l: L) -> L | T"
reveal_type(foo(a))  # list[int] | list[str] | int | str

Mypy should understand that T should be bound to foo from L

This is identical to generic TypeAliases:

L: TypeAlias = list[T]
a: L[int]

Here T is unbound, yet it's a valid and semantically sound expression.

Typescript example

The same idea could be represented in TypeScript as:

declare function foo<T, L extends T[]>(l: L): L | T

declare let a: number[] | string[]

let b = foo(a)

Although TS fails to infer the correct type here. (it infers as unknown)

basedmypy

This is partially supported in basedmypy

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: featureDiscussions about new features for Python's type annotations

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions