A Python implementation for comparing JSON objects and generating structured diffs that treats array changes as complete units.
jsondiff.py
- Main library containing JSONDiff and JSONReconstructor classesdemo.py
- Demonstration script showing both diff generation and reconstructiontests/test_jsondiff.py
- Comprehensive test suite
Run the demo:
uv run python demo.py
Run tests:
uv run pytest tests/test_jsondiff.py
from jsondiff import JSONDiff
differ = JSONDiff()
diffs = differ.compare(json1, json2)
from jsondiff import JSONReconstructor
reconstructor = JSONReconstructor()
original = reconstructor.reverse_diff(current_json, diffs)
import json
from jsondiff import JSONDiff, JSONReconstructor
# Sample JSON objects
json1 = {
"name": "John",
"fruits": {
"apple": 1,
"arr": [1, 2, 3]
}
}
json2 = {
"name": "John Doe",
"age": 30,
"fruits": {
"apple": 1,
"arr": [1, 3, 4]
}
}
# Generate diff
differ = JSONDiff()
diffs = differ.compare(json1, json2)
# Each diff contains:
for diff in diffs:
print(f"Field: {diff['field_name']}")
print(f"Change: {diff['change_type']}")
print(f"From: {diff['from_value']}")
print(f"To: {diff['to_value']}")
print(f"Path: {diff['full_path']}")
print(f"Type: {diff['value_type']}")
# Reconstruct original
reconstructor = JSONReconstructor()
original = reconstructor.reverse_diff(json2, diffs)
assert original == json1 # Should be True
Each difference is represented as:
{
"field_name": "arr",
"change_type": "modified",
"from_value": "[1,2,3]",
"to_value": "[1,3,4]",
"full_path": "/fruits/arr",
"value_type": "array"
}
added
- New field was addedremoved
- Existing field was deletedmodified
- Field value was changed
Arrays are treated as complete units. When array elements change, the entire array is considered modified rather than tracking individual element changes.
For example:
[1,2,3]
→[1,3,4]
creates a single "modified" entry- This approach keeps diffs clean and reconstruction straightforward
Both dict objects and JSON strings are supported:
# Dict input
differ.compare({"a": 1}, {"a": 2})
# JSON string input
differ.compare('{"a": 1}', '{"a": 2}')
# Mixed input
differ.compare({"a": 1}, '{"a": 2}')
deepdiff>=6.0.0
- For deep comparison logictyping
- For type annotations (Python standard library)json
- For JSON parsing (Python standard library)re
- For path manipulation (Python standard library)
Using uv (recommended):
uv add deepdiff
Or using pip:
pip install deepdiff
Then copy jsondiff.py
to your project or install the package.
The package includes comprehensive tests covering:
- Basic diff operations
- Nested object changes
- Array modifications
- Edge cases (unicode, special characters, etc.)
- Reconstruction accuracy
- Error handling
Run tests with:
uv run pytest tests/test_jsondiff.py -v