or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcore-operations.mddiff-syntaxes.mdindex.mdjsondiff-class.mdserialization.md

jsondiff-class.mddocs/

0

# JsonDiffer Configuration

1

2

The main class providing configurable diff computation with options for syntax, serialization, marshaling, and path exclusion. JsonDiffer serves as the central orchestrator for all diff operations and provides fine-grained control over the diff process.

3

4

## Capabilities

5

6

### JsonDiffer Class

7

8

Central class managing diff computation with comprehensive configuration options for different use cases and output requirements.

9

10

```python { .api }

11

class JsonDiffer:

12

"""

13

A class for computing differences between two JSON structures and applying patches.

14

"""

15

def __init__(self, syntax='compact', load=False, dump=False, marshal=False,

16

loader=None, dumper=None, escape_str='$'):

17

"""

18

Initialize JsonDiffer with specified options.

19

20

Parameters:

21

- syntax: str or syntax class, diff output format (default: 'compact')

22

- 'compact': Minimal output size

23

- 'explicit': Human-readable with clear operation labels

24

- 'symmetric': Bidirectional with original and modified values

25

- 'rightonly': Focus on final state values

26

- load: bool, automatically load JSON from strings or files (default: False)

27

- dump: bool, automatically dump output to JSON strings or files (default: False)

28

- marshal: bool, marshal diffs to handle special characters (default: False)

29

- loader: callable, custom function for loading JSON data (default: built-in JsonLoader)

30

- dumper: callable, custom function for dumping JSON data (default: built-in JsonDumper)

31

- escape_str: str, string used to escape special characters (default: '$')

32

"""

33

34

def diff(self, a, b, fp=None, exclude_paths=None):

35

"""

36

Compute difference between two JSON structures.

37

38

Parameters:

39

- a: Original JSON structure

40

- b: Modified JSON structure

41

- fp: Optional file pointer to dump diff to

42

- exclude_paths: list of string paths to exclude from diff

43

44

Returns:

45

dict: Computed diff structure

46

"""

47

48

def similarity(self, a, b):

49

"""

50

Calculate similarity score between two JSON structures.

51

52

Parameters:

53

- a: First JSON structure

54

- b: Second JSON structure

55

56

Returns:

57

float: Similarity score between 0.0 and 1.0

58

"""

59

60

def patch(self, a, d, fp=None):

61

"""

62

Apply diff to JSON structure to produce modified structure.

63

64

Parameters:

65

- a: Original JSON structure to patch

66

- d: Diff to apply

67

- fp: Optional file pointer to dump result to

68

69

Returns:

70

JSON structure: Patched structure

71

"""

72

73

def unpatch(self, b, d, fp=None):

74

"""

75

Reverse diff on JSON structure to produce original structure.

76

Available only with symmetric syntax.

77

78

Parameters:

79

- b: Modified JSON structure

80

- d: Diff that was applied

81

- fp: Optional file pointer to dump result to

82

83

Returns:

84

JSON structure: Original structure before diff

85

"""

86

87

def marshal(self, d):

88

"""

89

Convert structure to marshaled form with escaped special characters.

90

91

Parameters:

92

- d: Structure to marshal

93

94

Returns:

95

Marshaled structure with escaped symbols

96

"""

97

98

def unmarshal(self, d):

99

"""

100

Convert marshaled structure back to original form.

101

102

Parameters:

103

- d: Marshaled structure to unmarshal

104

105

Returns:

106

Original structure with unescaped symbols

107

"""

108

```

109

110

### Configuration Options

111

112

The JsonDiffer class provides extensive configuration through its Options inner class and constructor parameters.

113

114

```python { .api }

115

class JsonDiffer:

116

class Options:

117

"""Configuration options container for JsonDiffer."""

118

pass

119

```

120

121

**Usage Examples:**

122

123

```python

124

from jsondiff import JsonDiffer, JsonLoader, JsonDumper

125

126

# Basic configuration with different syntaxes

127

compact_differ = JsonDiffer(syntax='compact')

128

explicit_differ = JsonDiffer(syntax='explicit')

129

symmetric_differ = JsonDiffer(syntax='symmetric')

130

131

# Auto-loading from JSON strings

132

auto_loader = JsonDiffer(load=True)

133

result = auto_loader.diff('{"a": 1}', '{"a": 2, "b": 3}')

134

135

# Auto-dumping to JSON strings

136

auto_dumper = JsonDiffer(dump=True)

137

json_result = auto_dumper.diff({'a': 1}, {'a': 2}) # Returns JSON string

138

139

# Marshaling for safe serialization

140

marshal_differ = JsonDiffer(marshal=True)

141

result = marshal_differ.diff({'$delete': 'value'}, {'$delete': 'new_value'})

142

# Symbols are escaped: {'$$delete': 'new_value'}

143

144

# Custom loaders and dumpers

145

custom_loader = JsonLoader(parse_float=float, parse_int=int)

146

custom_dumper = JsonDumper(indent=2, sort_keys=True)

147

custom_differ = JsonDiffer(loader=custom_loader, dumper=custom_dumper)

148

149

# Custom escape string

150

custom_escape = JsonDiffer(escape_str='#')

151

# Symbols will be escaped with '#' instead of '$'

152

```

153

154

### Path Exclusion

155

156

Exclude specific JSON paths from diff computation, useful for ignoring timestamps, IDs, or other dynamic fields.

157

158

**Usage Examples:**

159

160

