or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdnaming.mdparsing.mdserialization.md

serialization.mddocs/

0

# Data Serialization

1

2

High-performance functionality for converting dataclass instances back to dictionaries and other data structures. The serialization system provides up to 10x performance improvement over Python's standard `asdict()` function with support for custom serializers and naming policies.

3

4

## Capabilities

5

6

### SerializerFactory

7

8

Main factory class for creating and caching serializers that convert dataclass instances to dictionaries. The factory automatically detects types and creates appropriate serializers with caching for optimal performance.

9

10

```python { .api }

11

class SerializerFactory:

12

def __init__(

13

self,

14

trim_trailing_underscore: bool = True,

15

debug_path: bool = False,

16

type_serializers: Dict[Type, Serializer] = None,

17

name_styles: Dict[Type, NameStyle] = None,

18

):

19

"""

20

Create a serializer factory with configuration options.

21

22

Args:

23

trim_trailing_underscore: Remove trailing underscores from field names

24

in output dictionaries (e.g., 'id_' field becomes 'id' key)

25

debug_path: Reserved for future use (not implemented in serializers)

26

type_serializers: Custom serializer functions for specific types

27

name_styles: Naming style mappings per dataclass type

28

"""

29

30

def get_serializer(self, cls: Any) -> Serializer:

31

"""

32

Get or create a serializer for the specified class.

33

34

Args:

35

cls: The class type to create serializer for

36

37

Returns:

38

Serializer function that converts instances of cls to dictionaries

39

"""

40

```

41

42

### Legacy Dict Factory

43

44

Legacy function for use with Python's standard `asdict()`. Still provided for compatibility but not recommended for new code as it will be removed in future versions.

45

46

```python { .api }

47

def dict_factory(

48

trim_trailing_underscore: bool = True,

49

skip_none: bool = False,

50

skip_internal: bool = False,

51

type_serializers: Dict[type, Callable] = None

52

):

53

"""

54

Create a dict factory function for use with dataclasses.asdict().

55

56

Args:

57

trim_trailing_underscore: Remove trailing underscores from field names

58

skip_none: Skip fields with None values

59

skip_internal: Skip fields starting with underscore

60

type_serializers: Custom serializers for specific types

61

62

Returns:

63

Dict factory function for use with asdict()

64

"""

65

```

66

67

### Usage Examples

68

69

#### Basic Dataclass Serialization

70

71

```python

72

from dataclasses import dataclass

73

from dataclass_factory import SerializerFactory

74

75

@dataclass

76

class Product:

77

name: str

78

price: float

79

in_stock: bool = True

80

81

serializer_factory = SerializerFactory()

82

serializer = serializer_factory.get_serializer(Product)

83

84

product = Product("Laptop", 999.99, False)

85

data = serializer(product)

86

# Result: {"name": "Laptop", "price": 999.99, "in_stock": False}

87

```

88

89

#### Complex Nested Types

90

91

```python

92

from dataclasses import dataclass

93

from typing import List, Optional

94

from dataclass_factory import SerializerFactory

95

96

@dataclass

97

class Address:

98

street: str

99

city: str

100

country: str = "USA"

101

102

@dataclass

103

class Person:

104

name: str

105

age: int

106

addresses: List[Address]

107

phone: Optional[str] = None

108

109

serializer_factory = SerializerFactory()

110

serializer = serializer_factory.get_serializer(Person)

111

112

person = Person(

113

name="John Doe",

114

age=30,

115

addresses=[

116

Address("123 Main St", "Anytown"),

117

Address("456 Oak Ave", "Another City", "Canada")

118

],

119

phone="+1-555-0123"

120

)

121

122

data = serializer(person)

123

# Result: {

124

# "name": "John Doe",

125

# "age": 30,

126

# "addresses": [

127

# {"street": "123 Main St", "city": "Anytown", "country": "USA"},

128

# {"street": "456 Oak Ave", "city": "Another City", "country": "Canada"}

129

# ],

130

# "phone": "+1-555-0123"

131

# }

132

```

133

134

#### Custom Type Serializers

135

136

