Reputation: 2899
Using polyfactory to generate test pydantic objects, I end up with this to describe the typing, but it is not correct according to pyright (runtime, all is fine) and I wonder how to fix this.
from typing import Self
from polyfactory.factories.pydantic_factory import ModelFactory
from pydantic import BaseModel
class Parent(BaseModel):
@classmethod
def generate_test_instance[**P](cls, *_: P.args, **kwargs: P.kwargs) -> Self:
class Factorio(ModelFactory[cls]):
__model__ = cls
return Factorio.build(**kwargs)
class Child(Parent):
param: str
Child.generate_test_instance()
The whole file is correct typing-wise, except the last line, complaining that Param spec "P@generate_test_instance" has no bound value
.
To bind P
, I could use cls:Callable[P, T]
as first parameter of generate_test_instance
but it breaks other things (typing wise): classmethod, use of cls in the __model__.
I understand that P
needs to be bound, but I am not sure how.
Experimenting, I ended up with this option for the parent
class Parent2(BaseModel):
@classmethod
def generate_test_instance[T: BaseModel, **P](cls: Type[Callable[P, T]], *_: P.args, **kwargs: P.kwargs) -> T:
class Factorio(ModelFactory[T]):
__model__ = cls
return Factorio.build(**kwargs)
The child is happy (parameters are auto completed) but __model__ = cls
in Parent2 gives a typing error (Expected type expression but received "(**P@generate_test_instance) -> T@generate_test_instance"
respectively) which is not unexpected.
How could I get both of both worlds, ie. complete valid typing?
Upvotes: 0
Views: 680