```python

161

from jsondiff import JsonDiffer

162

163

differ = JsonDiffer()

164

165

# Single path exclusion

166

data1 = {'user': {'name': 'John', 'last_login': '2023-01-01', 'id': 123}}

167

data2 = {'user': {'name': 'John', 'last_login': '2023-01-02', 'id': 123}}

168

169

result = differ.diff(data1, data2, exclude_paths=['user.last_login'])

170

# Result: {} (no differences after excluding timestamp)

171

172

# Multiple path exclusion

173

data1 = {

174

'users': [

175

{'name': 'Alice', 'id': 1, 'created': '2023-01-01'},

176

{'name': 'Bob', 'id': 2, 'created': '2023-01-02'}

177

],

178

'metadata': {'version': '1.0', 'timestamp': '2023-01-01T10:00:00'}

179

}

180

181

data2 = {

182

'users': [

183

{'name': 'Alice', 'id': 1, 'created': '2023-01-01'},

184

{'name': 'Bob', 'id': 2, 'created': '2023-01-02'},

185

{'name': 'Charlie', 'id': 3, 'created': '2023-01-03'}

186

],

187

'metadata': {'version': '1.1', 'timestamp': '2023-01-03T15:30:00'}

188

}

189

190

result = differ.diff(data1, data2, exclude_paths=[

191

'metadata.timestamp',

192

'users.created' # Note: This excludes the path pattern, not array elements

193

])

194

# Result focuses on structural changes, ignoring timestamps

195

```

196

197

### Advanced Configuration

198

199

Configure JsonDiffer for specialized use cases with custom serialization and processing options.

200

201

**Usage Examples:**

202

203

```python

204

from jsondiff import JsonDiffer, YamlLoader, YamlDumper

205

import json

206

207

# YAML processing configuration

208

yaml_differ = JsonDiffer(

209

load=True,

210

dump=True,

211

loader=YamlLoader(),

212

dumper=YamlDumper(default_flow_style=False)

213

)

214

215

# File-based operations

216

with open('config1.yaml', 'r') as f1, open('config2.yaml', 'r') as f2:

217

with open('diff.yaml', 'w') as output:

218

yaml_differ.diff(f1, f2, fp=output)

219

220

# High-precision numeric handling

221

class HighPrecisionLoader:

222

def __call__(self, src):

223

return json.loads(src, parse_float=lambda x: x) # Keep as string

224

225

precision_differ = JsonDiffer(loader=HighPrecisionLoader())

226

227

# Streaming large diffs

228

class StreamingDumper:

229

def __call__(self, obj, dest=None):

230

if dest:

231

json.dump(obj, dest, separators=(',', ':')) # Compact output

232

else:

233

return json.dumps(obj, separators=(',', ':'))

234

235

streaming_differ = JsonDiffer(dump=True, dumper=StreamingDumper())

236

237

# Combining multiple options

238

production_differ = JsonDiffer(

239

syntax='compact', # Minimal storage

240

marshal=True, # Safe for serialization

241

load=True, # Accept JSON strings

242

dump=True, # Return JSON strings

243

escape_str='@' # Custom escape character

244

)

245

```

246

247

### Marshaling and Unmarshaling

248

249

Handle special characters and symbols safely for serialization and storage.

250

251

**Usage Examples:**

252

253

```python

254

from jsondiff import JsonDiffer, delete, insert

255

256

differ = JsonDiffer(marshal=True)

257

258

# Data with symbol-like keys

259

original = {'$delete': 'some_value', 'normal_key': 'data'}

260

modified = {'$delete': 'updated_value', 'normal_key': 'data', '$insert': 'new'}

261

262

# Marshal handles symbol conflicts

263

result = differ.diff(original, modified)

264

# Symbols are properly escaped to avoid conflicts

265

266

# Manual marshaling/unmarshaling

267

raw_diff = {delete: ['removed_key'], 'updated_key': 'new_value'}

268

marshaled = differ.marshal(raw_diff)

269

print(marshaled) # {'$delete': ['removed_key'], 'updated_key': 'new_value'}

270

271

unmarshaled = differ.unmarshal(marshaled)

272

print(unmarshaled) # {delete: ['removed_key'], 'updated_key': 'new_value'}

273

274

# Safe round-trip serialization

275

import json

276

277

# Create diff with symbols

278

diff_with_symbols = differ.diff({'a': 1}, {'b': 2})

279

marshaled_diff = differ.marshal(diff_with_symbols)

280

281

# Serialize safely

282

json_str = json.dumps(marshaled_diff)

283

loaded_diff = json.loads(json_str)

284

285

# Unmarshal and apply

286

final_diff = differ.unmarshal(loaded_diff)

287

result = differ.patch({'a': 1}, final_diff)

288

```

289

290

## Error Handling

291

292

JsonDiffer handles various error conditions and provides clear error messages:

293

294

```python

295

from jsondiff import JsonDiffer

296

from json import JSONDecodeError

297

298

differ = JsonDiffer()

299

300

# Invalid syntax specification

301

try:

302

invalid_differ = JsonDiffer(syntax='nonexistent')

303

except (KeyError, AttributeError) as e:

304

print(f"Invalid syntax: {e}")

305

306

# Load errors with auto-loading

307

auto_differ = JsonDiffer(load=True)

308

try:

309

result = auto_differ.diff('{"invalid": json}', '{"valid": "json"}')

310

except JSONDecodeError as e:

311

print(f"JSON parsing error: {e}")

312

313

# Unpatch without symmetric syntax

314

compact_differ = JsonDiffer(syntax='compact')

315

try:

316

result = compact_differ.unpatch({'a': 2}, {'a': 1})

317

except AttributeError as e:

318

print(f"Unpatch not supported: {e}")

319

```