I discovered this bug when using pydantic, which makes heavy use of annotated types and type aliases when defining custom validators for types. From their documentation:
from typing import Annotated
from pydantic import BaseModel, AfterValidator, ValidationError
MyInt = Annotated[int, AfterValidator(lambda v: v + 1)]
class Model(BaseModel):
a: MyInt
print(Model(a=1).a)
# > 2
From what I understand, polyfactory lets the user define a custom provider map to override the default handling of user-defined types. Drilling down into polyfactory's code, I've found that the provider_map does not support "unwrap-able" types because all annotations, newtypes, optionals, and unions are removed or "unwrapped" before any attempt is made to find a type in the provider map. This means even if I add MyInt
to the provider_map with a custom factory method, polyfactory will always treat MyInt
as just an int because Annotated will be stripped by the unwrap_annotation
method.
polyfactory/polyfactory/factories/base.py
Line 636 in e4daf5f
polyfactory/polyfactory/field_meta.py
Line 131 in e4daf5f
from dataclasses import dataclass
from typing import NewType
from polyfactory.factories import DataclassFactory
MyType = NewType("MyType", str)
@dataclass
class MyModel:
my_type: MyType
class MyModelFactory(DataclassFactory):
__model__ = MyModel
@classmethod
def get_provider_map(cls):
base_provider_map = super().get_provider_map()
return {
MyType: lambda: "constant", # Any MyType value *should* always be populated with "constant"
**base_provider_map
}
if __name__ == "__main__":
my_model = MyModelFactory.build()
print(my_model.my_type)
Results in:
# stdout
ddtJwRSSJdmQZPLLcuuq # expected value is "constant"
2.8.0
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too