or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

base-types.mdboolean-types.mddatetime-types.mddict-types.mdindex.mdinspection-types.mdnumeric-types.mdother-types.mdsequence-types.mdstring-types.md

dict-types.mddocs/

0

# Dictionary Types

1

2

Dictionary comparison with flexible matching strategies including partial matching, strict ordering, and key filtering. These types enable sophisticated validation of dictionary structures with configurable constraints for different use cases.

3

4

## Capabilities

5

6

### IsDict

7

8

Configurable dictionary comparison that serves as the base for all dictionary validation. Supports multiple matching modes through the settings method and direct instantiation with expected key-value pairs.

9

10

```python { .api }

11

class IsDict(DirtyEquals):

12

"""

13

Flexible dictionary comparison with configurable matching behavior.

14

15

Supports exact matching, partial matching, key filtering, and order enforcement

16

through various configuration options.

17

"""

18

19

def __init__(self, *expected_args, **expected_kwargs):

20

"""

21

Initialize dictionary comparison (overloaded constructor).

22

23

Can be called in multiple ways:

24

- IsDict() - matches any dictionary

25

- IsDict(expected_dict) - matches specific dictionary

26

- IsDict(key1=value1, key2=value2) - matches with keyword arguments

27

- IsDict(expected_dict, key3=value3) - combines dict and kwargs

28

29

Args:

30

*expected_args: Expected dictionary as positional argument

31

**expected_kwargs: Expected key-value pairs as keyword arguments

32

"""

33

34

def settings(

35

self,

36

*,

37

strict: Optional[bool] = None,

38

partial: Optional[bool] = None,

39

ignore: Optional[Sequence[str]] = None

40

) -> 'IsDict':

41

"""

42

Configure dictionary matching behavior.

43

44

Args:

45

strict: If True, enforce key order and exact matching

46

partial: If True, allow subset matching (only check specified keys)

47

ignore: List of keys to ignore during comparison

48

49

Returns:

50

IsDict: New instance with updated settings

51

"""

52

53

@property

54

def expected_values(self) -> Dict[str, Any]:

55

"""Get expected key-value pairs."""

56

57

@property

58

def strict(self) -> bool:

59

"""Whether strict mode (order enforcement) is enabled."""

60

61

@property

62

def partial(self) -> bool:

63

"""Whether partial mode (subset matching) is enabled."""

64

65

@property

66

def ignore(self) -> Optional[Sequence[str]]:

67

"""Keys to ignore during comparison."""

68

69

def equals(self, other: Any) -> bool:

70

"""

71

Check if value matches dictionary constraints.

72

73

Args:

74

other: Value to validate (should be dict-like)

75

76

Returns:

77

bool: True if value satisfies all conditions

78

"""

79

```

80

81

#### Usage Examples

82

83

```python

84

from dirty_equals import IsDict, IsPositive, IsStr

85

86

# Basic dictionary matching

87

test_dict = {'a': 1, 'b': 2}

88

assert test_dict == IsDict({'a': 1, 'b': 2})

89

assert test_dict == IsDict(a=1, b=2)

90

91

# Match any dictionary

92

assert test_dict == IsDict()

93

assert {'x': 'y'} == IsDict()

94

95

# Combine positional and keyword arguments

96

base_dict = {'a': 1}

97

assert {'a': 1, 'b': 2} == IsDict(base_dict, b=2)

98

99

# With value validators

100

user_data = {

101

'id': 123,

102

'name': 'John',

103

'email': 'john@example.com',

104

'active': True

105

}

106

107

assert user_data == IsDict({

108

'id': IsPositive,

109

'name': IsStr(min_length=1),

110

'email': IsStr(regex=r'.+@.+\..+'),

111

'active': True

112

})

113

114

# Using settings for flexible matching

115

config = {'debug': True, 'port': 8080, 'host': 'localhost'}

116

117

# Partial matching - only check specified keys

118

assert config == IsDict({'debug': True}).settings(partial=True)

119

assert config == IsDict(debug=True).settings(partial=True)

120

121

# Ignore specific keys

122

assert config == IsDict({

123

'debug': True,

124

'port': 8080

125

}).settings(ignore=['host'])

126

127

# Strict mode - enforce order (for ordered dicts)

128

from collections import OrderedDict

129

ordered = OrderedDict([('a', 1), ('b', 2)])

130

assert ordered == IsDict(OrderedDict([('a', 1), ('b', 2)])).settings(strict=True)

131

132

# Chaining configurations

133

partial_ignored = IsDict(debug=True).settings(partial=True, ignore=['timestamp'])

134

test_config = {'debug': True, 'env': 'test', 'timestamp': '2023-01-01'}

135

assert test_config == partial_ignored

136

```