```python

137

from dataclasses import dataclass

138

from datetime import datetime

139

from dataclass_factory import SerializerFactory

140

141

@dataclass

142

class Event:

143

name: str

144

start_time: datetime

145

duration_minutes: int

146

147

# Create serializer with custom datetime formatting

148

serializer_factory = SerializerFactory(

149

type_serializers={datetime: lambda dt: dt.isoformat()}

150

)

151

serializer = serializer_factory.get_serializer(Event)

152

153

event = Event(

154

name="Meeting",

155

start_time=datetime(2023, 12, 25, 10, 0, 0),

156

duration_minutes=60

157

)

158

159

data = serializer(event)

160

# Result: {

161

# "name": "Meeting",

162

# "start_time": "2023-12-25T10:00:00",

163

# "duration_minutes": 60

164

# }

165

```

166

167

#### Naming Policies

168

169

```python

170

from dataclasses import dataclass

171

from dataclass_factory import SerializerFactory, NameStyle

172

173

@dataclass

174

class ApiResponse:

175

user_name: str

176

last_login: str

177

is_active: bool

178

179

# Serialize to camelCase

180

serializer_factory = SerializerFactory(

181

name_styles={ApiResponse: NameStyle.camel_lower}

182

)

183

serializer = serializer_factory.get_serializer(ApiResponse)

184

185

response = ApiResponse(

186

user_name="johndoe",

187

last_login="2023-12-25",

188

is_active=True

189

)

190

191

camel_case_data = serializer(response)

192

# Result: {

193

# "userName": "johndoe",

194

# "lastLogin": "2023-12-25",

195

# "isActive": True

196

# }

197

```

198

199

#### Trailing Underscore Handling

200

201

```python

202

from dataclasses import dataclass

203

from dataclass_factory import SerializerFactory

204

205

@dataclass

206

class DataWithKeywords:

207

class_: str # 'class' is a Python keyword

208

type_: str # 'type' is a Python builtin

209

id_: int # Common pattern to avoid 'id' builtin

210

211

serializer_factory = SerializerFactory(trim_trailing_underscore=True)

212

serializer = serializer_factory.get_serializer(DataWithKeywords)

213

214

data_obj = DataWithKeywords("MyClass", "string", 123)

215

result = serializer(data_obj)

216

# Result: {"class": "MyClass", "type": "string", "id": 123}

217

218

# Without trimming (trim_trailing_underscore=False)

219

serializer_no_trim = SerializerFactory(trim_trailing_underscore=False)

220

serializer_no_trim_func = serializer_no_trim.get_serializer(DataWithKeywords)

221

result_no_trim = serializer_no_trim_func(data_obj)

222

# Result: {"class_": "MyClass", "type_": "string", "id_": 123}

223

```

224

225

#### Using Legacy Dict Factory

226

227

```python

228

from dataclasses import dataclass, asdict

229

from enum import Enum

230

from dataclass_factory import dict_factory

231

232

class Status(Enum):

233

ACTIVE = "active"

234

INACTIVE = "inactive"

235

236

@dataclass

237

class User:

238

name: str

239

status: Status

240

id_: int

241

242

user = User("John", Status.ACTIVE, 123)

243

244

# Using custom dict factory with asdict

245

factory = dict_factory(

246

trim_trailing_underscore=True,

247

skip_none=True

248

)

249

result = asdict(user, dict_factory=factory)

250

# Result: {"name": "John", "status": "active", "id": 123}

251

```

252

253

## Types

254

255

```python { .api }

256

from typing import Callable, Any

257

258

Serializer = Callable[[Any], Any]

259

```

260

261

## Performance

262

263

SerializerFactory provides significant performance improvements over Python's standard `asdict()`:

264

265

- **Up to 10x faster** than `dataclasses.asdict()`

266

- **Caching**: Serializers are created once and cached for reuse

267

- **Type optimization**: Direct field access without reflection overhead

268

- **Optimized nested handling**: Efficient processing of complex nested structures

269

270

For best performance:

271

1. Create SerializerFactory once at application startup

272

2. Reuse serializers for the same types

273

3. Use type_serializers for expensive custom type conversions