or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-serialization.mdfield-configuration.mdformat-modules.mdindex.mdtype-system.mdunion-handling.md

field-configuration.mddocs/

0

# Field Configuration and Customization

1

2

Advanced field-level configuration for customizing serialization behavior, field renaming, conditional serialization, custom serializers, and field flattening. The field function provides fine-grained control over how individual fields are processed.

3

4

## Capabilities

5

6

### Field Definition

7

8

The field function extends dataclasses.field with serialization-specific parameters.

9

10

```python { .api }

11

def field(

12

default=...,

13

default_factory=...,

14

init: bool = True,

15

repr: bool = True,

16

hash: bool | None = None,

17

compare: bool = True,

18

metadata: dict | None = None,

19

rename: str | None = None,

20

alias: list[str] | None = None,

21

serializer: Callable | None = None,

22

deserializer: Callable | None = None,

23

flatten: bool = False,

24

skip: bool = False,

25

skip_if: Callable | None = None,

26

skip_if_false: bool = False,

27

skip_if_default: bool = False,

28

) -> Any:

29

"""

30

Define field with serialization parameters.

31

32

Standard dataclass parameters:

33

- default: Default value for the field

34

- default_factory: Function to generate default value

35

- init: Include field in __init__

36

- repr: Include field in __repr__

37

- hash: Include field in __hash__

38

- compare: Include field in comparison operations

39

- metadata: Additional metadata dictionary

40

41

pyserde-specific parameters:

42

- rename: Alternative name for serialization

43

- alias: List of alternative names for deserialization

44

- serializer: Custom serializer function for this field

45

- deserializer: Custom deserializer function for this field

46

- flatten: Flatten nested object fields into parent

47

- skip: Skip field during serialization/deserialization

48

- skip_if: Function to conditionally skip field

49

- skip_if_false: Skip field if value is falsy

50

- skip_if_default: Skip field if value equals default

51

52

Returns:

53

Field descriptor with custom serialization behavior

54

"""

55

```

56

57

### Custom Serializers and Deserializers

58

59

Functions for registering global custom serialization logic.

60

61

```python { .api }

62

def add_serializer(serializer: ClassSerializer) -> None:

63

"""

64

Register custom global serializer.

65

66

Parameters:

67

- serializer: ClassSerializer instance to register globally

68

"""

69

70

def add_deserializer(deserializer: ClassDeserializer) -> None:

71

"""

72

Register custom global deserializer.

73

74

Parameters:

75

- deserializer: ClassDeserializer instance to register globally

76

"""

77

78

def default_serializer(_cls: type[Any], obj: Any) -> Any:

79

"""

80

Marker function to tell serde to use the default serializer.

81

Used when custom serializer is specified at the class level but

82

you want to override a field with the default serializer.

83

84

Parameters:

85

- _cls: Class type (not used)

86

- obj: Object to serialize

87

88

Returns:

89

Serialized representation using default logic

90

"""

91

92

def default_deserializer(_cls: type[Any], obj: Any) -> Any:

93

"""

94

Marker function to tell serde to use the default deserializer.

95

Used when custom deserializer is specified at the class level but

96

you want to override a field with the default deserializer.

97

98

Parameters:

99

- _cls: Class type to deserialize to

100

- obj: Object to deserialize

101

102

Returns:

103

Deserialized object using default logic

104

"""

105

```

106

107

### Class-Level Serializers

108

109

Protocol classes for implementing custom class-level serialization behavior.

110

111

```python { .api }

112

class ClassSerializer(Protocol):

113

"""Protocol for custom class serializers."""

114

115

def serialize(self, obj: Any) -> Any:

116

"""

117

Serialize object to intermediate representation.

118

119

Parameters:

120

- obj: Object to serialize

121

122

Returns:

123

Serialized representation

124

"""

125

126

class ClassDeserializer(Protocol):

127

"""Protocol for custom class deserializers."""

128

129

def deserialize(self, cls: type, data: Any) -> Any:

130

"""

131

Deserialize data to object instance.

132

133

Parameters:

134

- cls: Target class type

135

- data: Data to deserialize

136

137

Returns:

138

Deserialized object instance

139

"""

140

```