137

138

### IsPartialDict

139

140

Specialized dictionary comparison that only validates specified keys, ignoring any additional keys in the actual dictionary. Equivalent to `IsDict(...).settings(partial=True)`.

141

142

```python { .api }

143

class IsPartialDict(IsDict):

144

"""

145

Partial dictionary matching - validates only specified keys.

146

147

Checks that the target dictionary contains at least the specified keys

148

with matching values, but allows additional keys to be present.

149

"""

150

151

def __init__(self, *expected_args, **expected_kwargs):

152

"""

153

Initialize partial dictionary comparison.

154

155

Args:

156

*expected_args: Expected dictionary as positional argument

157

**expected_kwargs: Expected key-value pairs as keyword arguments

158

"""

159

```

160

161

#### Usage Examples

162

163

```python

164

from dirty_equals import IsPartialDict, IsPositive

165

166

# Basic partial matching

167

full_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

168

assert full_dict == IsPartialDict({'a': 1, 'b': 2})

169

assert full_dict == IsPartialDict(a=1, b=2)

170

171

# API response validation - ignore extra fields

172

api_response = {

173

'user_id': 123,

174

'username': 'john_doe',

175

'email': 'john@example.com',

176

'created_at': '2023-01-01T00:00:00Z',

177

'last_login': '2023-01-15T12:30:00Z',

178

'profile_picture': 'https://example.com/pic.jpg',

179

'preferences': {'theme': 'dark', 'language': 'en'}

180

}

181

182

# Only validate essential fields

183

assert api_response == IsPartialDict({

184

'user_id': IsPositive,

185

'username': 'john_doe',

186

'email': IsStr

187

})

188

189

# Database record validation - focus on updated fields

190

updated_record = {

191

'id': 456,

192

'name': 'Updated Name',

193

'email': 'updated@example.com',

194

'updated_at': '2023-01-15T12:00:00Z',

195

'version': 2,

196

# ... many other fields we don't care about for this test

197

}

198

199

assert updated_record == IsPartialDict({

200

'name': 'Updated Name',

201

'email': 'updated@example.com'

202

})

203

204

# Nested partial matching

205

complex_data = {

206

'user': {

207

'id': 123,

208

'profile': {'name': 'John', 'age': 30, 'city': 'NYC'},

209

'settings': {'notifications': True}

210

},

211

'metadata': {'version': 1, 'source': 'api'}

212

}

213

214

assert complex_data == IsPartialDict({

215

'user': IsPartialDict({

216

'id': 123,

217

'profile': IsPartialDict({'name': 'John'})

218

})

219

})

220

```

221

222

### IsIgnoreDict

223

224

Dictionary comparison that ignores keys with `None` values during matching. Useful when dealing with APIs or databases that include null fields that should be excluded from validation.

225

226

```python { .api }

227

class IsIgnoreDict(IsDict):

228

"""

229

Dictionary comparison ignoring None values.

230

231

Performs dictionary matching but excludes any key-value pairs

232

where the value is None from the comparison.

233

"""

234

235

def __init__(self, *expected_args, **expected_kwargs):

236

"""

237

Initialize dictionary comparison that ignores None values.

238

239

Args:

240

*expected_args: Expected dictionary as positional argument

241

**expected_kwargs: Expected key-value pairs as keyword arguments

242

"""

243

```

244

245

#### Usage Examples

246

247

