Цель — предварительно инициализировать объект, обернув его в Lazy > и позже завершите инициализацию, вызвав to_eager, где пользователь может предоставить некоторые дополнительные аргументы. Проблема заключается в сохранении подсказок типов в IDE.
Вот код
Код: Выделить всё
from typing import Callable, Generic, ParamSpec, Type, TypeVar
T = TypeVar("T")
P = ParamSpec("P")
class Lazy(Generic[T, P]): # Any makes it ok to asign to any other type
def __init__(
self, cls: Type[T] | Callable[P, T], *args: P.args, **kwargs: P.kwargs
):
self.cls = cls
self.args = args
self.kwargs = kwargs
def to_eager(self, *args: P.args, **kwargs: P.kwargs) -> T:
assert not args
kwg = {**self.kwargs, **kwargs}
return self.cls(*self.args, **kwg)
class SomeClass:
def __init__(self, y: int = 1):
self.y = y
l = Lazy(SomeClass, y=5)
l.to_eager() # here VSCode hints me with (y: int -> 1)

Теперь проблема в том, что если это сочетается с типом переменной задание
Код: Выделить всё
l: Lazy = Lazy(SomeClass, y=5)
l.to_eager() # type hint is gone, I get (... -> Unknown)
Код: Выделить всё
l: Lazy[SomeClass, ...] = Lazy(SomeClass, y=5)
l.to_eager() # I get (... -> SomeClass)
Мой вопрос: как сохранить подсказки типа аргументов в этом случае, одновременно выполняя тип переменной назначение? Назначение типа необходимо, например, когда я объединяю это с классом данных. Может быть, есть какая-то конфигурация для Pyright, чтобы не расширять тип? Или, возможно, у vscode есть какая-то полезная опция для этого?
Что я пробовал до сих пор:
- Pass P в качестве второго аргумента в Lazy[SomeClass, P], но получаю предупреждение о том, что P не имеет значения в этом контексте, а также никаких подсказок типа от VSCode
Подробнее здесь: https://stackoverflow.com/questions/781 ... assignment