or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

decorators-hooks.mdexceptions-utils.mdfield-types.mdindex.mdschema-definition.mdvalidation.md

exceptions-utils.mddocs/

0

# Exceptions and Utilities

1

2

Marshmallow provides structured exception types for error handling and utility functions for data manipulation, type checking, and advanced use cases.

3

4

## Capabilities

5

6

### Exception Classes

7

8

Comprehensive exception hierarchy for handling validation and processing errors.

9

10

```python { .api }

11

class MarshmallowError(Exception):

12

"""

13

Base exception class for all marshmallow-related errors.

14

"""

15

16

class ValidationError(MarshmallowError):

17

"""

18

Main exception raised when validation fails during deserialization.

19

20

Attributes:

21

- messages: dict/list/str, validation error messages

22

- field_name: str, name of the field where error occurred (if applicable)

23

- data: dict, raw input data that caused the error

24

- valid_data: dict, successfully validated data (if any)

25

"""

26

27

def __init__(self, message, field_name="_schema", data=None, valid_data=None, **kwargs):

28

"""

29

Initialize ValidationError.

30

31

Parameters:

32

- message: str/list/dict, error message(s)

33

- field_name: str, field name where error occurred (default: "_schema")

34

- data: dict, input data that failed validation

35

- valid_data: dict, any data that passed validation

36

"""

37

38

@property

39

def messages_dict(self):

40

"""

41

Get error messages as a dictionary.

42

43

Returns:

44

dict: error messages organized by field name

45

"""

46

47

class RegistryError(MarshmallowError):

48

"""

49

Raised for invalid schema registry operations.

50

"""

51

52

class StringNotCollectionError(ValidationError):

53

"""

54

Raised when a string is passed where a collection is expected.

55

"""

56

```

57

58

### Error Constants

59

60

```python { .api }

61

SCHEMA = "_schema" # Key used for schema-level validation errors

62

```

63

64

### Utility Functions

65

66

Helper functions for data manipulation and object introspection.

67

68

```python { .api }

69

def get_value(obj, key, default=missing):

70

"""

71

Get a value from an object by key with fallback support.

72

73

Parameters:

74

- obj: object to get value from (dict-like or object with attributes)

75

- key: str, key or attribute name (supports dot notation for nested access)

76

- default: default value if key is not found

77

78

Returns:

79

The value at the specified key, or default if not found

80

"""

81

82

def set_value(dct, key, value):

83

"""

84

Set a value in a dictionary using dot notation for nested keys.

85

86

Parameters:

87

- dct: dict, dictionary to modify

88

- key: str, key name (supports dot notation like 'user.profile.name')

89

- value: value to set

90

"""

91

92

def pluck(dictlist, key):

93

"""

94

Extract a list of values by key from a list of dictionaries.

95

96

Parameters:

97

- dictlist: list of dict, list of dictionaries

98

- key: str, key to extract from each dictionary

99

100

Returns:

101

list: values extracted from each dictionary

102

"""

103

```

104

105

### Type Checking Utilities

106

107

Functions for runtime type checking and validation.

108

109

```python { .api }

110

def is_collection(obj):

111

"""

112

Check if an object is a collection type (but not string/bytes).

113

114

Parameters:

115

- obj: object to check

116

117

Returns:

118

bool: True if object is a collection, False otherwise

119

"""

120

121

def is_iterable_but_not_string(obj):

122

"""

123

Check if an object is iterable but not a string or bytes.

124

125

Parameters:

126

- obj: object to check

127

128

Returns:

129

bool: True if iterable and not string/bytes

130

"""

131

132

def is_sequence_but_not_string(obj):

133

"""

134

Check if an object is a sequence but not a string or bytes.

135

136

Parameters:

137

- obj: object to check

138

139

Returns:

140

bool: True if sequence and not string/bytes

141

"""

142

143

def is_generator(obj):

144

"""

145

Check if an object is a generator.

146

147

Parameters:

148

- obj: object to check

149

150

Returns:

151

bool: True if object is a generator

152

"""

153

154

def callable_or_raise(obj):

155

"""

156

Check if an object is callable, raise TypeError if not.

157

158

Parameters:

159

- obj: object to check

160

161

Raises:

162

TypeError: if object is not callable

163

"""

164

```

