or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

class-definition.mdconfiguration-errors.mdfield-configuration.mdindex.mdutilities.mdvalidation-conversion.md

field-configuration.mddocs/

0

# Field Configuration

1

2

Define attributes with validation, conversion, default values, and metadata using both modern and legacy APIs. Fields provide fine-grained control over attribute behavior, serialization, and validation.

3

4

## Capabilities

5

6

### Modern Field Definition

7

8

#### Field Function

9

Define attributes with comprehensive configuration options for modern attrs classes.

10

11

```python { .api }

12

def field(

13

*,

14

default=NOTHING,

15

factory=None,

16

validator=None,

17

repr=True,

18

hash=None,

19

init=True,

20

metadata=None,

21

converter=None,

22

kw_only=False,

23

eq=True,

24

order=None,

25

on_setattr=None,

26

alias=None,

27

type=None,

28

):

29

"""

30

Define a field for attrs classes with comprehensive configuration.

31

32

Parameters:

33

- default (Any): Default value for the attribute

34

- factory (callable, optional): Function to generate default values

35

- validator (callable or list, optional): Validation function(s)

36

- repr (bool): Include in __repr__ output (default: True)

37

- hash (bool, optional): Include in __hash__ calculation

38

- init (bool): Include in __init__ method (default: True)

39

- metadata (dict, optional): Arbitrary metadata for the field

40

- converter (callable or list, optional): Value conversion function(s)

41

- kw_only (bool): Make this field keyword-only (default: False)

42

- eq (bool): Include in equality comparison (default: True)

43

- order (bool, optional): Include in ordering comparison

44

- on_setattr (callable or list, optional): Hooks for attribute setting

45

- alias (str, optional): Alternative name for the field in __init__

46

- type (type, optional): Type annotation for the field

47

48

Returns:

49

Field descriptor for use in class definitions

50

"""

51

```

52

53

Usage examples:

54

```python

55

@attrs.define

56

class Person:

57

# Simple field with default

58

name: str = attrs.field()

59

60

# Field with validation

61

age: int = attrs.field(validator=attrs.validators.instance_of(int))

62

63

# Field with factory function

64

created_at: datetime = attrs.field(factory=datetime.now)

65

66

# Field excluded from repr

67

password: str = attrs.field(repr=False)

68

69

# Keyword-only field

70

debug: bool = attrs.field(default=False, kw_only=True)

71

72

# Field with converter

73

tags: list = attrs.field(factory=list, converter=list)

74

75

# Field with metadata

76

score: float = attrs.field(

77

default=0.0,

78

metadata={"unit": "points", "min": 0.0, "max": 100.0}

79

)

80

```

81

82

### Legacy Field Definition

83

84

#### Attrib Function

85

Define attributes using the legacy API with comprehensive configuration options.

86

87

```python { .api }

88

def attrib(

89

default=NOTHING,

90

validator=None,

91

repr=True,

92

cmp=None,

93

hash=None,

94

init=True,

95

metadata=None,

96

converter=None,

97

factory=None,

98

kw_only=False,

99

eq=None,

100

order=None,

101

on_setattr=None,

102

alias=None,

103

type=None,

104

):

105

"""

106

Legacy field definition with comprehensive configuration.

107

108

Parameters: Similar to field() but uses cmp instead of eq/order

109

- cmp (bool, optional): Include in comparison methods (deprecated, use eq/order)

110

- Other parameters same as field()

111

112

Returns:

113

Attribute descriptor for use in class definitions

114

"""

115

```

116

117

Usage examples:

118

```python

119

@attr.attrs

120

class Person:

121

name = attr.attrib()

122

age = attr.attrib(validator=attr.validators.instance_of(int))

123

email = attr.attrib(default="")

124

created_at = attr.attrib(factory=datetime.now)

125

```

126

127

### Field Aliases

128

129

Legacy aliases for backward compatibility:

130

131

```python { .api }

132

# In attr module

133

ib = attr = attrib # Field definition aliases

134

```

135

136

### Factory Functions

137

138

#### Factory Class

139

Wrapper for factory functions that generate default values.

140

141

```python { .api }

142

class Factory:

143

"""

144

Wrapper for factory functions used as default values.

145

146

Attributes:

147

- factory (callable): Function to generate default values

148

- takes_self (bool): Whether factory function receives instance as first argument

149

"""

150

151

def __init__(self, factory, takes_self=False):

152

"""

153

Create a factory wrapper.

154

155

Parameters:

156

- factory (callable): Function to call for default values

157

- takes_self (bool): Pass instance as first argument (default: False)

158

"""

159

```

