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.pyRun tests:
uv run pytest tests/test_jsondiff.pyfrom 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 TrueEach 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 deepdiffOr using pip:
pip install deepdiffThen 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