0
# Code Generation and Optimization
1
2
High-performance code generation utilities for creating specialized structuring and unstructuring functions. The cattrs.gen module provides tools for creating optimized, type-specific converter functions that can significantly improve performance for critical code paths.
3
4
## Capabilities
5
6
### Structure Function Generation
7
8
Functions for generating optimized structuring functions tailored to specific classes and types.
9
10
```python { .api }
11
from cattrs.gen import (
12
make_dict_structure_fn,
13
make_dict_structure_fn_from_attrs,
14
make_mapping_structure_fn
15
)
16
17
def make_dict_structure_fn(cl, converter, **kwargs):
18
"""
19
Generate specialized dict structuring functions for attrs classes/dataclasses.
20
21
Creates optimized functions that can structure dictionaries into class instances
22
faster than the generic converter methods.
23
24
Parameters:
25
- cl: The class to generate a structuring function for
26
- converter: The converter instance to use for nested structuring
27
- **kwargs: Additional generation options
28
29
Returns:
30
Function that structures dictionaries into instances of the specified class
31
"""
32
33
def make_dict_structure_fn_from_attrs(attrs_and_types, cl, converter, **kwargs):
34
"""
35
Generate dict structuring functions from attribute lists.
36
37
Creates structuring functions based on explicit attribute specifications
38
rather than introspecting the class.
39
40
Parameters:
41
- attrs_and_types: List of (attribute, type) tuples
42
- cl: Target class for structuring
43
- converter: Converter instance for nested types
44
- **kwargs: Additional options
45
46
Returns:
47
Optimized structuring function for the specified attributes
48
"""
49
50
def make_mapping_structure_fn(cl, converter, mapping_key=None, **kwargs):
51
"""
52
Generate structuring functions for mappings.
53
54
Creates functions optimized for structuring mapping types (dict-like objects)
55
with specific key and value type handling.
56
57
Parameters:
58
- cl: The mapping class to structure into
59
- converter: Converter for key/value structuring
60
- mapping_key: Optional key transformation function
61
- **kwargs: Additional generation options
62
63
Returns:
64
Optimized mapping structuring function
65
"""
66
```
67
68
### Unstructure Function Generation
69
70
Functions for generating optimized unstructuring functions for various data types.
71
72
```python { .api }
73
from cattrs.gen import (
74
make_dict_unstructure_fn,
75
make_dict_unstructure_fn_from_attrs,
76
make_hetero_tuple_unstructure_fn,
77
make_iterable_unstructure_fn,
78
make_mapping_unstructure_fn
79
)
80
81
def make_dict_unstructure_fn(cl, converter, **kwargs):
82
"""
83
Generate specialized dict unstructuring functions for attrs classes/dataclasses.
84
85
Creates optimized functions that convert class instances to dictionaries
86
faster than generic converter methods.
87
88
Parameters:
89
- cl: The class to generate an unstructuring function for
90
- converter: Converter instance for nested unstructuring
91
- **kwargs: Additional generation options (unstructure_as, etc.)
92
93
Returns:
94
Function that unstructures instances into dictionaries
95
"""
96
97
def make_dict_unstructure_fn_from_attrs(attrs_and_types, cl, converter, **kwargs):
98
"""
99
Generate dict unstructuring functions from attribute lists.
100
101
Creates unstructuring functions based on explicit attribute specifications.
102
103
Parameters:
104
- attrs_and_types: List of (attribute, type) tuples to unstructure
105
- cl: Source class for unstructuring
106
- converter: Converter instance for nested types
107
- **kwargs: Additional options
108
109
Returns:
110
Optimized unstructuring function for the specified attributes
111
"""
112
113
def make_hetero_tuple_unstructure_fn(tuple_type, converter, **kwargs):
114
"""
115
Generate unstructuring functions for heterogeneous tuples.
116
117
Creates functions optimized for unstructuring tuples with mixed element types.
118
119
Parameters:
120
- tuple_type: The tuple type to unstructure (e.g., Tuple[int, str, bool])
121
- converter: Converter for element unstructuring
122
- **kwargs: Additional options
123
124
Returns:
125
Optimized heterogeneous tuple unstructuring function
126
"""
127
128
def make_iterable_unstructure_fn(iterable_type, converter, **kwargs):
129
"""
130
Generate unstructuring functions for iterables.
131
132
Creates functions optimized for unstructuring lists, sets, and other iterables.
133
134
Parameters:
135
- iterable_type: The iterable type (e.g., List[MyClass], Set[str])
136
- converter: Converter for element unstructuring
137
- **kwargs: Additional options
138
139
Returns:
140
Optimized iterable unstructuring function
141
"""
142
143
def make_mapping_unstructure_fn(mapping_type, converter, **kwargs):
144
"""
145
Generate unstructuring functions for mappings.
146
147
Creates functions optimized for unstructuring dictionary-like objects.
148
149
Parameters:
150
- mapping_type: The mapping type (e.g., Dict[str, MyClass])
151
- converter: Converter for key/value unstructuring
152
- **kwargs: Additional options
153
154
Returns:
155
Optimized mapping unstructuring function
156
"""
157
```
158
159
### Override System
160
161
Tools for creating fine-grained customizations of field handling during code generation.
162
163
```python { .api }
164
from cattrs.gen import override, AttributeOverride
165
166
def override(
167
rename=None,
168
omit_if_default=None,
169
struct_hook=None,
170
unstruct_hook=None,
171
**kwargs
172
):
173
"""
174
Create attribute overrides for customizing field handling.
175
176
Provides field-level control over structuring and unstructuring behavior
177
when generating optimized converter functions.
178
179
Parameters:
180
- rename: Alternative name for the field in unstructured data
181
- omit_if_default: Whether to omit field if it has the default value
182
- struct_hook: Custom structuring function for this field
183
- unstruct_hook: Custom unstructuring function for this field
184
- **kwargs: Additional override options
185
186
Returns:
187
AttributeOverride instance for use with converter configuration
188
"""
189
190
class AttributeOverride:
191
"""
192
Class for specifying field-level overrides in code generation.
193
194
Encapsulates customization options for individual fields when generating
195
optimized structuring and unstructuring functions.
196
"""
197
def __init__(
198
self,
199
rename=None,
200
omit_if_default=None,
201
struct_hook=None,
202
unstruct_hook=None,
203
**kwargs
204
):
205
"""
206
Initialize attribute override.
207
208
Parameters match those of the override() function.
209
"""
210
```
211
212
### TypedDict Support
213
214
Specialized code generation for TypedDict classes.
215
216
```python { .api }
217
from cattrs.gen.typeddicts import make_dict_structure_fn, make_dict_unstructure_fn
218
219
def make_dict_structure_fn(cl, converter, **kwargs):
220
"""
221
Generate TypedDict structuring functions.
222
223
Creates optimized functions specifically for structuring data into TypedDict
224
classes with proper type checking and validation.
225
226
Parameters:
227
- cl: The TypedDict class to structure into
228
- converter: Converter instance for nested structuring
229
- **kwargs: Additional options
230
231
Returns:
232
Optimized TypedDict structuring function
233
"""
234
235
def make_dict_unstructure_fn(cl, converter, **kwargs):
236
"""
237
Generate TypedDict unstructuring functions.
238
239
Creates functions optimized for unstructuring TypedDict instances while
240
preserving type information and structure.
241
242
Parameters:
243
- cl: The TypedDict class to unstructure from
244
- converter: Converter instance for nested unstructuring
245
- **kwargs: Additional options
246
247
Returns:
248
Optimized TypedDict unstructuring function
249
"""
250
```
251
252
## Usage Examples
253
254
### Basic Function Generation
255
256
```python
257
from cattrs import Converter
258
from cattrs.gen import make_dict_structure_fn, make_dict_unstructure_fn
259
from attrs import define
260
261
@define
262
class User:
263
name: str
264
age: int
265
email: str
266
267
converter = Converter()
268
269
# Generate optimized functions for the User class
270
structure_user = make_dict_structure_fn(User, converter)
271
unstructure_user = make_dict_unstructure_fn(User, converter)
272
273
# Use the generated functions directly for better performance
274
user_data = {"name": "Alice", "age": 30, "email": "alice@example.com"}
275
user = structure_user(user_data) # Faster than converter.structure()
276
277
user_dict = unstructure_user(user) # Faster than converter.unstructure()
278
```
279
280
### Using Overrides for Customization
281
282
```python
283
from cattrs import Converter
284
from cattrs.gen import make_dict_structure_fn, make_dict_unstructure_fn, override
285
from attrs import define
286
from datetime import datetime
287
288
@define
289
class Event:
290
name: str
291
timestamp: datetime
292
description: str = "No description"
293
294
converter = Converter()
295
296
# Configure overrides for specific fields
297
converter.register_structure_hook(datetime, lambda s, _: datetime.fromisoformat(s))
298
converter.register_unstructure_hook(datetime, lambda dt: dt.isoformat())
299
300
# Create overrides for field-level customization
301
overrides = {
302
"timestamp": override(rename="event_time"),
303
"description": override(omit_if_default=True)
304
}
305
306
# Generate functions with overrides
307
structure_event = make_dict_structure_fn(
308
Event,
309
converter,
310
_attrib_overrides=overrides
311
)
312
unstructure_event = make_dict_unstructure_fn(
313
Event,
314
converter,
315
_attrib_overrides=overrides
316
)
317
318
# Data uses "event_time" instead of "timestamp"
319
event_data = {
320
"name": "Meeting",
321
"event_time": "2024-01-01T10:00:00"
322
# description omitted when it's the default value
323
}
324
325
event = structure_event(event_data)
326
```
327
328
### High-Performance Iterable Processing
329
330
```python
331
from cattrs import Converter
332
from cattrs.gen import make_iterable_unstructure_fn, make_dict_structure_fn
333
from attrs import define
334
from typing import List
335
336
@define
337
class Product:
338
name: str
339
price: float
340
in_stock: bool
341
342
converter = Converter()
343
344
# Generate optimized functions for lists of products
345
structure_product = make_dict_structure_fn(Product, converter)
346
unstructure_products = make_iterable_unstructure_fn(List[Product], converter)
347
348
# Process large lists efficiently
349
products = [
350
Product("Laptop", 999.99, True),
351
Product("Mouse", 29.99, False),
352
# ... thousands of products
353
]
354
355
# Optimized bulk unstructuring
356
products_data = unstructure_products(products)
357
358
# Individual structuring using the optimized function
359
structured_products = [structure_product(data) for data in products_data]
360
```
361
362
### Mapping and Complex Type Generation
363
364
```python
365
from cattrs import Converter
366
from cattrs.gen import make_mapping_structure_fn, make_mapping_unstructure_fn
367
from attrs import define
368
from typing import Dict
369
370
@define
371
class Config:
372
host: str
373
port: int
374
ssl: bool
375
376
converter = Converter()
377
378
# Generate functions for mappings with Config values
379
structure_config_map = make_mapping_structure_fn(Dict[str, Config], converter)
380
unstructure_config_map = make_mapping_unstructure_fn(Dict[str, Config], converter)
381
382
# Use with configuration mappings
383
configs = {
384
"development": Config("localhost", 8000, False),
385
"production": Config("prod.example.com", 443, True)
386
}
387
388
# Efficient mapping operations
389
config_data = unstructure_config_map(configs)
390
configs_copy = structure_config_map(config_data)
391
```
392
393
### Integration with Converter Hooks
394
395
```python
396
from cattrs import Converter
397
from cattrs.gen import make_dict_structure_fn
398
from attrs import define
399
400
@define
401
class APIResponse:
402
status: str
403
data: dict
404
timestamp: int
405
406
converter = Converter()
407
408
# Register the generated function as a hook for automatic use
409
structure_response = make_dict_structure_fn(APIResponse, converter)
410
converter.register_structure_hook(APIResponse, structure_response)
411
412
# Now the converter uses the optimized function automatically
413
response_data = {
414
"status": "success",
415
"data": {"result": "ok"},
416
"timestamp": 1640995200
417
}
418
419
response = converter.structure(response_data, APIResponse) # Uses optimized function
420
```
421
422
## Performance Considerations
423
424
Generated functions provide significant performance improvements:
425
426
- **Structure functions**: 2-5x faster than generic converter methods
427
- **Unstructure functions**: 2-4x faster for complex objects
428
- **Bulk operations**: Even greater improvements for lists and mappings
429
- **Memory efficiency**: Reduced allocation overhead for repeated operations
430
431
Best practices:
432
- Generate functions once and reuse them
433
- Use overrides to avoid runtime field processing
434
- Consider generating functions for performance-critical code paths
435
- Combine with converter hooks for seamless integration
436
437
## Types
438
439
```python { .api }
440
from typing import TypeVar, Callable, Any, Dict, List, Tuple, Type
441
from cattrs.gen import AttributeOverride
442
443
T = TypeVar('T')
444
445
# Function type aliases
446
StructureFn = Callable[[Dict[str, Any]], T]
447
UnstructureFn = Callable[[T], Dict[str, Any]]
448
HeteroTupleUnstructureFn = Callable[[Tuple], Tuple]
449
IterableUnstructureFn = Callable[[List[T]], List[Any]]
450
MappingUnstructureFn = Callable[[Dict[Any, T]], Dict[Any, Any]]
451
452
# Override types
453
AttributeOverrides = Dict[str, AttributeOverride]
454
OverrideMapping = Dict[str, Any]
455
```