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

diff-syntaxes.mddocs/

0

# Diff Syntaxes

1

2

Multiple output formats for representing differences between JSON structures. Each syntax is optimized for different use cases, from compact storage to human readability to bidirectional operations. Syntaxes are accessed by name through the `JsonDiffer` class or `diff()` function parameters.

3

4

## Capabilities

5

6

### Compact Syntax

7

8

The default syntax focusing on minimizing output size while maintaining full diff information. Ideal for storage, transmission, and most programmatic use cases. Use `syntax='compact'` with `diff()` or `JsonDiffer`.

9

10

```python { .api }

11

# Access via string name, not direct class import

12

syntax_name = 'compact' # Use with diff() or JsonDiffer(syntax='compact')

13

```

14

15

**Usage Examples:**

16

17

```python

18

from jsondiff import diff, JsonDiffer

19

from jsondiff.symbols import insert, delete, replace

20

21

# Dictionary changes

22

original = {'name': 'Alice', 'age': 30, 'skills': ['Python', 'Django']}

23

modified = {'name': 'Alice', 'age': 31, 'skills': ['Python', 'Django', 'Flask']}

24

25

result = diff(original, modified, syntax='compact')

26

# Result: {'age': 31, 'skills': {insert: [(2, 'Flask')]}}

27

28

# List with mixed operations

29

list1 = ['x', 'a', 'c', 'x']

30

list2 = ['a', 'b', 'c']

31

32

result = diff(list1, list2, syntax='compact')

33

# Result: {insert: [(1, 'b')], delete: [3, 0]}

34

35

# Complete replacement when similarity is low

36

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

37

dict2 = {'x': 10, 'y': 20, 'z': 30}

38

39

result = diff(dict1, dict2, syntax='compact')

40

# Result: {replace: {'x': 10, 'y': 20, 'z': 30}}

41

```

42

43

### Explicit Syntax

44

45

Clear, human-readable syntax that explicitly labels all operations. Best for debugging, logging, and when diff readability is important. Use `syntax='explicit'` with `diff()` or `JsonDiffer`.

46

47

```python { .api }

48

# Access via string name, not direct class import

49

syntax_name = 'explicit' # Use with diff() or JsonDiffer(syntax='explicit')

50

```

51

52

**Usage Examples:**

53

54

```python

55

from jsondiff import diff

56

from jsondiff.symbols import insert, update, delete

57

58

# Dictionary with explicit operations

59

original = {'name': 'Alice', 'age': 30, 'temp': 'xyz'}

60

modified = {'name': 'Bob', 'age': 30, 'city': 'NYC'}

61

62

result = diff(original, modified, syntax='explicit')

63

# Result: {insert: {'city': 'NYC'}, update: {'name': 'Bob'}, delete: ['temp']}

64

65

# List operations clearly labeled

66

list1 = ['a', 'b', 'c']

67

list2 = ['a', 'x', 'c', 'd']

68

69

result = diff(list1, list2, syntax='explicit')

70

# Result: {insert: [(3, 'd')], update: {1: 'x'}}

71

72

# Set operations with clear labels

73

set1 = {'red', 'green', 'blue'}

74

set2 = {'red', 'yellow', 'purple'}

75

76

result = diff(set1, set2, syntax='explicit')

77

# Result: {add: {'yellow', 'purple'}, discard: {'green', 'blue'}}

78

```

79

80

### Symmetric Syntax

81

82

Maintains both original and modified values, enabling bidirectional operations. Supports both `patch()` and `unpatch()` operations for reversible diffs. Use `syntax='symmetric'` with `JsonDiffer`.

83

84

```python { .api }

85

# Access via string name, not direct class import

86

syntax_name = 'symmetric' # Use with JsonDiffer(syntax='symmetric')

87

```

88

89

**Usage Examples:**

90

91

```python

92

from jsondiff import diff, JsonDiffer

93

from jsondiff.symbols import insert, delete

94

95

# Dictionary with value history

96

original = {'name': 'Alice', 'age': 30, 'status': 'active'}

97

modified = {'name': 'Alice', 'age': 31, 'city': 'NYC'}

98

99

result = diff(original, modified, syntax='symmetric')

100

# Result: {'age': [30, 31], insert: {'city': 'NYC'}, delete: {'status': 'active'}}

101

102

# Bidirectional operations

103

differ = JsonDiffer(syntax='symmetric')

104

105

# Forward patch: original -> modified

106

patched = differ.patch(original, result)

107

print(patched) # {'name': 'Alice', 'age': 31, 'city': 'NYC'}

108

109

# Reverse patch: modified -> original

110

unpatched = differ.unpatch(patched, result)

111

print(unpatched) # {'name': 'Alice', 'age': 30, 'status': 'active'}

112

113

# List with symmetric changes

114

list1 = ['a', 'b', 'c']

115

list2 = ['a', 'x', 'c', 'd']

116

117

result = diff(list1, list2, syntax='symmetric')

118

# Result: {1: ['b', 'x'], insert: [(3, 'd')]}

119

120

# Complete replacement with both values

121

dict1 = {'a': 1}

122

dict2 = {'b': 2}

123

124

result = diff(dict1, dict2, syntax='symmetric')

125

# Result: [{'a': 1}, {'b': 2}]

126

```

