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

inspection-types.mddocs/

0

# Inspection Types

1

2

Object introspection and type validation classes for checking instances, attributes, names, and string representations. These types enable validation of object properties and metadata beyond simple value comparison.

3

4

## Capabilities

5

6

### IsInstance

7

8

Type instance checking with support for generic type syntax and optional direct instance validation. Provides flexible type validation including inheritance checking and strict instance validation.

9

10

```python { .api }

11

class IsInstance(DirtyEquals):

12

"""

13

Type instance checking with generic support.

14

15

Validates that a value is an instance of the specified type,

16

with options for inheritance checking or direct instance validation.

17

"""

18

19

def __init__(self, expected_type: type, *, only_direct_instance: bool = False):

20

"""

21

Initialize instance type checker.

22

23

Args:

24

expected_type: The type to check against

25

only_direct_instance: If True, require exact type match (no inheritance)

26

"""

27

28

@classmethod

29

def __class_getitem__(cls, expected_type: type) -> 'IsInstance':

30

"""

31

Support generic syntax: IsInstance[Type] equivalent to IsInstance(Type).

32

33

Args:

34

expected_type: The type to check against

35

36

Returns:

37

IsInstance: New instance configured for the specified type

38

"""

39

40

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

41

"""

42

Check if value is an instance of the expected type.

43

44

Args:

45

other: Value to type-check

46

47

Returns:

48

bool: True if isinstance(other, expected_type) or direct match

49

"""

50

```

51

52

#### Usage Examples

53

54

```python

55

from dirty_equals import IsInstance

56

57

# Basic type checking

58

assert 42 == IsInstance(int)

59

assert "hello" == IsInstance(str)

60

assert [1, 2, 3] == IsInstance(list)

61

assert {"key": "value"} == IsInstance(dict)

62

63

# Generic syntax (equivalent to above)

64

assert 42 == IsInstance[int]

65

assert "hello" == IsInstance[str]

66

assert [1, 2, 3] == IsInstance[list]

67

68

# Inheritance checking (default behavior)

69

class Animal:

70

pass

71

72

class Dog(Animal):

73

pass

74

75

dog = Dog()

76

assert dog == IsInstance(Animal) # True - Dog inherits from Animal

77

assert dog == IsInstance(Dog) # True - Dog is direct instance

78

79

# Direct instance only (no inheritance)

80

assert dog == IsInstance(Dog, only_direct_instance=True) # True

81

# assert dog == IsInstance(Animal, only_direct_instance=True) # False

82

83

# Multiple type options with unions

84

from typing import Union

85

import numbers

86

87

assert 42 == IsInstance((int, float)) # Built-in union

88

assert 3.14 == IsInstance((int, float))

89

assert 42 == IsInstance(numbers.Number) # Abstract base class

90

91

# Complex data validation

92

api_response = {

93

'user_id': 123,

94

'data': [1, 2, 3],

95

'metadata': {'created': 'today'},

96

'success': True

97

}

98

99

assert api_response == {

100

'user_id': IsInstance[int],

101

'data': IsInstance[list],

102

'metadata': IsInstance[dict],

103

'success': IsInstance[bool]

104

}

105

106

# Custom class validation

107

from datetime import datetime

108

109

class User:

110

def __init__(self, name, created_at):

111

self.name = name

112

self.created_at = created_at

113

114

user = User("John", datetime.now())

115

user_data = {

116

'user_object': user,

117

'created_timestamp': datetime.now()

118

}

119

120

assert user_data == {

121

'user_object': IsInstance[User],

122

'created_timestamp': IsInstance[datetime]

123

}

124

125

# With boolean logic

126

from dirty_equals import IsPositive

127

128

# Must be both an integer and positive

129

assert 42 == (IsInstance[int] & IsPositive)

130

131

# Can be either string or integer

132

assert "test" == (IsInstance[str] | IsInstance[int])

133

assert 123 == (IsInstance[str] | IsInstance[int])

134

```

135

136

### HasName

137

138

