0
# Dataclasses and Type Adapters
1
2
Integration with Python dataclasses and standalone type validation without model inheritance.
3
4
## Capabilities
5
6
### Pydantic Dataclasses
7
8
Enhanced dataclasses with pydantic validation, providing dataclass syntax with pydantic's validation capabilities.
9
10
```python { .api }
11
def dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False,
12
frozen=False, config=None, validate_on_init=None, use_enum_values=None,
13
kw_only=False, slots=False):
14
"""
15
Decorator to create pydantic dataclass with validation.
16
17
Args:
18
init (bool): Generate __init__ method
19
repr (bool): Generate __repr__ method
20
eq (bool): Generate __eq__ method
21
order (bool): Generate comparison methods
22
unsafe_hash (bool): Generate __hash__ method
23
frozen (bool): Make instances immutable
24
config: Pydantic configuration
25
validate_on_init (bool): Validate during initialization
26
use_enum_values (bool): Use enum values instead of instances
27
kw_only (bool): Make all fields keyword-only
28
slots (bool): Generate __slots__
29
30
Returns:
31
Decorated dataclass with pydantic validation
32
"""
33
34
class Field:
35
"""
36
Field definition for pydantic dataclasses.
37
38
Similar to pydantic.Field but for dataclass fields.
39
"""
40
41
def __init__(self, default=dataclasses.MISSING, *, default_factory=dataclasses.MISSING,
42
init=True, repr=True, hash=None, compare=True, metadata=None, **kwargs):
43
"""
44
Initialize dataclass field.
45
46
Args:
47
default: Default value
48
default_factory: Factory for default values
49
init (bool): Include in __init__
50
repr (bool): Include in __repr__
51
hash (bool): Include in __hash__
52
compare (bool): Include in comparison methods
53
metadata (dict): Field metadata
54
**kwargs: Additional pydantic field options
55
"""
56
```
57
58
### Type Adapters
59
60
Standalone validation for any type without requiring model inheritance, useful for validating individual values or complex types.
61
62
```python { .api }
63
class TypeAdapter(Generic[T]):
64
"""
65
Type adapter for validating and serializing any type.
66
67
Provides pydantic validation for types without BaseModel inheritance.
68
"""
69
70
def __init__(self, type_: type, *, config=None, _root=True):
71
"""
72
Initialize type adapter.
73
74
Args:
75
type_: Type to adapt
76
config: Validation configuration
77
_root (bool): Whether this is a root type adapter
78
"""
79
80
def validate_python(self, obj, /, *, strict=None, from_attributes=None, context=None):
81
"""
82
Validate Python object against the type.
83
84
Args:
85
obj: Object to validate
86
strict (bool): Enable strict validation
87
from_attributes (bool): Extract data from object attributes
88
context (dict): Validation context
89
90
Returns:
91
Validated object of the specified type
92
93
Raises:
94
ValidationError: If validation fails
95
"""
96
97
def validate_json(self, json_data, /, *, strict=None, context=None):
98
"""
99
Validate JSON string against the type.
100
101
Args:
102
json_data (str | bytes): JSON data to validate
103
strict (bool): Enable strict validation
104
context (dict): Validation context
105
106
Returns:
107
Validated object of the specified type
108
109
Raises:
110
ValidationError: If validation fails
111
"""
112
113
def validate_strings(self, obj, /, *, strict=None, context=None):
114
"""
115
Validate with string inputs against the type.
116
117
Args:
118
obj: Object to validate
119
strict (bool): Enable strict validation
120
context (dict): Validation context
121
122
Returns:
123
Validated object of the specified type
124
125
Raises:
126
ValidationError: If validation fails
127
"""
128
129
def dump_python(self, instance, /, *, mode='python', include=None, exclude=None,
130
context=None, by_alias=False, exclude_unset=False, exclude_defaults=False,
131
exclude_none=False, round_trip=False, warnings=True, serialize_as_any=False):
132
"""
133
Serialize instance to Python object.
134
135
Args:
136
instance: Instance to serialize
137
mode (str): Serialization mode
138
include: Fields to include
139
exclude: Fields to exclude
140
context (dict): Serialization context
141
by_alias (bool): Use field aliases
142
exclude_unset (bool): Exclude unset fields
143
exclude_defaults (bool): Exclude default values
144
exclude_none (bool): Exclude None values
145
round_trip (bool): Enable round-trip serialization
146
warnings (bool): Show serialization warnings
147
serialize_as_any (bool): Serialize using Any serializer
148
149
Returns:
150
Serialized Python object
151
"""
152
153
def dump_json(self, instance, /, *, indent=None, include=None, exclude=None,
154
context=None, by_alias=False, exclude_unset=False, exclude_defaults=False,
155
exclude_none=False, round_trip=False, warnings=True, serialize_as_any=False):
156
"""
157
Serialize instance to JSON string.
158
159
Args:
160
instance: Instance to serialize
161
indent (int): JSON indentation
162
include: Fields to include
163
exclude: Fields to exclude
164
context (dict): Serialization context
165
by_alias (bool): Use field aliases
166
exclude_unset (bool): Exclude unset fields
167
exclude_defaults (bool): Exclude default values
168
exclude_none (bool): Exclude None values
169
round_trip (bool): Enable round-trip serialization
170
warnings (bool): Show serialization warnings
171
serialize_as_any (bool): Serialize using Any serializer
172
173
Returns:
174
str: JSON string
175
"""
176
177
def json_schema(self, *, by_alias=True, ref_template='#/$defs/{model}'):
178
"""
179
Generate JSON schema for the type.
180
181
Args:
182
by_alias (bool): Use field aliases in schema
183
ref_template (str): Template for schema references
184
185
Returns:
186
dict: JSON schema
187
"""
188
189
@property
190
def core_schema(self):
191
"""dict: Core schema for the type"""
192
193
@property
194
def validator(self):
195
"""Validator: Core validator instance"""
196
197
@property
198
def serializer(self):
199
"""Serializer: Core serializer instance"""
200
```
201
202
### Legacy Functions
203
204
Legacy functions for backward compatibility with pydantic v1.
205
206
```python { .api }
207
def parse_obj_as(type_, obj):
208
"""
209
Parse object as specified type (legacy function).
210
211
Args:
212
type_: Type to parse as
213
obj: Object to parse
214
215
Returns:
216
Parsed object
217
218
Note:
219
Deprecated: Use TypeAdapter.validate_python() instead
220
"""
221
222
def schema_of(type_, *, title='Generated schema'):
223
"""
224
Generate schema for type (legacy function).
225
226
Args:
227
type_: Type to generate schema for
228
title (str): Schema title
229
230
Returns:
231
dict: Type schema
232
233
Note:
234
Deprecated: Use TypeAdapter.json_schema() instead
235
"""
236
```
237
238
## Usage Examples
239
240
### Pydantic Dataclasses
241
242
```python
243
from pydantic.dataclasses import dataclass, Field
244
from typing import Optional
245
from datetime import datetime
246
247
@dataclass
248
class User:
249
id: int
250
name: str = Field(..., min_length=1, max_length=100)
251
email: str = Field(..., regex=r'^[\w\.-]+@[\w\.-]+\.\w+$')
252
age: Optional[int] = Field(None, ge=0, le=150)
253
created_at: datetime = Field(default_factory=datetime.now)
254
active: bool = True
255
256
# Usage like regular dataclass with validation
257
user = User(
258
id=123,
259
name="John Doe",
260
email="john@example.com",
261
age=30
262
)
263
264
print(user.name) # "John Doe"
265
print(user.active) # True
266
267
# Validation errors are raised for invalid data
268
try:
269
invalid_user = User(id=123, name="", email="invalid")
270
except ValueError as e:
271
print(f"Validation error: {e}")
272
```
273
274
### Dataclass Configuration
275
276
```python
277
from pydantic.dataclasses import dataclass
278
from pydantic import ConfigDict
279
280
@dataclass(config=ConfigDict(str_strip_whitespace=True, frozen=True))
281
class ImmutableUser:
282
name: str
283
email: str
284
285
# Whitespace is stripped, object is immutable
286
user = ImmutableUser(name=" John ", email="john@example.com")
287
print(user.name) # "John"
288
289
# This would raise an error - object is frozen
290
# user.name = "Jane"
291
```
292
293
### TypeAdapter for Simple Types
294
295
```python
296
from pydantic import TypeAdapter, ValidationError
297
from typing import List
298
299
# Create adapter for list of integers
300
list_adapter = TypeAdapter(List[int])
301
302
# Validate Python objects
303
valid_list = list_adapter.validate_python([1, 2, 3, "4"]) # "4" converted to 4
304
print(valid_list) # [1, 2, 3, 4]
305
306
# Validate JSON
307
json_list = list_adapter.validate_json('[1, 2, 3, 4]')
308
print(json_list) # [1, 2, 3, 4]
309
310
# Handle validation errors
311
try:
312
invalid_list = list_adapter.validate_python([1, 2, "invalid"])
313
except ValidationError as e:
314
print(f"Validation failed: {e}")
315
316
# Serialize back to JSON
317
json_output = list_adapter.dump_json([1, 2, 3, 4])
318
print(json_output) # '[1,2,3,4]'
319
```
320
321
### TypeAdapter for Complex Types
322
323
```python
324
from pydantic import TypeAdapter
325
from typing import Dict, List, Optional
326
from datetime import datetime
327
328
# Complex nested type
329
ComplexType = Dict[str, List[Dict[str, Optional[datetime]]]]
330
331
adapter = TypeAdapter(ComplexType)
332
333
# Validate complex data structure
334
data = {
335
"events": [
336
{"timestamp": "2023-12-25T10:30:00", "name": None},
337
{"timestamp": "2023-12-26T15:45:00", "name": "2023-12-26T16:00:00"}
338
],
339
"logs": [
340
{"created": "2023-12-25T08:00:00", "level": None}
341
]
342
}
343
344
validated_data = adapter.validate_python(data)
345
print(type(validated_data["events"][0]["timestamp"])) # <class 'datetime.datetime'>
346
347
# Generate JSON schema
348
schema = adapter.json_schema()
349
print(schema) # Complete JSON schema for the complex type
350
```
351
352
### TypeAdapter with Custom Types
353
354
```python
355
from pydantic import TypeAdapter, field_validator
356
from typing import Annotated
357
358
def validate_positive(v):
359
if v <= 0:
360
raise ValueError("Must be positive")
361
return v
362
363
# Create adapter for annotated type
364
PositiveInt = Annotated[int, field_validator(validate_positive)]
365
adapter = TypeAdapter(PositiveInt)
366
367
# Validate with custom logic
368
valid_value = adapter.validate_python(42) # OK
369
print(valid_value) # 42
370
371
try:
372
invalid_value = adapter.validate_python(-5) # Raises ValidationError
373
except ValidationError as e:
374
print(f"Custom validation failed: {e}")
375
```
376
377
### Integration with Existing Classes
378
379
```python
380
from pydantic import TypeAdapter
381
from dataclasses import dataclass as stdlib_dataclass
382
from typing import List
383
384
# Regular Python dataclass (not pydantic)
385
@stdlib_dataclass
386
class Point:
387
x: float
388
y: float
389
390
# Use TypeAdapter to add validation
391
PointList = List[Point]
392
adapter = TypeAdapter(PointList)
393
394
# Validate list of points
395
points_data = [
396
{"x": 1.0, "y": 2.0},
397
{"x": 3.5, "y": 4.2}
398
]
399
400
validated_points = adapter.validate_python(points_data)
401
print(validated_points) # [Point(x=1.0, y=2.0), Point(x=3.5, y=4.2)]
402
print(type(validated_points[0])) # <class '__main__.Point'>
403
```
404
405
### Legacy Functions
406
407
```python
408
from pydantic import parse_obj_as, schema_of, ValidationError
409
from typing import List, Dict
410
411
# Legacy parsing (use TypeAdapter instead in new code)
412
data = [{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]
413
UserDict = Dict[str, str | int]
414
415
try:
416
parsed = parse_obj_as(List[UserDict], data)
417
print(parsed) # [{'name': 'John', 'age': 30}, {'name': 'Jane', 'age': 25}]
418
except ValidationError as e:
419
print(f"Parsing failed: {e}")
420
421
# Legacy schema generation (use TypeAdapter instead in new code)
422
schema = schema_of(List[UserDict], title="User List Schema")
423
print(schema) # JSON schema for List[Dict[str, str | int]]
424
```
425
426
### Dataclass with Validation
427
428
```python
429
from pydantic.dataclasses import dataclass
430
from pydantic import field_validator, model_validator
431
from typing import Optional
432
433
@dataclass
434
class Rectangle:
435
width: float
436
height: float
437
name: Optional[str] = None
438
439
@field_validator('width', 'height')
440
@classmethod
441
def validate_dimensions(cls, v):
442
if v <= 0:
443
raise ValueError('Dimensions must be positive')
444
return v
445
446
@model_validator(mode='after')
447
def validate_aspect_ratio(self):
448
if self.width / self.height > 10 or self.height / self.width > 10:
449
raise ValueError('Aspect ratio too extreme')
450
return self
451
452
@property
453
def area(self):
454
return self.width * self.height
455
456
# Usage with validation
457
rect = Rectangle(width=5.0, height=3.0, name="My Rectangle")
458
print(f"Area: {rect.area}") # Area: 15.0
459
460
# Validation error for invalid dimensions
461
try:
462
invalid_rect = Rectangle(width=-1.0, height=3.0)
463
except ValueError as e:
464
print(f"Validation error: {e}")
465
```