Summary
Python 3.14 added type aliases through type statements: https://docs.python.org/3/library/typing.html#type-aliases
These aliases are preserved in the annotations:
type ConstrainedString = Annotated[str, pydantic.AfterValidator(validator)]
ConstrainedStringOld = Annotated[str, pydantic.AfterValidator(validator)]
print(repr(ConstrainedString | None)) # ConstrainedString | None
print(repr(ConstrainedStringOld | None)) # typing.Optional[typing.Annotated[str, AfterValidator(func=<function validator at ...)]]
Thus this is something that polyfactory could leverage to allow for easier ways to add custom providers for types that are just constrained versions of built-in types.
Basic Example
Here's an example of some usage of a type alias.
Note that coverage() (accidentally) works when the type alias is part of a Union.
from typing import Annotated
import pydantic
from polyfactory.factories.pydantic_factory import ModelFactory
def validator(value: str) -> str:
if len(value) % 2 == 0:
raise ValueError("Must be an odd length string")
return value
type ConstrainedString = Annotated[str, pydantic.AfterValidator(validator)]
ModelFactory.add_provider(ConstrainedString, lambda: "f" + "oo" * ModelFactory.__random__.randint(0,100))
class MyModel(pydantic.BaseModel):
s: ConstrainedString
class MyModelFactory(ModelFactory[MyModel]):
__check_model__ = True
# Neither of these work
print(list(MyModelFactory.coverage()))
print(list(MyModelFactory.batch(10)))
class MyModelWithNone(pydantic.BaseModel):
s: ConstrainedString | None
class MyModelWithNoneFactory(ModelFactory[MyModelWithNone]):
__check_model__ = True
print(list(MyModelWithNoneFactory.coverage())) # Surprisingly works
print(list(MyModelWithNoneFactory.batch(10))) # But this doesn't work
Drawbacks and Impact
No response
Unresolved questions
No response
Summary
Python 3.14 added type aliases through type statements: https://docs.python.org/3/library/typing.html#type-aliases
These aliases are preserved in the annotations:
Thus this is something that polyfactory could leverage to allow for easier ways to add custom providers for types that are just constrained versions of built-in types.
Basic Example
Here's an example of some usage of a type alias.
Note that
coverage()(accidentally) works when the type alias is part of aUnion.Drawbacks and Impact
No response
Unresolved questions
No response