I am writing a Lazy class that works like partial, but has some extra functionalities.
The goal is to pre-initialize an object by wrapping it in the Lazy class and later finish the initialization by calling to_eager, where the user can provide some additional arguments. The issue is with preserving type hints in IDE.
Here is the code
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)
When I try to call to_eager(), I get a nice hint about possible args for the original class.
Now the issue is, if this is combined with variable type assignment
l: Lazy = Lazy(SomeClass, y=5)
l.to_eager() # type hint is gone, I get (... -> Unknown)
This can be improved a bit by
l: Lazy[SomeClass, ...] = Lazy(SomeClass, y=5)
l.to_eager() # I get (... -> SomeClass)
but this does not contain the args.
My question is - how to preserve the args type hints in this case while also doing the variable type assignment? The type assignment is needed eg when I combine this with a dataclass. Maybe there is some configuration for pyright to not do type widening? Or perhaps vscode has some useful option for this?
What I tried so far:
- Pass
Pas the second argument inLazy[SomeClass, P], but getting warning that P has no meaning in this context and also no type hints from VSCode

Lazyby itself is equivalent toLazy[Any, Any], overriding the inferred type ofLazy[SomeClass, int]. It's the laziness (pun intended) of not specifying a precise type hint that prevents the editor from providing an argument hint....itself is recognized as shorthand fortypes.EllipsisType.What you would want is for the editor to support some notion of type-variable binding so that you can write one "type" whose value is bound by the actual argument passed to
Lazy, something likeand have
ClsandTbound (perhaps just for this assignment) toSomeClassandint, respectively.