Правильные аннотации типа для общей функции, которая возвращает генератор T?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Правильные аннотации типа для общей функции, которая возвращает генератор T?

Сообщение Anonymous »

Я использую Python 3.13 и имею эту функцию: < /p>

Код: Выделить всё

def chunk(data, chunk_size: int):
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
Я хочу дать аннотации типа типа, чтобы указать, что он может работать с байтами , Bytearray или общей коллекцией. Sevestence любого рода, и пусть тип возврата будет генератором точного входного типа. Я не хочу, чтобы тип возврата был типом объединения всех возможных входов (например, байт | Bytearray | sequence [t] ), потому что это чрезмерно; Я хочу точный тип, который я случайно вставил, чтобы вернуться на другой конец. Вызов chunk на байтах должен возвращать генератор [Bytes] и т. Д.

Код: Выделить всё

def chunk[T](data: Sequence[T], chunk_size: int) -> Generator[Sequence[T]]:
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
Но это имеет проблему ковариации- тип возврата- это последовательность [t] , а не байты , и пирайт жалуется, когда я передаю возврат в функцию, которая принимает байт (параметр>

Код: Выделить всё

def print_bytes(b: bytes) -> None: ...
):

Код: Выделить всё

error: Argument of type "Sequence[int]" cannot be assigned to parameter "b" of type "bytes" in function "print_bytes"
  "Sequence[int]" is not assignable to "bytes" (reportArgumentType)
< /code>
Итак, я попытался использовать ограничение типа: "chunk
может взять любую последовательность и возвращает генератор такого типа. »

Код: Выделить всё

def chunk[T: Sequence](data: T, chunk_size: int) -> Generator[T]:
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
< /code>
На этот раз пирайт жалуется на саму функцию: < /p>
error: Return type of generator function must be compatible with "Generator[Sequence[Unknown], Any, Any]"
  "Generator[Sequence[Unknown], None, Unknown]" is not assignable to "Generator[T@chunk, None, None]"
    Type parameter "_YieldT_co@Generator" is covariant, but "Sequence[Unknown]" is not a subtype of "T@chunk"
      Type "Sequence[Unknown]" is not assignable to type "T@chunk" (reportReturnType)
Я признаю, что не полностью понимает здесь жалобу- мы установили с ограничением типа, что t является последовательности , но пирайт не любит, и я предполагаю, что мой код виноват.

Код: Выделить всё

@typing.overload
def chunk[T: bytes | bytearray](data: T, chunk_size: int) -> Generator[T]: ...

@typing.overload
def chunk[T](data: Sequence[T], chunk_size: int) -> Generator[Sequence[T]]: ...

def chunk(data, chunk_size: int):
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
В данном случае Pyright может выбрать правильную перегрузку для всех моих применений, но это немного глупо- есть 2x как код типирования, как и фактический код реализации!>

Подробнее здесь: https://stackoverflow.com/questions/796 ... rator-of-t
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»