Checks an object's `__name__` attribute against an expected value. Useful for validating functions, classes, or other named objects, with optional support for instances.

139

140

```python { .api }

141

class HasName(DirtyEquals):

142

"""

143

Checks object's __name__ attribute.

144

145

Validates that an object has a __name__ attribute matching

146

the expected value, with configurable instance support.

147

"""

148

149

def __init__(self, expected_name: str, *, allow_instances: bool = True):

150

"""

151

Initialize name checker.

152

153

Args:

154

expected_name: Expected value of __name__ attribute

155

allow_instances: If True, check instances' class names too

156

"""

157

158

@classmethod

159

def __class_getitem__(cls, expected_name: str) -> 'HasName':

160

"""

161

Support generic syntax: HasName['name'] equivalent to HasName('name').

162

163

Args:

164

expected_name: Expected name value

165

166

Returns:

167

HasName: New instance configured for the specified name

168

"""

169

170

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

171

"""

172

Check if object's __name__ matches expected value.

173

174

Args:

175

other: Object to check (should have __name__ attribute)

176

177

Returns:

178

bool: True if __name__ matches expected value

179

"""

180

```

181

182

#### Usage Examples

183

184

```python

185

from dirty_equals import HasName

186

187

# Function name checking

188

def my_function():

189

pass

190

191

assert my_function == HasName('my_function')

192

assert my_function == HasName['my_function'] # Generic syntax

193

194

# Class name checking

195

class MyClass:

196

pass

197

198

assert MyClass == HasName('MyClass')

199

assert MyClass == HasName['MyClass']

200

201

# Instance name checking (class name)

202

obj = MyClass()

203

assert obj == HasName('MyClass') # Checks obj.__class__.__name__

204

205

# Disable instance checking

206

assert obj == HasName('MyClass', allow_instances=True) # True

207

# assert obj == HasName('MyClass', allow_instances=False) # False (no __name__ on instance)

208

209

# Built-in type/function validation

210

assert int == HasName('int')

211

assert len == HasName('len')

212

assert list == HasName('list')

213

214

# Module validation

215

import json

216

import datetime

217

218

assert json == HasName('json')

219

assert datetime == HasName('datetime')

220

221

# API endpoint validation

222

def get_users():

223

pass

224

225

def create_user():

226

pass

227

228

def update_user():

229

pass

230

231

endpoints = [get_users, create_user, update_user]

232

expected_names = ['get_users', 'create_user', 'update_user']

233

234

for endpoint, expected in zip(endpoints, expected_names):

235

assert endpoint == HasName(expected)

236

237

# Class method validation

238

class APIHandler:

239

def handle_request(self):

240

pass

241

242

def validate_input(self):

243

pass

244

245

handler = APIHandler()

246

method = getattr(handler, 'handle_request')

247

assert method == HasName('handle_request')

248

249

# Dynamic validation

250

function_registry = {

251

'handler1': get_users,

252

'handler2': create_user

253

}

254

255

# Validate function names match registry expectations

256

for key, func in function_registry.items():

257

if key == 'handler1':

258

assert func == HasName('get_users')

259

elif key == 'handler2':

260

assert func == HasName('create_user')

261

```

262

263

### HasRepr

264

265

Checks an object's string representation (via `repr()`) against an expected value. Useful for validating object representations, especially for debugging or testing object state.

266

267

```python { .api }

268

class HasRepr(DirtyEquals):

269

"""

270

Checks object's repr() output.

271

272

Validates that an object's string representation matches

273

the expected value exactly.

274

"""

275

276

def __init__(self, expected_repr: str):

277

"""

278

Initialize repr checker.

279

280

Args:

281

expected_repr: Expected result of repr(object)

282

"""

283

284

@classmethod

285

def __class_getitem__(cls, expected_repr: str) -> 'HasRepr':

286

"""

287

Support generic syntax: HasRepr['repr'] equivalent to HasRepr('repr').

288

289

Args:

290

expected_repr: Expected repr string

291

292

Returns:

293

HasRepr: New instance configured for the specified repr

294

"""

295

296

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

297

"""

298

Check if object's repr() matches expected value.

299

300

Args:

301

other: Object to check repr() of

302

303

Returns:

304

bool: True if repr(other) equals expected_repr

305

"""

306

```

