pyright: Использование TypeVar в однородном списке с мин. / макс.

Я пытаюсь понять, как использовать TypeVar с pyright.

Я построил следующую небольшую функцию:

import random
from typing import List, Sequence, TypeVar


T = TypeVar("T", int, str, float)
TypedList = List[T]


def merge(a: TypedList, b: TypedList) -> TypedList:
    i0, i1 = 0, 0
    merged = []

    # Run with two pointers
    while i0 < len(a) and i1 < len(b):
        merged.append(min(a[i0], b[i1]))
        if merged[-1] == a[i0]:
            i0 += 1
        else:
            i1 += 1

    # Add the tail
    if i0 >= len(a):
        merged.extend(b[i1:])
    if i1 >= len(b):
        merged.extend(a[i0:])

    return merged

Это заставляет Пайрайта жаловаться в сети:

    merged.append(min(a[i0], b[i1]))

Потому что:

Никаких перегрузок для min, соответствующих предоставленным аргументам

Типы аргументов: (TypedList [int], TypedList [int])

[Pyright: reportGeneralTypeIssues]

Также он жалуется на:

if merged[-1] == a[i0]

Потому что:

Ожидаемый тип класса, но получено int

а также:

Аннотации недопустимого типа: переменная не разрешена, если это не псевдоним типа

mypy, похоже, отлично работает с этой строкой. Есть идеи о том, в чем проблема и как я могу ее исправить?

Спасибо!


person Infinity    schedule 09.04.2021    source источник


Ответы (1)


Используйте Union вместо TypeVar

import random
from typing import List, Sequence, TypeVar, Union


U = Union[int, str, float]
TypedList = List[U]


def merge(a: TypedList, b: TypedList) -> TypedList:
    i0, i1 = 0, 0
    merged = []

    # Run with two pointers
    while i0 < len(a) and i1 < len(b):
        merged.append(min(a[i0], b[i1]))
        if merged[-1] == a[i0]:
            i0 += 1
        else:
            i1 += 1

    # Add the tail
    if i0 >= len(a):
        merged.extend(b[i1:])
    if i1 >= len(b):
        merged.extend(a[i0:])

    return merged

При использовании TypeVar, например T = TypeVar (...), все T должны быть одного типа. Итак, Пирт запутался. В этой ситуации вам следует использовать «Union», потому что «U» не обязательно относится к одному и тому же типу.

или как это

import random
from typing import List, Sequence, TypeVar


T = TypeVar("T", int, str, float)


def merge(a: list[T], b: list[T]) -> list[T]:
    i0, i1 = 0, 0
    merged = []

    # Run with two pointers
    while i0 < len(a) and i1 < len(b):
        merged.append(min(a[i0], b[i1]))
        if merged[-1] == a[i0]:
            i0 += 1
        else:
            i1 += 1

    # Add the tail
    if i0 >= len(a):
        merged.extend(b[i1:])
    if i1 >= len(b):
        merged.extend(a[i0:])

    return merged
person FG452    schedule 01.06.2021