or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-validation.mderror-handling.mdformat-validation.mdindex.mdtype-checking.mdvalidator-creation.mdvalidators.md

type-checking.mddocs/

0

# Type Checking

1

2

Customizable type checking system for JSON Schema types with built-in type checkers for each draft version and extensibility for custom type definitions. The type system maps JSON Schema types to Python types and validation logic.

3

4

## Capabilities

5

6

### TypeChecker

7

8

The main class for JSON Schema type validation, supporting both built-in and custom type definitions.

9

10

```python { .api }

11

class TypeChecker:

12

"""

13

A type property checker for JSON Schema type keyword validation.

14

15

Converts between JSON Schema types and Python types/objects.

16

Supports customization and extension of type checking behavior.

17

"""

18

19

def __init__(self, type_checkers=()):

20

"""

21

Initialize type checker.

22

23

Parameters:

24

- type_checkers: Mapping of type names to checker functions

25

"""

26

27

def is_type(self, instance, type):

28

"""

29

Check if instance is of the specified JSON Schema type.

30

31

Parameters:

32

- instance: Value to check

33

- type: JSON Schema type name

34

35

Returns:

36

- bool: True if instance is of the specified type

37

38

Raises:

39

- UndefinedTypeCheck: If type is not defined

40

"""

41

42

def redefine(self, type, fn):

43

"""

44

Create new TypeChecker with redefined type.

45

46

Parameters:

47

- type: Type name to redefine

48

- fn: Type checking function

49

50

Returns:

51

- TypeChecker: New TypeChecker instance

52

"""

53

54

def redefine_many(self, definitions=()):

55

"""

56

Create new TypeChecker with multiple redefined types.

57

58

Parameters:

59

- definitions: Dictionary mapping type names to checker functions

60

61

Returns:

62

- TypeChecker: New TypeChecker instance

63

"""

64

65

def remove(self, *types):

66

"""

67

Create new TypeChecker without specified types.

68

69

Parameters:

70

- types: Type names to remove

71

72

Returns:

73

- TypeChecker: New TypeChecker instance

74

75

Raises:

76

- UndefinedTypeCheck: If any type is not defined

77

"""

78

```

79

80

### Built-in Type Checkers

81

82

Pre-configured type checkers for each JSON Schema draft version.

83

84

```python { .api }

85

# Type checkers for each draft

86

draft202012_type_checker: TypeChecker

87

draft201909_type_checker: TypeChecker

88

draft7_type_checker: TypeChecker

89

draft6_type_checker: TypeChecker

90

draft4_type_checker: TypeChecker

91

draft3_type_checker: TypeChecker

92

```

93

94

### Built-in Type Checking Functions

95

96

Individual type checking functions for standard JSON Schema types.

97

98

```python { .api }

99

def is_array(checker, instance):

100

"""

101

Check if instance is an array (Python list).

102

103

Parameters:

104

- checker: TypeChecker instance

105

- instance: Value to check

106

107

Returns:

108

- bool: True if instance is a list

109

"""

110

111

def is_bool(checker, instance):

112

"""

113

Check if instance is a boolean.

114

115

Parameters:

116

- checker: TypeChecker instance

117

- instance: Value to check

118

119

Returns:

120

- bool: True if instance is a boolean

121

"""

122

123

def is_integer(checker, instance):

124

"""

125

Check if instance is an integer.

126

127

Parameters:

128

- checker: TypeChecker instance

129

- instance: Value to check

130

131

Returns:

132

- bool: True if instance is an integer (excludes booleans)

133

"""

134

135

def is_null(checker, instance):

136

"""

137

Check if instance is null (Python None).

138

139

Parameters:

140

- checker: TypeChecker instance

141

- instance: Value to check

142

143

Returns:

144

- bool: True if instance is None

145

"""

146

147

def is_number(checker, instance):

148

"""

149

Check if instance is a number.

150

151

Parameters:

152

- checker: TypeChecker instance

153

- instance: Value to check

154

155

Returns:

156

- bool: True if instance is numeric (excludes booleans)

157

"""

158

159

def is_object(checker, instance):

160

"""

161

Check if instance is an object (Python dict).

162

163

Parameters:

164

- checker: TypeChecker instance

165

- instance: Value to check

166

167

Returns:

168

- bool: True if instance is a dictionary

169

"""

170

171

def is_string(checker, instance):

172

"""

173

Check if instance is a string.

174

175

Parameters:

176

- checker: TypeChecker instance

177

- instance: Value to check

178

179

Returns:

180

- bool: True if instance is a string

181

"""

182

183

def is_any(checker, instance):

184

"""

185

Check if instance is any type (always returns True).

186

187

Used for Draft 3 "any" type.

188

189

Parameters:

190

- checker: TypeChecker instance

191

- instance: Value to check

192

193

Returns:

194

- bool: Always True

195

"""

196

```

197

198

## Usage Examples

199

200

### Basic Type Checking

201

202

```python

203

from jsonschema import Draft202012Validator

204

from jsonschema._types import draft202012_type_checker

205

206

# Direct type checking

207

checker = draft202012_type_checker

208

209

print(checker.is_type("hello", "string")) # True

210

print(checker.is_type(123, "integer")) # True

211

print(checker.is_type(123.5, "number")) # True

212

print(checker.is_type([1, 2, 3], "array")) # True

213

print(checker.is_type({"a": 1}, "object")) # True

214

print(checker.is_type(None, "null")) # True

215

print(checker.is_type(True, "boolean")) # True

216

217

# Type checking in validation

218

schema = {"type": "integer"}

219

validator = Draft202012Validator(schema)

220

221

validator.validate(42) # Valid

222

validator.validate(42.0) # Valid (Draft 6+ allows integers as floats)

223

validator.validate("42") # Invalid - string, not integer

224

```