307

308

#### Usage Examples

309

310

```python

311

from dirty_equals import HasRepr

312

313

# Basic repr checking

314

numbers = [1, 2, 3]

315

assert numbers == HasRepr('[1, 2, 3]')

316

assert numbers == HasRepr['[1, 2, 3]'] # Generic syntax

317

318

# String repr checking

319

text = "hello"

320

assert text == HasRepr("'hello'") # Note the quotes in repr

321

322

# Dict repr checking

323

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

324

assert data == HasRepr("{'a': 1, 'b': 2}")

325

326

# Custom class with __repr__

327

class Point:

328

def __init__(self, x, y):

329

self.x = x

330

self.y = y

331

332

def __repr__(self):

333

return f"Point({self.x}, {self.y})"

334

335

point = Point(3, 4)

336

assert point == HasRepr('Point(3, 4)')

337

338

# Complex object validation

339

from datetime import datetime

340

from collections import namedtuple

341

342

# Named tuple representation

343

Person = namedtuple('Person', ['name', 'age'])

344

person = Person('Alice', 25)

345

assert person == HasRepr("Person(name='Alice', age=25)")

346

347

# Set representation (order may vary, so use with caution)

348

small_set = {1, 2}

349

# Note: set repr order is not guaranteed, so this might be fragile

350

# assert small_set == HasRepr('{1, 2}') or assert small_set == HasRepr('{2, 1}')

351

352

# Regex pattern repr

353

import re

354

pattern = re.compile(r'\d+')

355

expected_repr = "re.compile('\\\\d+')" # Escaped backslashes in repr

356

assert pattern == HasRepr[expected_repr]

357

358

# Exception representation

359

try:

360

raise ValueError("test error")

361

except ValueError as e:

362

assert e == HasRepr("ValueError('test error')")

363

364

# Debugging object state

365

class StatefulObject:

366

def __init__(self, value):

367

self.value = value

368

self.modified = False

369

370

def __repr__(self):

371

return f"StatefulObject(value={self.value}, modified={self.modified})"

372

373

obj = StatefulObject(42)

374

assert obj == HasRepr('StatefulObject(value=42, modified=False)')

375

376

obj.modified = True

377

assert obj == HasRepr('StatefulObject(value=42, modified=True)')

378

379

# Testing object snapshots in different states

380

class Counter:

381

def __init__(self):

382

self.count = 0

383

384

def increment(self):

385

self.count += 1

386

387

def __repr__(self):

388

return f"Counter(count={self.count})"

389

390

counter = Counter()

391

assert counter == HasRepr('Counter(count=0)')

392

393

counter.increment()

394

assert counter == HasRepr('Counter(count=1)')

395

396

counter.increment()

397

assert counter == HasRepr('Counter(count=2)')

398

```

399

400

### HasAttributes

401

402

Checks that an object has specified attributes with optional value validation. Supports both attribute presence checking and attribute value validation.

403

404

```python { .api }

405

class HasAttributes(DirtyEquals):

406

"""

407

Checks object has specified attributes.

408

409

Validates that an object contains the specified attributes,

410

optionally checking their values as well.

411

"""

412

413

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

414

"""

415

Initialize attribute checker (overloaded constructor).

416

417

Can be called in multiple ways:

418

- HasAttributes('attr1', 'attr2') - check presence only

419

- HasAttributes(attr1=value1, attr2=value2) - check presence and values

420

- HasAttributes({'attr1': value1}, attr2='value2') - mixed approach

421

422

Args:

423

*expected_args: Attribute names or dict of attribute-value pairs

424

**expected_kwargs: Attribute names and expected values

425

"""

426

427

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

428

"""

429

Check if object has the specified attributes.

430

431

Args:

432

other: Object to check for attributes

433

434

Returns:

435

bool: True if all specified attributes exist (and match values if given)

436

"""

437

```