141

142

## Usage Examples

143

144

### Field Renaming

145

146

```python

147

from serde import serde, field

148

149

@serde

150

class User:

151

username: str = field(rename="user_name")

152

email_address: str = field(rename="email")

153

full_name: str = field(rename="name")

154

155

user = User("alice", "alice@example.com", "Alice Smith")

156

data = to_dict(user)

157

# {'user_name': 'alice', 'email': 'alice@example.com', 'name': 'Alice Smith'}

158

```

159

160

### Conditional Field Skipping

161

162

```python

163

from serde import serde, field

164

165

@serde

166

class Config:

167

host: str

168

port: int

169

debug: bool = field(skip_if_false=True)

170

secret_key: str | None = field(skip_if=lambda x: x is None)

171

default_timeout: int = field(default=30, skip_if_default=True)

172

173

config = Config("localhost", 8080, False, None, 30)

174

data = to_dict(config)

175

# {'host': 'localhost', 'port': 8080} # debug, secret_key, and default_timeout skipped

176

```

177

178

### Custom Field Serializers

179

180

```python

181

from serde import serde, field

182

from datetime import datetime

183

184

def serialize_timestamp(dt: datetime) -> int:

185

return int(dt.timestamp())

186

187

def deserialize_timestamp(cls, timestamp: int) -> datetime:

188

return datetime.fromtimestamp(timestamp)

189

190

@serde

191

class Event:

192

name: str

193

created_at: datetime = field(

194

serializer=serialize_timestamp,

195

deserializer=deserialize_timestamp

196

)

197

198

event = Event("Meeting", datetime(2023, 12, 25, 10, 30))

199

data = to_dict(event)

200

# {'name': 'Meeting', 'created_at': 1703502600}

201

```

202

203

### Field Flattening

204

205

```python

206

from serde import serde, field

207

208

@serde

209

class Address:

210

street: str

211

city: str

212

country: str

213

214

@serde

215

class Person:

216

name: str

217

age: int

218

address: Address = field(flatten=True)

219

220

person = Person("Alice", 30, Address("123 Main St", "Boston", "USA"))

221

data = to_dict(person)

222

# {

223

# 'name': 'Alice',

224

# 'age': 30,

225

# 'street': '123 Main St',

226

# 'city': 'Boston',

227

# 'country': 'USA'

228

# }

229

```

230

231

### Global Custom Serializers

232

233

```python

234

from serde import serde, add_serializer, add_deserializer

235

from decimal import Decimal

236

237

def decimal_serializer(obj: Decimal) -> str:

238

return str(obj)

239

240

def decimal_deserializer(cls, data: str) -> Decimal:

241

return Decimal(data)

242

243

# Register global serializers

244

add_serializer(Decimal, decimal_serializer)

245

add_deserializer(Decimal, decimal_deserializer)

246

247

@serde

248

class Product:

249

name: str

250

price: Decimal

251

252

product = Product("Widget", Decimal("19.99"))

253

data = to_dict(product)

254

# {'name': 'Widget', 'price': '19.99'}

255

```

256

257

### Class-Level Custom Serializers

258

259

```python

260

from serde import serde, ClassSerializer, ClassDeserializer

261

262

class TimestampSerializer:

263

def serialize(self, obj):

264

result = {}

265

for field_name, field_value in obj.__dict__.items():

266

if isinstance(field_value, datetime):

267

result[field_name] = int(field_value.timestamp())

268

else:

269

result[field_name] = field_value

270

return result

271

272

class TimestampDeserializer:

273

def deserialize(self, cls, data):

274

kwargs = {}

275

for field_name, field_value in data.items():

276

field_type = cls.__annotations__.get(field_name)

277

if field_type == datetime:

278

kwargs[field_name] = datetime.fromtimestamp(field_value)

279

else:

280

kwargs[field_name] = field_value

281

return cls(**kwargs)

282

283

@serde(

284

class_serializer=TimestampSerializer(),

285

class_deserializer=TimestampDeserializer()

286

)

287

class LogEntry:

288

message: str

289

timestamp: datetime

290

level: str

291

```