225

226

### Custom Type Definitions

227

228

```python

229

from jsonschema import Draft202012Validator, create

230

from jsonschema._types import TypeChecker, draft202012_type_checker

231

import decimal

232

233

# Define custom type checker function

234

def is_decimal(checker, instance):

235

"""Check if instance is a decimal number."""

236

return isinstance(instance, decimal.Decimal)

237

238

def is_positive_number(checker, instance):

239

"""Check if instance is a positive number."""

240

return (isinstance(instance, (int, float)) and

241

not isinstance(instance, bool) and

242

instance > 0)

243

244

# Create custom type checker

245

custom_type_checker = draft202012_type_checker.redefine_many({

246

"decimal": is_decimal,

247

"positive-number": is_positive_number

248

})

249

250

# Create validator with custom types

251

validator_class = create(

252

meta_schema=Draft202012Validator.META_SCHEMA,

253

validators=Draft202012Validator.VALIDATORS,

254

type_checker=custom_type_checker

255

)

256

257

# Use custom types in schema

258

schema = {

259

"type": "object",

260

"properties": {

261

"price": {"type": "decimal"},

262

"quantity": {"type": "positive-number"}

263

}

264

}

265

266

validator = validator_class(schema)

267

268

# Test custom types

269

import decimal

270

test_data = {

271

"price": decimal.Decimal("19.99"),

272

"quantity": 5

273

}

274

275

validator.validate(test_data) # Should pass

276

277

# Invalid data

278

invalid_data = {

279

"price": 19.99, # float, not Decimal

280

"quantity": -1 # not positive

281

}

282

283

errors = list(validator.iter_errors(invalid_data))

284

for error in errors:

285

print(f"Type error: {error.message}")

286

```

287

288

### Extending Existing Type Checkers

289

290

```python

291

from jsonschema._types import draft202012_type_checker

292

from collections import namedtuple

293

294

# Define custom object type that includes namedtuples

295

def is_object_or_namedtuple(checker, instance):

296

"""Check if instance is dict or namedtuple."""

297

return (isinstance(instance, dict) or

298

(hasattr(instance, '_fields') and

299

hasattr(instance, '_asdict')))

300

301

# Extend type checker

302

extended_checker = draft202012_type_checker.redefine(

303

"object", is_object_or_namedtuple

304

)

305

306

# Test with namedtuple

307

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

308

person = Person('Alice', 30)

309

310

print(extended_checker.is_type(person, "object")) # True

311

print(draft202012_type_checker.is_type(person, "object")) # False

312

```

313

314

### Removing Type Support

315

316

```python

317

from jsonschema._types import draft202012_type_checker

318

319

# Create type checker without null support

320

no_null_checker = draft202012_type_checker.remove("null")

321

322

try:

323

no_null_checker.is_type(None, "null")

324

except UndefinedTypeCheck as e:

325

print(f"Type undefined: {e}")

326

327

# Available types

328

print("Available types:", list(no_null_checker._type_checkers.keys()))

329

```

330

331

### Draft-Specific Type Differences

332

333

```python

334

from jsonschema._types import (

335

draft3_type_checker,

336

draft4_type_checker,

337

draft6_type_checker

338

)

339

340

# Draft 3 supports "any" type

341

print("Draft 3 types:", list(draft3_type_checker._type_checkers.keys()))

342

# Includes: 'any', 'array', 'boolean', 'integer', 'null', 'number', 'object', 'string'

343

344

# Draft 4+ removes "any" type

345

print("Draft 4 types:", list(draft4_type_checker._type_checkers.keys()))

346

# Excludes 'any'

347

348

# Draft 6+ changes integer handling

349

print(draft4_type_checker.is_type(42.0, "integer")) # False

350

print(draft6_type_checker.is_type(42.0, "integer")) # True (if 42.0.is_integer())

351

```

352

353

### Type Checking in Custom Validators

354

355

```python

356

from jsonschema import Draft202012Validator

357

from jsonschema._types import TypeChecker

358

359

# Create validator with custom type checking

360

def is_non_empty_string(checker, instance):

361

"""Check if instance is a non-empty string."""

362

return isinstance(instance, str) and len(instance) > 0

363

364

custom_checker = TypeChecker().redefine_many({

365

"string": is_string,

366

"non-empty-string": is_non_empty_string,

367

"array": is_array,

368

"object": is_object,

369

"number": is_number,

370

"integer": is_integer,

371

"boolean": is_bool,

372

"null": is_null

373

})

374

375

# Import required items

376

from jsonschema._types import is_string, is_array, is_object, is_number, is_integer, is_bool, is_null

377

378

# Use in validator

379

validator = Draft202012Validator(

380

{"type": "non-empty-string"},

381

type_checker=custom_checker

382

)

383

384

validator.validate("hello") # Valid

385

try:

386

validator.validate("") # Invalid - empty string

387

except ValidationError as e:

388

print(f"Type error: {e.message}")

389

```

390

391

### Type Checking Function Signature

392

393

All type checking functions must follow this signature:

394

395

```python

396

def my_type_checker(checker, instance):

397

"""

398

Custom type checking function.

399

400

Parameters:

401

- checker: The TypeChecker instance calling this function

402

- instance: The value to type-check

403

404

Returns:

405

- bool: True if instance is of this type, False otherwise

406

"""

407

# Custom type checking logic here

408

return isinstance(instance, MyCustomType)

409

```