Как создать Variadic универсальный контейнер с гетерогенными типами в Python 3.13, используя PEP 646 и PEP 695?Python

Программы на Python
Ответить
Anonymous
 Как создать Variadic универсальный контейнер с гетерогенными типами в Python 3.13, используя PEP 646 и PEP 695?

Сообщение Anonymous »

Я экспериментирую с PEP 646 Variadic Generics и PEP 695 TypeVar с областью действия класса/функции в Python 3.13. Моя цель — создать гетерогенный контейнер, в котором будут храниться элементы (в данном примере функции), каждый из которых возвращает свой тип, избегая при этом Any.
Вот упрощенный пример. :

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

from typing import Callable

class Operation[R]:
"""Encapsulates a function returning type R."""
def __init__(self, fn: Callable[[], R]) -> None:
self._fn = fn

def run(self) -> R:
return self._fn()

class OperationSequence[*Ts]:
"""
A typed-tuple container for Operation objects,
each possibly returning a different type in Ts.
For example, OperationSequence[int, str] means
item[0] returns int, item[1] returns str, etc.
"""
def __init__(self, *ops: Operation[*Ts]) -> None:
self._ops = ops  # storing them in a tuple

def __getitem__(self, index: int) -> Operation[Ts[index]]: # What do do here?
return self._ops[index]

def __len__(self) -> int:
return len(self._ops)

def run_all(self) -> tuple[*Ts]:
# I'd like this to return e.g. tuple[int, str]
return tuple(op.run() for op in self._ops)

# Example usage
def get_number() -> int:
return 42

def get_text() -> str:
return "Hello"

ops = OperationSequence(
Operation(get_number),  # returns int
Operation(get_text),    # returns str
)

# I'd like mypy/pyright to infer:
#   ops.run_all() -> tuple[int, str]
#   ops[0].run() -> int
#   ops[1].run() -> str
print(ops.run_all())
Проблема:
  • *Конструктор: я получаю такие ошибки, как *“TypeVarTuple не является разрешено в этом контексте» в mypy/pyright.
  • *getitem: я вижу * «Тип 'Operation[*Ts@OperationSequence]' не может быть назначен для возврата тип «Operation[Ts[index]]» или «TypeVar 'Ts@OperationSequence' не подлежит индексации» и т. д.
Я бы хотел сохранить оба:
  • run_all() возвращает полностью типизированный кортеж[*Ts],
  • Каждый индекс имеет свой точный тип (например, ops[0] — это Operation[int]).
Существует ли лучшая практика для универсального контейнера с переменным числом вариантов в Python 3.13, которая позволяет избежать этих ошибок ? Или это в настоящее время ограничение в инструментах? Я уже привык к этой «новой» вещи «TypeVarTuple».
Любые шаблоны или пояснения приветствуются. Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/793 ... n-python-3
Ответить

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

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

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

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

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