165

166

### Date and Time Utilities

167

168

Functions for datetime conversion and manipulation.

169

170

```python { .api }

171

def is_aware(dt):

172

"""

173

Check if a datetime object is timezone-aware.

174

175

Parameters:

176

- dt: datetime object to check

177

178

Returns:

179

bool: True if datetime is timezone-aware

180

"""

181

182

def from_timestamp(value):

183

"""

184

Convert a POSIX timestamp to a datetime object.

185

186

Parameters:

187

- value: numeric timestamp (seconds since epoch)

188

189

Returns:

190

datetime: datetime object in UTC

191

"""

192

193

def from_timestamp_ms(value):

194

"""

195

Convert a millisecond timestamp to a datetime object.

196

197

Parameters:

198

- value: numeric timestamp (milliseconds since epoch)

199

200

Returns:

201

datetime: datetime object in UTC

202

"""

203

204

def timestamp(value):

205

"""

206

Convert a datetime object to a POSIX timestamp.

207

208

Parameters:

209

- value: datetime object

210

211

Returns:

212

float: timestamp in seconds since epoch

213

"""

214

215

def timestamp_ms(value):

216

"""

217

Convert a datetime object to a millisecond timestamp.

218

219

Parameters:

220

- value: datetime object

221

222

Returns:

223

int: timestamp in milliseconds since epoch

224

"""

225

226

def timedelta_to_microseconds(value):

227

"""

228

Convert a timedelta to total microseconds.

229

230

Parameters:

231

- value: timedelta object

232

233

Returns:

234

int: total microseconds

235

"""

236

```

237

238

### String Utilities

239

240

Functions for text processing and encoding.

241

242

```python { .api }

243

def ensure_text_type(val):

244

"""

245

Ensure a value is a text/string type.

246

247

Parameters:

248

- val: value to convert

249

250

Returns:

251

str: string representation of the value

252

"""

253

```

254

255

### Advanced Utilities

256

257

#### OrderedSet Class

258

259

```python { .api }

260

class OrderedSet:

261

"""

262

Set that maintains insertion order (similar to dict keys in Python 3.7+).

263

264

Provides standard set operations while preserving the order elements were added.

265

"""

266

267

def add(self, item):

268

"""Add an item to the set."""

269

270

def discard(self, item):

271

"""Remove an item from the set if present."""

272

273

def pop(self):

274

"""Remove and return the last item."""

275

276

def clear(self):

277

"""Remove all items from the set."""

278

279

def __contains__(self, item):

280

"""Check if item is in the set."""

281

282

def __iter__(self):

283

"""Iterate over items in insertion order."""

284

285

def __len__(self):

286

"""Return the number of items."""

287

```

288

289

290

## Usage Examples

291

292

### Error Handling

293

294

```python

295

from marshmallow import Schema, fields, ValidationError

296

297

class UserSchema(Schema):

298

username = fields.Str(required=True)

299

email = fields.Email(required=True)

300

age = fields.Int(validate=lambda x: x >= 18)

301

302

schema = UserSchema()

303

304

try:

305

result = schema.load({

306

'username': '',

307

'email': 'invalid-email',

308

'age': 15

309

})

310

except ValidationError as err:

311

print("Validation failed:")

312

print(f"Messages: {err.messages}")

313

print(f"Field errors: {err.messages_dict}")

314

print(f"Valid data: {err.valid_data}")

315

316

# Handle specific field errors

317

if 'email' in err.messages:

318

print("Email validation failed")

319

320

# Access nested error structure

321

for field, errors in err.messages.items():

322

print(f"{field}: {errors}")

323

```

324

325

### Data Manipulation Utilities

326

327

