CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-polyfactory

Mock data generation factories for Python types with support for dataclasses, Pydantic, SQLAlchemy, and more

Pending
Overview
Eval results
Files

field-configuration.mddocs/

Field Configuration

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.

Capabilities

Use Field

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 string

Ignore Field

Marker 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 name

Require Field

Marker 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"
)

PostGenerated Field

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_name

Fixture Field (Deprecated)

Creates 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
        """

PostGenerated Decorator

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 items

Field Configuration Patterns

Combining Field Types

Field 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")

Advanced PostGenerated Patterns

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

docs

customization.md

factory-operations.md

field-configuration.md

index.md

persistence.md

specialized-factories.md

tile.json