or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

class-integration.mdconfiguration.mdcore-serialization.mdcustomization.mdindex.mdkey-transformation.mdtype-system.md

type-system.mddocs/

0

# Type System

1

2

Comprehensive support for Python's type system including built-in types, collections, datetime objects, Enum types, Union types, and custom objects. The jsons library provides default serializers and deserializers for all common Python types with intelligent type inference.

3

4

## Capabilities

5

6

### Built-in Type Support

7

8

jsons automatically handles serialization and deserialization for these Python types:

9

10

#### Primitive Types

11

- **str** - String values (no conversion needed)

12

- **int** - Integer numbers

13

- **float** - Floating-point numbers

14

- **bool** - Boolean values (True/False)

15

- **None** - Null values

16

17

#### Numeric Types

18

- **complex** - Complex numbers (serialized as dict with 'real' and 'imag' keys)

19

- **Decimal** - High-precision decimal numbers (serialized as string)

20

21

#### Collection Types

22

- **list** - Lists and List[T] type hints

23

- **tuple** - Tuples and Tuple[T, ...] type hints

24

- **dict** - Dictionaries and Dict[K, V] type hints

25

- **set** - Sets (serialized as lists)

26

- **frozenset** - Frozen sets (serialized as lists)

27

- **DefaultDict** - Default dictionaries with default factory preservation

28

29

#### Date and Time Types

30

- **datetime** - Date and time objects (ISO format strings)

31

- **date** - Date objects (ISO date strings)

32

- **time** - Time objects (ISO time strings)

33

- **timezone** - Timezone objects

34

- **timedelta** - Time duration objects

35

- **ZoneInfo** - Timezone info objects (Python 3.9+)

36

37

#### Other Built-in Types

38

- **UUID** - Universally unique identifiers (serialized as strings)

39

- **Enum** - Enumeration values (serialized as enum values)

40

- **IntEnum** - Integer enumeration values

41

- **pathlib.Path** - Path objects (serialized as strings)

42

- **Mapping** - Abstract base class for mappings

43

- **Iterable** - Abstract base class for iterables

44

45

### Generic Type Support

46

47

```python { .api }

48

# Automatic handling of typing module generics:

49

# List[T], Tuple[T, ...], Dict[K, V], Set[T], FrozenSet[T]

50

# Union[T1, T2, ...], Optional[T], DefaultDict[K, V]

51

# Mapping[K, V], Iterable[T]

52

```

53

54

## Usage Examples

55

56

### Primitive and Numeric Types

57

58

```python

59

import jsons

60

from decimal import Decimal

61

62

# Primitive types work automatically

63

data = {

64

'name': 'John', # str

65

'age': 30, # int

66

'height': 5.9, # float

67

'is_active': True, # bool

68

'notes': None # NoneType

69

}

70

71

serialized = jsons.dump(data)

72

restored = jsons.load(serialized, dict)

73

print(restored == data) # True

74

75

# Complex numbers

76

complex_num = 3 + 4j

77

serialized = jsons.dump(complex_num)

78

print(serialized) # {'real': 3.0, 'imag': 4.0}

79

restored = jsons.load(serialized, complex)

80

print(restored) # (3+4j)

81

82

# Decimal precision

83

price = Decimal('19.99')

84

serialized = jsons.dump(price)

85

print(serialized) # '19.99'

86

restored = jsons.load(serialized, Decimal)

87

print(restored == price) # True

88

```

89

90

### Collection Types

91

92