```python

328

from marshmallow.utils import get_value, set_value, pluck

329

330

# Working with nested data

331

user_data = {

332

'profile': {

333

'personal': {

334

'name': 'John Doe'

335

}

336

}

337

}

338

339

# Get nested values with dot notation

340

name = get_value(user_data, 'profile.personal.name') # 'John Doe'

341

missing_value = get_value(user_data, 'profile.work.title', 'N/A') # 'N/A'

342

343

# Set nested values

344

set_value(user_data, 'profile.personal.age', 30)

345

# user_data now has: {'profile': {'personal': {'name': 'John Doe', 'age': 30}}}

346

347

# Extract values from list of dictionaries

348

users = [

349

{'name': 'Alice', 'age': 25},

350

{'name': 'Bob', 'age': 30},

351

{'name': 'Charlie', 'age': 35}

352

]

353

names = pluck(users, 'name') # ['Alice', 'Bob', 'Charlie']

354

```

355

356

### Type Checking

357

358

```python

359

from marshmallow.utils import is_collection, is_sequence_but_not_string

360

361

# Type checking examples

362

print(is_collection([1, 2, 3])) # True

363

print(is_collection({'a': 1})) # True

364

print(is_collection('string')) # False

365

print(is_collection({1, 2, 3})) # True

366

367

print(is_sequence_but_not_string([1, 2, 3])) # True

368

print(is_sequence_but_not_string('string')) # False

369

print(is_sequence_but_not_string((1, 2, 3))) # True

370

print(is_sequence_but_not_string({1, 2, 3})) # False (set is not sequence)

371

```

372

373

### DateTime Utilities

374

375

```python

376

from datetime import datetime, timezone

377

from marshmallow.utils import timestamp, from_timestamp, is_aware

378

379

# Convert datetime to timestamp

380

dt = datetime(2023, 1, 1, 12, 0, 0, tzinfo=timezone.utc)

381

ts = timestamp(dt) # Unix timestamp

382

383

# Convert timestamp back to datetime

384

dt_from_ts = from_timestamp(ts)

385

386

# Check timezone awareness

387

naive_dt = datetime(2023, 1, 1, 12, 0, 0)

388

aware_dt = datetime(2023, 1, 1, 12, 0, 0, tzinfo=timezone.utc)

389

390

print(is_aware(naive_dt)) # False

391

print(is_aware(aware_dt)) # True

392

```

393

394

### Custom Exception Handling

395

396

```python

397

from marshmallow import Schema, fields, ValidationError, validates_schema

398

399

class CustomValidationSchema(Schema):

400

data = fields.Dict()

401

402

@validates_schema

403

def custom_validation(self, data, **kwargs):

404

"""Custom validation with detailed error reporting."""

405

errors = {}

406

407

# Complex validation logic

408

if 'required_field' not in data.get('data', {}):

409

errors['data'] = ['Missing required_field in data object']

410

411

# Multiple error conditions

412

value = data.get('data', {}).get('value')

413

if value is not None:

414

if not isinstance(value, (int, float)):

415

errors.setdefault('data', []).append('Value must be numeric')

416

elif value < 0:

417

errors.setdefault('data', []).append('Value must be positive')

418

419

if errors:

420

raise ValidationError(errors)

421

422

# Usage

423

schema = CustomValidationSchema()

424

try:

425

result = schema.load({'data': {'value': -5}})

426

except ValidationError as err:

427

# Handle multiple validation errors

428

for field, field_errors in err.messages.items():

429

for error in field_errors:

430

print(f"Error in {field}: {error}")

431

```

432

433

### OrderedSet Usage

434

435

```python

436

from marshmallow.orderedset import OrderedSet

437

438

# Create ordered set

439

tags = OrderedSet()

440

tags.add('python')

441

tags.add('marshmallow')

442

tags.add('validation')

443

tags.add('python') # Duplicate ignored

444

445

# Maintains insertion order

446

print(list(tags)) # ['python', 'marshmallow', 'validation']

447

448

# Standard set operations

449

tags.discard('python')

450

print('python' in tags) # False

451

print(len(tags)) # 2

452

```