127

128

### RightOnly Syntax

129

130

Focuses exclusively on the modified (right) values, particularly for lists. Useful when only the final state matters, not the path to get there. Use `syntax='rightonly'` with `diff()` or `JsonDiffer`.

131

132

```python { .api }

133

# Access via string name, not direct class import

134

syntax_name = 'rightonly' # Use with diff() or JsonDiffer(syntax='rightonly')

135

```

136

137

**Usage Examples:**

138

139

```python

140

from jsondiff import diff

141

142

# List shows final state only

143

original = ['Python', 'Django']

144

modified = ['Python', 'Django', 'Flask', 'React']

145

146

result = diff(original, modified, syntax='rightonly')

147

# Result: ['Python', 'Django', 'Flask', 'React']

148

149

# Dictionary still shows changes but focuses on final values

150

dict1 = {'name': 'Alice', 'skills': ['Python']}

151

dict2 = {'name': 'Alice', 'skills': ['Python', 'JavaScript', 'React']}

152

153

result = diff(dict1, dict2, syntax='rightonly')

154

# Result: {'skills': ['Python', 'JavaScript', 'React']}

155

156

# Useful for configuration updates where history doesn't matter

157

config1 = {'servers': ['srv1', 'srv2'], 'timeout': 30}

158

config2 = {'servers': ['srv1', 'srv3', 'srv4'], 'timeout': 60}

159

160

result = diff(config1, config2, syntax='rightonly')

161

# Result: {'servers': ['srv1', 'srv3', 'srv4'], 'timeout': 60}

162

```

163

164

### Custom Syntax Registration

165

166

Built-in syntaxes are accessible by name through `JsonDiffer` and can be extended with custom implementations.

167

168

```python { .api }

169

# Available built-in syntax names

170

available_syntaxes = ['compact', 'symmetric', 'explicit', 'rightonly']

171

```

172

173

**Usage Examples:**

174

175

```python

176

from jsondiff import JsonDiffer

177

178

# Use built-in syntax by name

179

differ = JsonDiffer(syntax='compact')

180

181

# Custom syntax class (advanced usage)

182

class VerboseJsonDiffSyntax:

183

def emit_value_diff(self, a, b, s):

184

if s == 1.0:

185

return {"status": "unchanged", "value": a}

186

else:

187

return {"status": "changed", "from": a, "to": b}

188

189

def emit_dict_diff(self, a, b, s, added, changed, removed):

190

# ... implement required method

191

pass

192

193

def emit_list_diff(self, a, b, s, inserted, changed, deleted):

194

# ... implement required method

195

pass

196

197

def emit_set_diff(self, a, b, s, added, removed):

198

# ... implement required method

199

pass

200

201

def patch(self, a, d):

202

# ... implement required method

203

pass

204

205

# Use custom syntax

206

custom_differ = JsonDiffer(syntax=VerboseJsonDiffSyntax())

207

result = custom_differ.diff({'x': 1}, {'x': 2})

208

# Result: {'x': {"status": "changed", "from": 1, "to": 2}}

209

```

210

211

## Syntax Comparison

212

213

| Syntax | Use Case | Patch Support | Unpatch Support | Output Size |

214

|--------|----------|---------------|-----------------|-------------|

215

| `compact` | General purpose, storage ||| Minimal |

216

| `explicit` | Human readable, debugging ||| Medium |

217

| `symmetric` | Bidirectional, version control ||| Large |

218

| `rightonly` | Final state focus ||| Medium |

219

220

## Error Handling

221

222

Syntax classes may raise exceptions for malformed diffs:

223

224

```python

225

from jsondiff import JsonDiffer

226

227

differ = JsonDiffer(syntax='symmetric')

228

229

# Invalid symmetric diff structure

230

try:

231

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

232

except Exception as e:

233

print(f"Invalid diff format: {e}")

234

```