438

439

#### Usage Examples

440

441

```python

442

from dirty_equals import HasAttributes, IsPositive, IsStr

443

444

# Basic attribute presence checking

445

class User:

446

def __init__(self, name, email, age):

447

self.name = name

448

self.email = email

449

self.age = age

450

451

user = User("John", "john@example.com", 25)

452

453

# Check that attributes exist

454

assert user == HasAttributes('name', 'email', 'age')

455

456

# Check attributes with specific values

457

assert user == HasAttributes(name="John", email="john@example.com", age=25)

458

459

# Check attributes with validation

460

assert user == HasAttributes(

461

name=IsStr,

462

email=IsStr,

463

age=IsPositive

464

)

465

466

# Mixed approach - some presence, some values

467

assert user == HasAttributes('name', email="john@example.com", age=IsPositive)

468

469

# Complex object validation

470

import datetime

471

472

class Article:

473

def __init__(self, title, author, created_at):

474

self.title = title

475

self.author = author

476

self.created_at = created_at

477

self.view_count = 0

478

self.published = False

479

480

article = Article("Python Guide", "Jane Doe", datetime.datetime.now())

481

482

# Validate essential attributes exist

483

assert article == HasAttributes('title', 'author', 'created_at', 'view_count')

484

485

# Validate attributes with conditions

486

from dirty_equals import IsNow, IsFalseLike

487

488

assert article == HasAttributes(

489

title=IsStr,

490

author=IsStr,

491

created_at=IsNow(delta=60), # Created within last minute

492

view_count=0,

493

published=IsFalseLike

494

)

495

496

# Dictionary-style attribute checking

497

expected_attrs = {

498

'title': 'Python Guide',

499

'author': IsStr,

500

'view_count': IsPositive | 0 # Can be positive or zero

501

}

502

assert article == HasAttributes(expected_attrs)

503

504

# API response object validation

505

class APIResponse:

506

def __init__(self, status_code, data, headers):

507

self.status_code = status_code

508

self.data = data

509

self.headers = headers

510

self.response_time = 0.123

511

512

response = APIResponse(200, {"users": [1, 2, 3]}, {"Content-Type": "application/json"})

513

514

# Validate response structure

515

assert response == HasAttributes(

516

status_code=200,

517

data=dict, # Just check it's a dict

518

headers=dict,

519

response_time=IsPositive

520

)

521

522

# Database model validation

523

class DatabaseRecord:

524

def __init__(self, id, created_at, updated_at):

525

self.id = id

526

self.created_at = created_at

527

self.updated_at = updated_at

528

self.version = 1

529

530

record = DatabaseRecord(123, datetime.datetime.now(), datetime.datetime.now())

531

532

# Validate standard database fields

533

assert record == HasAttributes(

534

'id', 'created_at', 'updated_at', 'version'

535

)

536

537

# Validate with type and value constraints

538

assert record == HasAttributes(

539

id=IsPositive,

540

created_at=IsNow(delta=300), # Within 5 minutes

541

updated_at=IsNow(delta=300),

542

version=1

543

)

544

545

# Configuration object validation

546

class Config:

547

def __init__(self):

548

self.database_url = "postgresql://localhost/mydb"

549

self.debug = True

550

self.secret_key = "super-secret"

551

self.port = 8000

552

553

config = Config()

554

555

# Validate configuration completeness

556

assert config == HasAttributes(

557

'database_url', 'debug', 'secret_key', 'port'

558

)

559

560

# Validate configuration values

561

assert config == HasAttributes(

562

database_url=IsStr,

563

debug=bool,

564

secret_key=IsStr,

565

port=IsPositive

566

)

567

```

568

569

## Type Definitions

570

571

```python { .api }

572

from typing import Any, Union

573

574

# All inspection types inherit from DirtyEquals

575

# They work with any Python objects that have the inspected properties

576

```