```python

248

from dirty_equals import IsIgnoreDict, IsStr

249

250

# Basic None value ignoring

251

test_dict = {'a': 1, 'b': None, 'c': 'hello'}

252

expected = {'a': 1, 'c': 'hello'}

253

assert test_dict == IsIgnoreDict(expected)

254

255

# API response with null fields

256

api_data = {

257

'user_id': 123,

258

'username': 'john_doe',

259

'first_name': 'John',

260

'last_name': None, # Not provided

261

'middle_name': None, # Not provided

262

'email': 'john@example.com',

263

'phone': None # Not provided

264

}

265

266

# Validate ignoring null fields

267

assert api_data == IsIgnoreDict({

268

'user_id': 123,

269

'username': 'john_doe',

270

'first_name': 'John',

271

'email': IsStr

272

})

273

274

# Database record with optional fields

275

db_record = {

276

'id': 456,

277

'title': 'Test Article',

278

'content': 'Article content...',

279

'author_id': 123,

280

'editor_id': None, # No editor assigned

281

'published_at': '2023-01-01T00:00:00Z',

282

'featured_image': None, # No image

283

'tags': ['tech', 'python']

284

}

285

286

assert db_record == IsIgnoreDict({

287

'id': 456,

288

'title': 'Test Article',

289

'content': IsStr,

290

'author_id': 123,

291

'published_at': IsStr,

292

'tags': ['tech', 'python']

293

})

294

295

# Form data processing

296

form_input = {

297

'name': 'John Doe',

298

'email': 'john@example.com',

299

'company': 'Acme Corp',

300

'phone': None, # Optional field not filled

301

'address': None, # Optional field not filled

302

'newsletter': True

303

}

304

305

# Validate required fields only

306

assert form_input == IsIgnoreDict({

307

'name': IsStr,

308

'email': IsStr,

309

'company': IsStr,

310

'newsletter': True

311

})

312

```

313

314

### IsStrictDict

315

316

Dictionary comparison with strict ordering enforcement. Validates both the key-value pairs and their order, useful for ordered dictionaries or when insertion order matters.

317

318

```python { .api }

319

class IsStrictDict(IsDict):

320

"""

321

Strict dictionary comparison with order enforcement.

322

323

Validates dictionary contents and enforces that keys appear

324

in the same order as specified in the expected dictionary.

325

"""

326

327

def __init__(self, *expected_args, **expected_kwargs):

328

"""

329

Initialize strict dictionary comparison.

330

331

Args:

332

*expected_args: Expected dictionary as positional argument

333

**expected_kwargs: Expected key-value pairs as keyword arguments

334

"""

335

```

336

337

#### Usage Examples

338

339

```python

340

from dirty_equals import IsStrictDict

341

from collections import OrderedDict

342

343

# Order-sensitive dictionary matching

344

ordered_dict = OrderedDict([('first', 1), ('second', 2), ('third', 3)])

345

assert ordered_dict == IsStrictDict(OrderedDict([('first', 1), ('second', 2), ('third', 3)]))

346

347

# Regular dict with insertion order (Python 3.7+)

348

test_dict = {'a': 1, 'b': 2, 'c': 3}

349

assert test_dict == IsStrictDict({'a': 1, 'b': 2, 'c': 3})

350

351

# This would fail due to different order:

352

# different_order = {'b': 2, 'a': 1, 'c': 3}

353

# assert different_order == IsStrictDict({'a': 1, 'b': 2, 'c': 3}) # False

354

355

# Configuration validation where order matters

356

config_sections = {

357

'database': {'host': 'localhost', 'port': 5432},

358

'cache': {'host': 'redis', 'port': 6379},

359

'logging': {'level': 'INFO', 'file': 'app.log'}

360

}

361

362

# Ensure sections appear in specific order

363

expected_order = {

364

'database': IsStrictDict({'host': 'localhost', 'port': 5432}),

365

'cache': IsStrictDict({'host': 'redis', 'port': 6379}),

366

'logging': IsStrictDict({'level': 'INFO', 'file': 'app.log'})

367

}

368

assert config_sections == IsStrictDict(expected_order)

369

370

# API response with ordered fields

371

api_response = OrderedDict([

372

('status', 'success'),

373

('data', {'id': 123, 'name': 'John'}),

374

('metadata', {'timestamp': '2023-01-01T00:00:00Z'})

375

])

376

377

assert api_response == IsStrictDict({

378

'status': 'success',

379

'data': {'id': 123, 'name': 'John'},

380

'metadata': {'timestamp': IsStr}

381

})

382

383

# JSON object with preserved field order

384

import json

385

json_string = '{"id": 123, "name": "John", "email": "john@example.com"}'

386

parsed = json.loads(json_string, object_pairs_hook=OrderedDict)

387

388

assert parsed == IsStrictDict(OrderedDict([

389

('id', 123),

390

('name', 'John'),

391

('email', IsStr)

392

]))

393

```

394

395

## Type Definitions

396

397

```python { .api }

398

from typing import Any, Dict, Optional, Sequence, Union

399

400

# All dictionary types inherit from IsDict which inherits from DirtyEquals

401

# They work with standard Python dict objects and dict-like objects

402

```