160

161

Usage examples:

162

```python

163

@attrs.define

164

class Record:

165

# Simple factory

166

created_at: datetime = attrs.field(factory=datetime.now)

167

168

# Factory that takes self

169

id: str = attrs.field(factory=Factory(lambda self: f"{self.name}_{uuid.uuid4()}", takes_self=True))

170

name: str = ""

171

172

# Using Factory class directly

173

data: dict = attrs.field(factory=Factory(dict))

174

```

175

176

### Converters

177

178

#### Converter Class

179

Wrapper for converter functions with additional context.

180

181

```python { .api }

182

class Converter:

183

"""

184

Wrapper for converter functions with context information.

185

186

Attributes:

187

- converter (callable): Function to convert values

188

- takes_self (bool): Whether converter receives instance as argument

189

- takes_field (bool): Whether converter receives field info as argument

190

"""

191

192

def __init__(self, converter, *, takes_self=False, takes_field=False):

193

"""

194

Create a converter wrapper.

195

196

Parameters:

197

- converter (callable): Function to convert values

198

- takes_self (bool): Pass instance as argument (default: False)

199

- takes_field (bool): Pass field info as argument (default: False)

200

"""

201

```

202

203

Usage examples:

204

```python

205

def normalize_email(value):

206

return value.lower().strip()

207

208

def context_converter(value, instance, field):

209

return f"{field.name}: {value} (from {instance.__class__.__name__})"

210

211

@attrs.define

212

class User:

213

email: str = attrs.field(converter=normalize_email)

214

name: str = attrs.field(converter=Converter(context_converter, takes_self=True, takes_field=True))

215

```

216

217

### Special Values

218

219

#### NOTHING Constant

220

Sentinel value indicating the absence of a value when None is ambiguous.

221

222

```python { .api }

223

NOTHING: NothingType # Sentinel for missing values

224

225

class NothingType:

226

"""Type for NOTHING literal value."""

227

228

def __bool__(self) -> False:

229

"""NOTHING is always falsy."""

230

```

231

232

Usage example:

233

```python

234

@attrs.define

235

class Config:

236

# Distinguish between None and not set

237

timeout: Optional[int] = attrs.field(default=NOTHING)

238

239

def get_timeout(self) -> int:

240

if self.timeout is NOTHING:

241

return 30 # Default timeout

242

return self.timeout

243

```

244

245

## Common Patterns

246

247

### Validation with Type Hints

248

```python

249

@attrs.define

250

class Point:

251

x: float = attrs.field(validator=attrs.validators.instance_of(float))

252

y: float = attrs.field(validator=attrs.validators.instance_of(float))

253

```

254

255

### Complex Default Values

256

```python

257

@attrs.define

258

class Configuration:

259

# Mutable defaults using factory

260

features: list = attrs.field(factory=list)

261

settings: dict = attrs.field(factory=dict)

262

263

# Computed defaults

264

created_at: datetime = attrs.field(factory=datetime.now)

265

id: str = attrs.field(factory=lambda: str(uuid.uuid4()))

266

```

267

268

### Field Exclusion and Control

269

```python

270

@attrs.define

271

class User:

272

username: str

273

password: str = attrs.field(repr=False) # Hide from repr

274

internal_id: int = attrs.field(init=False, eq=False) # Not in init or comparison

275

276

def __attrs_post_init__(self):

277

self.internal_id = hash(self.username)

278

```

279

280

### Metadata and Introspection

281

```python

282

@attrs.define

283

class APIField:

284

value: str = attrs.field(metadata={"api_name": "fieldValue", "required": True})

285

optional: str = attrs.field(default="", metadata={"api_name": "optionalField", "required": False})

286

287

# Access metadata

288

field_info = attrs.fields(APIField)

289

for field in field_info:

290

if field.metadata.get("required"):

291

print(f"Required field: {field.name}")

292

```

293

294

### Conversion Chains

295

```python

296

@attrs.define

297

class Document:

298

# Convert string to Path object

299

path: Path = attrs.field(converter=Path)

300

301

# Chain converters: strip whitespace, then convert to int

302

priority: int = attrs.field(

303

converter=attrs.converters.pipe(str.strip, int),

304

default="0"

305

)

306

```