Mock data generation factories for Python types with support for dataclasses, Pydantic, SQLAlchemy, and more
—
Special field types and decorators that provide fine-grained control over how individual attributes are generated. These tools allow customization of the data generation process for specific fields while maintaining the automatic generation capabilities for others.
Wrapper for callables that are invoked during attribute generation, allowing custom value generation logic for specific fields.
class Use:
"""
Factory field that wraps a callable to be invoked when building the factory attribute.
The callable can accept arguments and will be called with appropriate parameters
during instance generation.
"""
def __init__(self, fn: Callable[..., Any]) -> None:
"""
Initialize Use field with a callable.
Parameters:
- fn: Callable to invoke for generating the field value
"""Usage Example:
from dataclasses import dataclass
from polyfactory import Use
from polyfactory.factories import DataclassFactory
import uuid
@dataclass
class User:
id: str
name: str
email: str
class UserFactory(DataclassFactory[User]):
__model__ = User
# Use a custom function to generate UUID strings
id = Use(lambda: str(uuid.uuid4()))
# Use a lambda with faker access
email = Use(lambda: f"user_{uuid.uuid4().hex[:8]}@example.com")
user = UserFactory.build() # id will be a UUID stringMarker that excludes a field from automatic generation, useful for computed properties or fields that should remain unset.
class Ignore:
"""
Factory field marker that indicates an attribute should be ignored during generation.
Fields marked with Ignore will not be set in the generated instance,
allowing default values or computed properties to take effect.
"""Usage Example:
from dataclasses import dataclass, field
from polyfactory import Ignore
from polyfactory.factories import DataclassFactory
@dataclass
class User:
name: str
email: str
full_name: str = field(init=False) # Computed property
def __post_init__(self):
self.full_name = f"Mr/Ms {self.name}"
class UserFactory(DataclassFactory[User]):
__model__ = User
# Don't generate full_name, let __post_init__ handle it
full_name = Ignore()
user = UserFactory.build() # full_name will be computed from nameMarker that designates a field as a required build-time keyword argument, forcing explicit value specification.
class Require:
"""
Factory field marker that indicates an attribute must be provided as a keyword argument
when calling build(), batch(), or other generation methods.
Raises MissingBuildKwargException if the required field is not provided.
"""Usage Example:
from dataclasses import dataclass
from polyfactory import Require
from polyfactory.factories import DataclassFactory
@dataclass
class BankAccount:
account_number: str
owner_name: str
balance: float
class BankAccountFactory(DataclassFactory[BankAccount]):
__model__ = BankAccount
# Force explicit specification of sensitive data
account_number = Require()
owner_name = Require()
# This will raise MissingBuildKwargException
# account = BankAccountFactory.build()
# This works
account = BankAccountFactory.build(
account_number="123456789",
owner_name="John Doe"
)Allows generating field values after other factory fields have been generated, enabling dependencies between fields.
class PostGenerated:
"""
Factory field that generates values after other fields are completed.
Useful for fields that depend on other generated values or need access
to the partially constructed instance.
"""
def __init__(self, fn: Callable[..., Any]) -> None:
"""
Initialize PostGenerated field with a callable.
Parameters:
- fn: Callable that receives the instance and returns the field value
"""Usage Example:
from dataclasses import dataclass
from polyfactory import PostGenerated
from polyfactory.factories import DataclassFactory
@dataclass
class User:
first_name: str
last_name: str
email: str
username: str
class UserFactory(DataclassFactory[User]):
__model__ = User
# Generate email based on names
email = PostGenerated(
lambda **kwargs: f"{kwargs['first_name'].lower()}.{kwargs['last_name'].lower()}@example.com"
)
# Generate username based on names
username = PostGenerated(
lambda **kwargs: f"{kwargs['first_name'].lower()}{kwargs['last_name'].lower()}"
)
user = UserFactory.build()
# email and username will be based on the generated first_name and last_nameCreates pytest fixtures from factories (deprecated in v2.20.0, use register_fixture instead).
class Fixture:
"""
Factory field for creating pytest fixtures from factories.
DEPRECATED in v2.20.0: Use register_fixture decorator instead.
"""
def __init__(
self,
fixture_name: str | None = None,
scope: str = "function",
**kwargs
) -> None:
"""
Initialize Fixture field.
Parameters:
- fixture_name: Name for the pytest fixture
- scope: Pytest fixture scope
- **kwargs: Additional arguments for fixture creation
"""Descriptor decorator that wraps classmethods into PostGenerated fields for cleaner syntax.
@post_generated
def field_method(cls, **kwargs) -> Any:
"""
Decorator that converts a classmethod into a PostGenerated field.
The decorated method will be called after other fields are generated
and receives all generated field values as keyword arguments.
Parameters:
- **kwargs: Generated field values from other factory fields
Returns:
Value for the decorated field
"""Usage Example:
from dataclasses import dataclass
from polyfactory.decorators import post_generated
from polyfactory.factories import DataclassFactory
@dataclass
class Order:
items: list[str]
item_count: int
total_price: float
class OrderFactory(DataclassFactory[Order]):
__model__ = Order
@post_generated
@classmethod
def item_count(cls, **kwargs) -> int:
"""Generate item count based on items list."""
return len(kwargs["items"])
@post_generated
@classmethod
def total_price(cls, **kwargs) -> float:
"""Generate total price based on item count."""
return kwargs["item_count"] * 19.99
order = OrderFactory.build() # item_count and total_price computed from itemsField configuration types can be combined to create sophisticated generation patterns:
from dataclasses import dataclass
from polyfactory import Use, PostGenerated, Require
from polyfactory.factories import DataclassFactory
import random
@dataclass
class Product:
category: str # Required at build time
name: str # Generated automatically
sku: str # Custom generation logic
price: float # Computed after other fields
class ProductFactory(DataclassFactory[Product]):
__model__ = Product
category = Require() # Must be provided
sku = Use(lambda: f"SKU-{random.randint(10000, 99999)}") # Custom logic
price = PostGenerated(
lambda **kwargs: random.uniform(10.0, 100.0) if kwargs["category"] == "basic" else random.uniform(100.0, 500.0)
) # Depends on category
# Usage
product = ProductFactory.build(category="premium")PostGenerated fields can access the factory class and other generated values:
@dataclass
class ComplexModel:
data: dict
computed_field: str
metadata: dict
class ComplexModelFactory(DataclassFactory[ComplexModel]):
__model__ = ComplexModel
computed_field = PostGenerated(
lambda cls, instance, **kwargs: f"processed_{len(kwargs['data'])}"
)
metadata = PostGenerated(
lambda cls, instance, **kwargs: {
"generated_at": "2023-01-01",
"data_keys": list(kwargs["data"].keys()),
"computed": kwargs["computed_field"]
}
)Install with Tessl CLI
npx tessl i tessl/pypi-polyfactory