| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
⚠️ Please install the Codecov Report❌ Patch coverage is 94.38503% with 21 lines in your changes missing coverage. Please review.
@@ Coverage Diff @@
## master #612 +/- ##
==========================================
- Coverage 95.10% 95.07% -0.04%
==========================================
Files 17 18 +1
Lines 4900 5274 +374
==========================================
+ Hits 4660 5014 +354
- Misses 240 260 +20 ☔ View full report in Codecov by Harness.
|
Sorry, something went wrong.
Add an opt-in JSON collection comparison facade with path-scoped identity matching, sorting, filtering, normalization, diagnostics, compatibility boundaries, tests, and documentation.
| Back | FazBrowse Home | New Git URL |
Problem statement
DeepDiff compares arbitrary Python and JSON-like structures, but nested API collections are often unordered and keyed by business identity rather than list position. Positional comparison can create cascading false positives when records are inserted, removed, or reordered.
This PR adds an opt-in, reusable normalization layer for declaring collection-specific semantics without changing existing DeepDiff behavior.
Proposed solution
The PR introduces DeepJSONDiff and CollectionStrategy. Both inputs are converted into canonical caller-isolated views, then compared by the existing DeepDiff engine.
The existing DeepDiff constructor and comparison semantics remain unchanged.
Selector semantics
Supported selectors include:
JSON object keys are expected to be strings. Diagnostic paths use the same quoted-key syntax and can be reused as selectors.
Collection behavior
Identity matching
match_by supports single, composite, and nested fields. Identity values must resolve after normalization to finite JSON scalars: None, booleans, integers, finite floats, or strings.
Identity labels use canonical type-preserving encoding, so integer 1, float 1.0, and string "1" remain distinct and composite identities cannot collide through delimiter characters.
Filtering, normalization, sorting, and exclusion
Filters and normalizers receive defensive copies and may mutate them without modifying caller-owned payloads. Copies are created only when callbacks are configured.
Processing order is:
Identity and sort fields may therefore be excluded from the compared record while still controlling matching or ordering.
sort_by provides a total, type-stable order for JSON-compatible values. Integers and floats remain distinct. Finite values, infinities, and NaN values have deterministic positions without heterogeneous comparison failures.
Structured sort keys are restricted to JSON lists and mappings with string keys. Unsupported values are rejected instead of being ordered through unstable repr() output.
Order-insensitive scalar arrays
compare_as_set=True performs multiset/bag comparison:
Missing and duplicate identities
Missing identity policies:
Duplicate policies:
Enum members and string values are accepted.
Diagnostics
get_stats() separates diagnostics by input side:
Each entry reports the selected strategy, input item count, filtered count, missing-identity count, and duplicate-group count. Separating sides prevents unrelated parent records from being conflated after parent reordering.
DeepDiff keyword compatibility
Identity matching changes selected arrays into canonical mappings. Options whose behavior depends on caller-visible paths, object paths, or iterable positions are rejected instead of being interpreted against a different structure:
Other keyword arguments are forwarded to the underlying DeepDiff instance.
Result interface
DeepJSONDiff is a composition-based facade rather than a complete DeepDiff subclass. It implements the read-only Mapping interface, delegates to_dict() and to_json(), and exposes the underlying result through result.diff.
Backward compatibility
The feature is fully opt-in:
Files changed
No custom GitHub Actions workflow is included.
Validation performed
The implementation is validated across Python 3.10–3.14 and includes focused tests for:
Scope and limitations
This PR provides deterministic exact reconciliation. It does not infer business identity or perform fuzzy matching. The selector grammar is intentionally smaller than full JSONPath. Relative identity and sort fields use dotted extraction and numeric list indexes.
For identity-matched collections, result paths contain canonical identity keys rather than unstable original list indexes.