or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdnaming.mdparsing.mdserialization.md

parsing.mddocs/

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.