0
# Data Parsing
1
2
Comprehensive functionality for converting dictionaries and other data structures into dataclass instances. The parsing system handles complex nested types, custom type factories, naming policies, and provides detailed error tracking for debugging.
3
4
## Capabilities
5
6
### ParserFactory
7
8
Main factory class for creating and caching parsers that convert data to dataclass instances. The factory automatically detects types and creates appropriate parsers with caching for performance optimization.
9
10
```python { .api }
11
class ParserFactory:
12
def __init__(
13
self,
14
trim_trailing_underscore: bool = True,
15
debug_path: bool = False,
16
type_factories: Dict[Type, Parser] = None,
17
name_styles: Dict[Type, NameStyle] = None,
18
):
19
"""
20
Create a parser factory with configuration options.
21
22
Args:
23
trim_trailing_underscore: Remove trailing underscores from field names
24
when looking up values in dictionaries (e.g., 'id_' becomes 'id')
25
debug_path: Enable debug path tracking in exceptions for easier debugging.
26
Causes some performance decrease but provides detailed error locations
27
type_factories: Custom parser functions for specific types
28
name_styles: Naming style mappings per dataclass type
29
"""
30
31
def get_parser(self, cls: ClassVar) -> Parser:
32
"""
33
Get or create a parser for the specified class.
34
35
Args:
36
cls: The target class to create parser for (typically a dataclass)
37
38
Returns:
39
Parser function that converts data to instances of cls
40
"""
41
```
42
43
### Convenience Parse Function
44
45
Simple function for one-off parsing operations without creating a factory instance. Not recommended for repeated use as it recreates the factory each time.
46
47
```python { .api }
48
def parse(
49
data,
50
cls,
51
trim_trailing_underscore: bool = True,
52
type_factories: Dict[Any, Callable] = None,
53
):
54
"""
55
Parse data into an instance of cls using default ParserFactory settings.
56
57
Args:
58
data: The data to parse (typically dict)
59
cls: Target class to parse into
60
trim_trailing_underscore: Remove trailing underscores from field names
61
type_factories: Custom parser functions for specific types
62
63
Returns:
64
Instance of cls created from data
65
"""
66
```
67
68
### Usage Examples
69
70
#### Basic Dataclass Parsing
71
72
```python
73
from dataclasses import dataclass
74
from dataclass_factory import ParserFactory
75
76
@dataclass
77
class Product:
78
name: str
79
price: float
80
in_stock: bool = True
81
82
parser_factory = ParserFactory()
83
parser = parser_factory.get_parser(Product)
84
85
data = {
86
"name": "Laptop",
87
"price": 999.99,
88
"in_stock": False
89
}
90
91
product = parser(data)
92
# Result: Product(name="Laptop", price=999.99, in_stock=False)
93
```
94
95
#### Complex Nested Types
96
97
```python
98
from dataclasses import dataclass
99
from typing import List, Optional, Union
100
from dataclass_factory import ParserFactory
101
102
@dataclass
103
class Address:
104
street: str
105
city: str
106
country: str = "USA"
107
108
@dataclass
109
class Person:
110
name: str
111
age: int
112
addresses: List[Address]
113
phone: Optional[str] = None
114
id_number: Union[str, int] = None
115
116
parser_factory = ParserFactory()
117
parser = parser_factory.get_parser(Person)
118
119
data = {
120
"name": "John Doe",
121
"age": 30,
122
"addresses": [
123
{"street": "123 Main St", "city": "Anytown"},
124
{"street": "456 Oak Ave", "city": "Another City", "country": "Canada"}
125
],
126
"phone": "+1-555-0123",
127
"id_number": "ABC123"
128
}
129
130
person = parser(data)
131
```
132
133
#### Custom Type Factories
134
135
```python
136
from dataclasses import dataclass
137
from datetime import datetime
138
from dataclass_factory import ParserFactory
139
import dateutil.parser
140
141
@dataclass
142
class Event:
143
name: str
144
start_time: datetime
145
duration_minutes: int
146
147
# Create parser with custom datetime parsing
148
parser_factory = ParserFactory(
149
type_factories={datetime: dateutil.parser.parse}
150
)
151
parser = parser_factory.get_parser(Event)
152
153
data = {
154
"name": "Meeting",
155
"start_time": "2023-12-25T10:00:00",
156
"duration_minutes": 60
157
}
158
159
event = parser(data)
160
```
161
162
#### Naming Policies
163
164
```python
165
from dataclasses import dataclass
166
from dataclass_factory import ParserFactory, NameStyle
167
168
@dataclass
169
class ApiResponse:
170
user_name: str
171
last_login: str
172
is_active: bool
173
174
# Parse from camelCase JSON
175
parser_factory = ParserFactory(
176
name_styles={ApiResponse: NameStyle.camel_lower}
177
)
178
parser = parser_factory.get_parser(ApiResponse)
179
180
camel_case_data = {
181
"userName": "johndoe",
182
"lastLogin": "2023-12-25",
183
"isActive": True
184
}
185
186
response = parser(camel_case_data)
187
# Result: ApiResponse(user_name="johndoe", last_login="2023-12-25", is_active=True)
188
```
189
190
#### Debug Path Tracking
191
192
```python
193
from dataclasses import dataclass
194
from dataclass_factory import ParserFactory
195
196
@dataclass
197
class NestedData:
198
items: List[Dict[str, int]]
199
200
parser_factory = ParserFactory(debug_path=True)
201
parser = parser_factory.get_parser(NestedData)
202
203
try:
204
# This will fail because "invalid" is not an int
205
invalid_data = {
206
"items": [
207
{"a": 1, "b": 2},
208
{"c": "invalid", "d": 4} # Error here
209
]
210
}
211
result = parser(invalid_data)
212
except ValueError as e:
213
print(f"Error: {e}")
214
# With debug_path=True, error includes path information
215
```
216
217
## Types
218
219
```python { .api }
220
from typing import Callable, Any
221
222
Parser = Callable[[Any], Any]
223
```
224
225
## Error Handling
226
227
The parsing system raises `ValueError` and `TypeError` exceptions when data cannot be converted to the target type. When `debug_path=True` is enabled in the ParserFactory, error messages include the full path to the problematic field for easier debugging.
228
229
**Note**: The library internally uses custom exception classes, but these are not part of the public API. Applications should catch standard Python exceptions (`ValueError`, `TypeError`) for error handling.