Issue
If I have "factory" method, taking a class type and the relevant parameters to create a resource, is there a way to have static analysis of the parameters?
from typing import Type
from pydantic import BaseModel
class Res(BaseModel):
f: int
class Config:
extra = "forbid"
def factory[T](resource_type: Type[T], **kwargs) -> T:
return resource_type(**kwargs)
factory(Res, f=3) # no problem!
factory(Res, f=3, g=4) # ValidationError, g is not allowed.
This works as expected at run time. I would love for pyright to notice statically that g
is not a valid parameter to Res
.
Is it at all possible? I am looking in the direction of ParamSpecs, but it does not help yet.
def factory[T, **P](resource_type: Type[T], *args: P.args, **kwargs: P.kwargs) -> T:
return resource_type(**kwargs)
factory(Res, f=3) # says: Param spec "P@factory" has no bound value
Solution
typing.ParamSpec
should be the way to go. The error message says it all: the ParamSpec is not bound to any callable. Change the signature from type[T]
to Callable[P, T]
.
from typing import Callable, ParamSpec, TypeVar, reveal_type
from pydantic import BaseModel
T = TypeVar("T", bound=BaseModel)
P = ParamSpec("P")
class Res(BaseModel):
f: int
class Config:
extra = "forbid"
def factory(resource_type: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
return resource_type(*args, **kwargs)
reveal_type(factory(Res, f=3)) # Revealed type is "Res"
Answered By - Paweł Rubin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.