0
# Field Configuration
1
2
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.
3
4
## Capabilities
5
6
### Use Field
7
8
Wrapper for callables that are invoked during attribute generation, allowing custom value generation logic for specific fields.
9
10
```python { .api }
11
class Use:
12
"""
13
Factory field that wraps a callable to be invoked when building the factory attribute.
14
15
The callable can accept arguments and will be called with appropriate parameters
16
during instance generation.
17
"""
18
19
def __init__(self, fn: Callable[..., Any]) -> None:
20
"""
21
Initialize Use field with a callable.
22
23
Parameters:
24
- fn: Callable to invoke for generating the field value
25
"""
26
```
27
28
**Usage Example:**
29
```python
30
from dataclasses import dataclass
31
from polyfactory import Use
32
from polyfactory.factories import DataclassFactory
33
import uuid
34
35
@dataclass
36
class User:
37
id: str
38
name: str
39
email: str
40
41
class UserFactory(DataclassFactory[User]):
42
__model__ = User
43
44
# Use a custom function to generate UUID strings
45
id = Use(lambda: str(uuid.uuid4()))
46
47
# Use a lambda with faker access
48
email = Use(lambda: f"user_{uuid.uuid4().hex[:8]}@example.com")
49
50
user = UserFactory.build() # id will be a UUID string
51
```
52
53
### Ignore Field
54
55
Marker that excludes a field from automatic generation, useful for computed properties or fields that should remain unset.
56
57
```python { .api }
58
class Ignore:
59
"""
60
Factory field marker that indicates an attribute should be ignored during generation.
61
62
Fields marked with Ignore will not be set in the generated instance,
63
allowing default values or computed properties to take effect.
64
"""
65
```
66
67
**Usage Example:**
68
```python
69
from dataclasses import dataclass, field
70
from polyfactory import Ignore
71
from polyfactory.factories import DataclassFactory
72
73
@dataclass
74
class User:
75
name: str
76
email: str
77
full_name: str = field(init=False) # Computed property
78
79
def __post_init__(self):
80
self.full_name = f"Mr/Ms {self.name}"
81
82
class UserFactory(DataclassFactory[User]):
83
__model__ = User
84
85
# Don't generate full_name, let __post_init__ handle it
86
full_name = Ignore()
87
88
user = UserFactory.build() # full_name will be computed from name
89
```
90
91
### Require Field
92
93
Marker that designates a field as a required build-time keyword argument, forcing explicit value specification.
94
95
```python { .api }
96
class Require:
97
"""
98
Factory field marker that indicates an attribute must be provided as a keyword argument
99
when calling build(), batch(), or other generation methods.
100
101
Raises MissingBuildKwargException if the required field is not provided.
102
"""
103
```
104
105
**Usage Example:**
106
```python
107
from dataclasses import dataclass
108
from polyfactory import Require
109
from polyfactory.factories import DataclassFactory
110
111
@dataclass
112
class BankAccount:
113
account_number: str
114
owner_name: str
115
balance: float
116
117
class BankAccountFactory(DataclassFactory[BankAccount]):
118
__model__ = BankAccount
119
120
# Force explicit specification of sensitive data
121
account_number = Require()
122
owner_name = Require()
123
124
# This will raise MissingBuildKwargException
125
# account = BankAccountFactory.build()
126
127
# This works
128
account = BankAccountFactory.build(
129
account_number="123456789",
130
owner_name="John Doe"
131
)
132
```
133
134
### PostGenerated Field
135
136
Allows generating field values after other factory fields have been generated, enabling dependencies between fields.
137
138
```python { .api }
139
class PostGenerated:
140
"""
141
Factory field that generates values after other fields are completed.
142
143
Useful for fields that depend on other generated values or need access
144
to the partially constructed instance.
145
"""
146
147
def __init__(self, fn: Callable[..., Any]) -> None:
148
"""
149
Initialize PostGenerated field with a callable.
150
151
Parameters:
152
- fn: Callable that receives the instance and returns the field value
153
"""
154
```
155
156
**Usage Example:**
157
```python
158
from dataclasses import dataclass
159
from polyfactory import PostGenerated
160
from polyfactory.factories import DataclassFactory
161
162
@dataclass
163
class User:
164
first_name: str
165
last_name: str
166
email: str
167
username: str
168
169
class UserFactory(DataclassFactory[User]):
170
__model__ = User
171
172
# Generate email based on names
173
email = PostGenerated(
174
lambda **kwargs: f"{kwargs['first_name'].lower()}.{kwargs['last_name'].lower()}@example.com"
175
)
176
177
# Generate username based on names
178
username = PostGenerated(
179
lambda **kwargs: f"{kwargs['first_name'].lower()}{kwargs['last_name'].lower()}"
180
)
181
182
user = UserFactory.build()
183
# email and username will be based on the generated first_name and last_name
184
```
185
186
### Fixture Field (Deprecated)
187
188
Creates pytest fixtures from factories (deprecated in v2.20.0, use register_fixture instead).
189
190
```python { .api }
191
class Fixture:
192
"""
193
Factory field for creating pytest fixtures from factories.
194
195
DEPRECATED in v2.20.0: Use register_fixture decorator instead.
196
"""
197
198
def __init__(
199
self,
200
fixture_name: str | None = None,
201
scope: str = "function",
202
**kwargs
203
) -> None:
204
"""
205
Initialize Fixture field.
206
207
Parameters:
208
- fixture_name: Name for the pytest fixture
209
- scope: Pytest fixture scope
210
- **kwargs: Additional arguments for fixture creation
211
"""
212
```
213
214
### PostGenerated Decorator
215
216
Descriptor decorator that wraps classmethods into PostGenerated fields for cleaner syntax.
217
218
```python { .api }
219
@post_generated
220
def field_method(cls, **kwargs) -> Any:
221
"""
222
Decorator that converts a classmethod into a PostGenerated field.
223
224
The decorated method will be called after other fields are generated
225
and receives all generated field values as keyword arguments.
226
227
Parameters:
228
- **kwargs: Generated field values from other factory fields
229
230
Returns:
231
Value for the decorated field
232
"""
233
```
234
235
**Usage Example:**
236
```python
237
from dataclasses import dataclass
238
from polyfactory.decorators import post_generated
239
from polyfactory.factories import DataclassFactory
240
241
@dataclass
242
class Order:
243
items: list[str]
244
item_count: int
245
total_price: float
246
247
class OrderFactory(DataclassFactory[Order]):
248
__model__ = Order
249
250
@post_generated
251
@classmethod
252
def item_count(cls, **kwargs) -> int:
253
"""Generate item count based on items list."""
254
return len(kwargs["items"])
255
256
@post_generated
257
@classmethod
258
def total_price(cls, **kwargs) -> float:
259
"""Generate total price based on item count."""
260
return kwargs["item_count"] * 19.99
261
262
order = OrderFactory.build() # item_count and total_price computed from items
263
```
264
265
## Field Configuration Patterns
266
267
### Combining Field Types
268
269
Field configuration types can be combined to create sophisticated generation patterns:
270
271
```python
272
from dataclasses import dataclass
273
from polyfactory import Use, PostGenerated, Require
274
from polyfactory.factories import DataclassFactory
275
import random
276
277
@dataclass
278
class Product:
279
category: str # Required at build time
280
name: str # Generated automatically
281
sku: str # Custom generation logic
282
price: float # Computed after other fields
283
284
class ProductFactory(DataclassFactory[Product]):
285
__model__ = Product
286
287
category = Require() # Must be provided
288
sku = Use(lambda: f"SKU-{random.randint(10000, 99999)}") # Custom logic
289
price = PostGenerated(
290
lambda **kwargs: random.uniform(10.0, 100.0) if kwargs["category"] == "basic" else random.uniform(100.0, 500.0)
291
) # Depends on category
292
293
# Usage
294
product = ProductFactory.build(category="premium")
295
```
296
297
### Advanced PostGenerated Patterns
298
299
PostGenerated fields can access the factory class and other generated values:
300
301
```python
302
@dataclass
303
class ComplexModel:
304
data: dict
305
computed_field: str
306
metadata: dict
307
308
class ComplexModelFactory(DataclassFactory[ComplexModel]):
309
__model__ = ComplexModel
310
311
computed_field = PostGenerated(
312
lambda cls, instance, **kwargs: f"processed_{len(kwargs['data'])}"
313
)
314
315
metadata = PostGenerated(
316
lambda cls, instance, **kwargs: {
317
"generated_at": "2023-01-01",
318
"data_keys": list(kwargs["data"].keys()),
319
"computed": kwargs["computed_field"]
320
}
321
)
322
```