```python

93

import jsons

94

from typing import List, Dict, Tuple, Set, Optional

95

from collections import defaultdict

96

97

# Lists with type hints

98

numbers: List[int] = [1, 2, 3, 4, 5]

99

serialized = jsons.dump(numbers)

100

restored = jsons.load(serialized, List[int])

101

print(restored) # [1, 2, 3, 4, 5]

102

103

# Dictionaries with type hints

104

scores: Dict[str, int] = {'Alice': 95, 'Bob': 87, 'Charlie': 92}

105

serialized = jsons.dump(scores)

106

restored = jsons.load(serialized, Dict[str, int])

107

print(restored) # {'Alice': 95, 'Bob': 87, 'Charlie': 92}

108

109

# Tuples with specific types

110

coordinates: Tuple[float, float, str] = (40.7128, -74.0060, 'NYC')

111

serialized = jsons.dump(coordinates)

112

restored = jsons.load(serialized, Tuple[float, float, str])

113

print(restored) # (40.7128, -74.006, 'NYC')

114

115

# Sets (serialized as lists)

116

unique_tags: Set[str] = {'python', 'json', 'serialization'}

117

serialized = jsons.dump(unique_tags)

118

print(serialized) # ['python', 'json', 'serialization'] (order may vary)

119

restored = jsons.load(serialized, Set[str])

120

print(type(restored)) # <class 'set'>

121

122

# DefaultDict with factory function preservation

123

def_dict = defaultdict(list)

124

def_dict['fruits'].extend(['apple', 'banana'])

125

def_dict['vegetables'].extend(['carrot', 'broccoli'])

126

127

serialized = jsons.dump(def_dict)

128

restored = jsons.load(serialized, defaultdict)

129

print(restored['new_key']) # [] (default factory still works)

130

```

131

132

### Date and Time Types

133

134

```python

135

import jsons

136

from datetime import datetime, date, time, timezone, timedelta

137

from zoneinfo import ZoneInfo # Python 3.9+

138

139

# Datetime objects

140

now = datetime.now()

141

serialized = jsons.dump(now)

142

print(serialized) # '2023-12-01T10:30:00.123456'

143

restored = jsons.load(serialized, datetime)

144

print(type(restored)) # <class 'datetime.datetime'>

145

146

# Date objects

147

today = date.today()

148

serialized = jsons.dump(today)

149

print(serialized) # '2023-12-01'

150

restored = jsons.load(serialized, date)

151

152

# Time objects

153

current_time = time(14, 30, 45)

154

serialized = jsons.dump(current_time)

155

print(serialized) # '14:30:45'

156

restored = jsons.load(serialized, time)

157

158

# Timezone-aware datetime

159

utc_time = datetime.now(timezone.utc)

160

serialized = jsons.dump(utc_time)

161

restored = jsons.load(serialized, datetime)

162

print(restored.tzinfo) # timezone.utc

163

164

# Timedelta objects

165

duration = timedelta(days=7, hours=3, minutes=30)

166

serialized = jsons.dump(duration)

167

restored = jsons.load(serialized, timedelta)

168

print(restored.days) # 7

169

170

# ZoneInfo (Python 3.9+)

171

ny_tz = ZoneInfo('America/New_York')

172

ny_time = datetime.now(ny_tz)

173

serialized = jsons.dump(ny_time)

174

restored = jsons.load(serialized, datetime)

175

```

176

177

### Enum and Special Types

178

179

```python

180

import jsons

181

from enum import Enum, IntEnum

182

from uuid import uuid4, UUID

183

from pathlib import Path

184

185

# Enum types

186

class Status(Enum):

187

PENDING = 'pending'

188

APPROVED = 'approved'

189

REJECTED = 'rejected'

190

191

class Priority(IntEnum):

192

LOW = 1

193

MEDIUM = 2

194

HIGH = 3

195

196

status = Status.APPROVED

197

priority = Priority.HIGH

198

199

status_serialized = jsons.dump(status)

200

priority_serialized = jsons.dump(priority)

201

202

print(status_serialized) # 'approved'

203

print(priority_serialized) # 2

204

205

status_restored = jsons.load(status_serialized, Status)

206

priority_restored = jsons.load(priority_serialized, Priority)

207

208

print(status_restored == Status.APPROVED) # True

209

print(priority_restored == Priority.HIGH) # True

210

211

# UUID objects

212

unique_id = uuid4()

213

serialized = jsons.dump(unique_id)

214

print(serialized) # '12345678-1234-5678-1234-567812345678'

215

restored = jsons.load(serialized, UUID)

216

print(type(restored)) # <class 'uuid.UUID'>

217

218

# Path objects

219

file_path = Path('/home/user/documents/file.txt')

220

serialized = jsons.dump(file_path)

221

print(serialized) # '/home/user/documents/file.txt'

222

restored = jsons.load(serialized, Path)

223

print(type(restored)) # <class 'pathlib.PosixPath'>

224

```

225

226

### Union and Optional Types

227

228

