Skip to content

Commit

Permalink
fix: AttrsFactory fixes (#370)
Browse files Browse the repository at this point in the history
* fix: don't register AttrsFactory by default

* fix: resolve stringified annotations for attrs models
  • Loading branch information
guacs committed Sep 17, 2023
1 parent 95d24cb commit 6cc7b03
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
18 changes: 16 additions & 2 deletions polyfactory/factories/attrs_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
try:
import attrs
from attr._make import Factory
from attrs import AttrsInstance
except ImportError as ex:
raise MissingDependencyException("attrs is not installed") from ex

T = TypeVar("T", bound=attrs.AttrsInstance)

T = TypeVar("T", bound=AttrsInstance)


class AttrsFactory(BaseFactory[T]):
Expand All @@ -32,9 +34,11 @@ def is_supported_type(cls, value: Any) -> TypeGuard[type[T]]:
@classmethod
def get_model_fields(cls) -> list[FieldMeta]:
field_metas: list[FieldMeta] = []
fields = attrs.fields(cls.__model__)
none_type = type(None)

cls.resolve_types(cls.__model__)
fields = attrs.fields(cls.__model__)

for field in fields:
annotation = none_type if field.type is None else field.type

Expand Down Expand Up @@ -63,3 +67,13 @@ def get_model_fields(cls) -> list[FieldMeta]:
)

return field_metas

@classmethod
def resolve_types(cls, model: type[T], **kwargs: Any) -> None:
"""Resolve any strings and forward annotations in type annotations.
:param model: The model to resolve the type annotations for.
:param kwargs: Any parameters that need to be passed to `attrs.resolve_types`.
"""

attrs.resolve_types(model, **kwargs) # type: ignore[type-var]
4 changes: 3 additions & 1 deletion polyfactory/factories/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,9 @@ def _register_builtin_factories() -> None:
"polyfactory.factories.beanie_odm_factory",
"polyfactory.factories.odmantic_odm_factory",
"polyfactory.factories.msgspec_factory",
"polyfactory.factories.attrs_factory",
# `AttrsFactory` is not being registered by default since not all versions of `attrs` are supported.
# Issue: https://github.com/litestar-org/polyfactory/issues/356
# "polyfactory.factories.attrs_factory",
]:
try:
import_module(module)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_attrs_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,16 @@ class ChildFactory(AttrsFactory[Child]):
child_dict = asdict(child)

assert child == Child(**child_dict)


def test_with_stringified_annotations() -> None:
@define
class Foo:
int_field: "int"

class FooFactory(AttrsFactory[Foo]):
__model__ = Foo

foo = FooFactory.build()

assert isinstance(foo.int_field, int)

0 comments on commit 6cc7b03

Please sign in to comment.