```python

229

import jsons

230

from typing import Union, Optional, List

231

from dataclasses import dataclass

232

233

@dataclass

234

class NumberContainer:

235

value: Union[int, float, str] # Can be int, float, or str

236

optional_notes: Optional[str] = None # Can be str or None

237

238

# Union types - jsons automatically detects the correct type

239

containers = [

240

NumberContainer(42), # int

241

NumberContainer(3.14), # float

242

NumberContainer("not_a_number"), # str

243

NumberContainer(100, "Important note") # with optional field

244

]

245

246

serialized_list = jsons.dump(containers)

247

print(serialized_list)

248

# [

249

# {'value': 42, 'optional_notes': None},

250

# {'value': 3.14, 'optional_notes': None},

251

# {'value': 'not_a_number', 'optional_notes': None},

252

# {'value': 100, 'optional_notes': 'Important note'}

253

# ]

254

255

restored_list = jsons.load(serialized_list, List[NumberContainer])

256

print(type(restored_list[0].value)) # <class 'int'>

257

print(type(restored_list[1].value)) # <class 'float'>

258

print(type(restored_list[2].value)) # <class 'str'>

259

260

# Optional types work seamlessly

261

@dataclass

262

class User:

263

username: str

264

email: Optional[str] = None

265

266

user1 = User("alice") # email is None

267

user2 = User("bob", "bob@example.com") # email provided

268

269

users = [user1, user2]

270

serialized = jsons.dump(users)

271

restored = jsons.load(serialized, List[User])

272

273

print(restored[0].email) # None

274

print(restored[1].email) # 'bob@example.com'

275

```

276

277

### Custom Object Support

278

279

```python

280

import jsons

281

from dataclasses import dataclass

282

from typing import List

283

284

@dataclass

285

class Address:

286

street: str

287

city: str

288

zip_code: str

289

290

@dataclass

291

class Person:

292

name: str

293

age: int

294

address: Address

295

phone_numbers: List[str]

296

297

# Nested custom objects work automatically with type hints

298

address = Address("123 Main St", "Anytown", "12345")

299

person = Person("John Doe", 30, address, ["+1-555-0100", "+1-555-0101"])

300

301

# Automatic serialization of nested objects

302

serialized = jsons.dump(person)

303

print(serialized)

304

# {

305

# 'name': 'John Doe',

306

# 'age': 30,

307

# 'address': {'street': '123 Main St', 'city': 'Anytown', 'zip_code': '12345'},

308

# 'phone_numbers': ['+1-555-0100', '+1-555-0101']

309

# }

310

311

# Automatic deserialization with proper type reconstruction

312

restored = jsons.load(serialized, Person)

313

print(type(restored.address)) # <class '__main__.Address'>

314

print(restored.address.city) # 'Anytown'

315

print(len(restored.phone_numbers)) # 2

316

```

317

318

### Generic Collections with Custom Objects

319

320

```python

321

import jsons

322

from dataclasses import dataclass

323

from typing import Dict, List, Optional

324

from datetime import datetime

325

326

@dataclass

327

class Task:

328

id: int

329

title: str

330

completed: bool

331

due_date: Optional[datetime] = None

332

333

@dataclass

334

class Project:

335

name: str

336

tasks: Dict[str, List[Task]] # Complex nested generic structure

337

338

# Complex nested structures with multiple generics

339

project = Project(

340

name="Website Redesign",

341

tasks={

342

"frontend": [

343

Task(1, "Create mockups", False, datetime(2023, 12, 15)),

344

Task(2, "Implement UI", False, datetime(2023, 12, 20))

345

],

346

"backend": [

347

Task(3, "API design", True),

348

Task(4, "Database schema", False, datetime(2023, 12, 10))

349

]

350

}

351

)

352

353

# Serialize complex nested structure

354

serialized = jsons.dump(project)

355

print(serialized['tasks']['frontend'][0]['title']) # 'Create mockups'

356

357

# Deserialize with full type reconstruction

358

restored = jsons.load(serialized, Project)

359

print(type(restored.tasks)) # <class 'dict'>

360

print(type(restored.tasks['frontend'])) # <class 'list'>

361

print(type(restored.tasks['frontend'][0])) # <class '__main__.Task'>

362

print(type(restored.tasks['frontend'][0].due_date)) # <class 'datetime.datetime'>

363

```