deepdiff-rs
onix is a Rust rewrite of Python DeepDiff's core: byte-compatible output, 37-4245x faster, with ignore_order support included. Install it as deepdiff-rs, a drop-in DeepDiff class for Python, or run the diff engine as the onix command-line tool.
deepdiff-rs reads live Python objects (or JSON) and produces the exact same report DeepDiff does at verbose_level=2, so it slots into code that already parses DeepDiff output while running dramatically faster on large or deeply nested inputs.
Status (September 2026): deepdiff-rs 0.x is live on PyPI (Python 3.9+, wheels for Linux x86_64/aarch64, macOS arm64/x86_64, and Windows x64, plus an sdist); the onix CLI builds from source, and nothing is on crates.io yet. Ordered and ignore_order diffing are complete, differentially tested against real DeepDiff 9.1.0, and benchmarked. It is 0.x, not stable or 1.0: the API may still change before 1.0.
Table of contents
- Install
- Quickstart
- Diffing tables
- Performance
- Reference
- Layout
- Known limitations
- Contributing
- License
Install
Python (the deepdiff-rs package, import name deepdiff_rs):
pip install deepdiff-rs
From source:
cd crates/onix-py
uv tool install maturin # the build tool (skip if already installed)
uv sync --group test # creates .venv, installs pytest, pinned deepdiff, and pyarrow/polars/duckdb for the table-diff tests
uv run --group test maturin develop --release
CLI (the onix binary), from a clean clone:
cargo install --path crates/onix-cli
Library crate (onix-core), a path dependency only (it sets publish = false):
[dependencies]
onix-core = { path = "crates/onix-core" }
Quickstart
The drop-in DeepDiff class, on live Python objects:
from deepdiff_rs import DeepDiff
diff = DeepDiff({"a": 1}, {"a": 2})
if diff:
print(diff.to_json()) # byte-compatible with DeepDiff(...).to_json() at verbose_level=2
print(diff.to_dict()) # the same report as a native Python dict
{"values_changed":{"root['a']":{"new_value":2,"old_value":1}}}
{'values_changed': {"root['a']": {'new_value': 2, 'old_value': 1}}}
diff_json, the fast path when you already have JSON text (it parses, diffs, and serializes entirely in Rust, with no Python-object conversion):
from deepdiff_rs import diff_json
print(diff_json('{"a": 1}', '{"a": 2}'))
{"values_changed":{"root['a']":{"new_value":2,"old_value":1}}}
The onix CLI, diffing two JSON files (compact JSON to stdout, {} for no differences):
$ echo '{"a": 1}' > left.json
$ echo '{"a": 2}' > right.json
$ onix diff left.json right.json
{"values_changed":{"root['a']":{"new_value":2,"old_value":1}}}
Pass --ignore-order to compare every list by value instead of by position, mirroring DeepDiff(..., ignore_order=True).
Diffing tables
diff_tables compares two tables the way DeepDiff compares two objects. It takes any object implementing the Arrow PyCapsule interface — a pyarrow Table or RecordBatch, a polars DataFrame, a DuckDB relation — and imports it with no Python round trip. The two tables are matched on a required, non-empty set of key columns (the table's primary key).
It reports the schema diff (which columns were added, removed, or changed type), the keyed row diff (which rows were added, removed, or changed, and which keys are duplicated), and the per-cell diff (cells_changed): one row per changed cell of a changed row, carrying the key columns, the column, its old_value/new_value in a canonical string rendering (a decimal at its native scale and a string verbatim, both matching DuckDB; a timestamp as its UTC instant, keeping its zone when aware; a cross-variant interval with its variant appended; a duration as ISO 8601 PT<seconds>S, never through the Arrow formatter (which can emit a <invalid> sentinel); numbers of differing width at the wider type, so an f32 0.1 shows as 0.10000000149011612 against an f64 0.1 — the exact rules are in the module doc of crates/onix-arrow/src/row_diff.rs), and a change: became_null/became_non_null for a one-sided null, type_changed when the two types are not losslessly comparable (different value kinds, an aware-versus-naive timestamp, or a cross-variant interval), otherwise value_changed — a lossless type difference (integer or float widening, a time/duration unit change, a decimal scale change) is value_changed only when the value truly differs, never merely for the type. Its rows are ordered by the canonical string rendering of the key columns (so numeric keys sort as strings — 10 before 2 — nulls first), then left-schema column order. Rows are matched by the key columns; rows_added, rows_removed, cells_changed, and duplicate_keys return Arrow tables, and summary() counts each outcome.
import pyarrow as pa
from deepdiff_rs import diff_tables
left = pa.table({
"id": pa.array([1, 2, 3], pa.int64()),
"amount": pa.array([10, 20, 30], pa.int32()),
})
right = pa.table({
"id": pa.array([2, 3, 4], pa.int64()),
"amount": pa.array([20, 31, 40], pa.int64()),
"note": pa.array(["a", "b", "c"], pa.string()),
})
diff = diff_tables(left, right, key=["id"])
print(diff.summary())
print("added ids:", pa.table(diff.rows_added()).column("id").to_pylist())
print("cells changed:", pa.table(diff.cells_changed()).to_pylist())
{'columns_added': 1, 'columns_removed': 0, 'columns_type_changed': 1, 'rows_added': 1, 'rows_removed': 1, 'rows_changed': 1, 'duplicate_keys': 0, 'null_keys': 0, 'cells_changed': 1}
added ids: [4]
cells changed: [{'id': 3, 'column': 'amount', 'old_value': '30', 'new_value': '31', 'change': 'value_changed'}]
A key appearing more than once on either side is reported in duplicate_keys (with left_count and right_count) and excluded from the added/removed/changed sets; a null key matches its counterpart and is counted in null_keys. Rows are compared by the non-key columns present on both sides, with onix's value semantics (integers and integral floats fold together, all NaNs compare equal, 1.00 equals 1.0000, a timestamp compares by its instant and a time or duration by its value across units, dictionary-encoded values equal their plain form, and null equals null); a nested non-key column is out of scope and is skipped rather than compared. The exact value-comparison rules are documented on the hashing functions in crates/onix-arrow/src/row_diff.rs.
Type comparison uses the full logical Arrow type (timestamp unit and timezone, decimal precision and scale, and so on), but physical encodings that carry the same logical type compare equal — a dictionary-encoded string equals a plain string, polars' Utf8View equals pyarrow's Utf8, the list variants normalize together, and a map compares equal however a library spells it — so the same table read through pyarrow, polars, or DuckDB reports no spurious type changes. The full normalization rules are documented on normalized_type (and map_entries) in crates/onix-arrow/src/schema.rs; nullability is ignored but reported in each record. Column names must be unique on each side; a repeated name raises ValueError. diff.schema_arrow is the same result as an Arrow table: it implements __arrow_c_stream__, so polars.DataFrame(diff.schema_arrow) and pandas consume it directly, and diff.schema_arrow.to_pyarrow() returns a pyarrow.Table.
pyarrow is optional: install it with pip install deepdiff-rs[arrow]. It is needed only for to_pyarrow() and for passing pyarrow objects in — importing deepdiff_rs and diffing polars or DuckDB tables need it not at all. Passing an object that implements neither Arrow protocol raises TypeError; calling to_pyarrow() without pyarrow installed raises ImportError naming the extra.
Performance
Two committed, regenerable reports back the numbers below; every figure here is copied verbatim from them.
The Python bindings against real deepdiff on live Python objects, the number a real caller pays (source: crates/onix-py/benchmarks/bench_bindings.py, macOS 26.5.1, Apple M5 Max, median of 11 isolated subprocess runs per side, run on 2026-09-04):
| Shape | deepdiff | deepdiff_rs | Speedup |
|---|---|---|---|
ignore_order, 10k shuffled ints, ~5% mutated (live objects) |
3111.56ms | 71.68ms | 43.41x |
| peak RSS | 228.5 MB | 93.2 MB | 2.45x |
| CPU seconds | 3.110 s | 0.072 s | 43.42x |
| Heterogeneous API-payload records, n=20,000 (live objects) | 3439.96ms | 153.83ms | 22.36x |
| peak RSS | 118.1 MB | 147.8 MB | 0.80x |
| CPU seconds | 3.439 s | 0.154 s | 22.36x |
| Typed records (datetime/tuple/set fields), n=10,000 (live objects) | 795.17ms | 48.48ms | 16.40x |
| peak RSS | 60.2 MB | 62.2 MB | 0.97x |
| CPU seconds | 0.795 s | 0.048 s | 16.40x |
Same typed-records shape, ignore_order (live objects) |
60506.65ms | 775.38ms | 78.03x |
| peak RSS | 110.3 MB | 121.6 MB | 0.91x |
| CPU seconds | 60.471 s | 0.774 s | 78.10x |
Same ignore_order shape, via diff_json (JSON-string path) |
3116.22ms | 73.85ms | 42.20x |
| peak RSS | 228.8 MB | 93.8 MB | 2.44x |
| CPU seconds | 3.114 s | 0.074 s | 42.20x |
Same API-payload shape, via diff_json (JSON-string path) |
4559.90ms | 87.02ms | 52.40x |
| peak RSS | 139.5 MB | 140.9 MB | 0.99x |
| CPU seconds | 4.558 s | 0.087 s | 52.58x |
| Same API-payload shape, both tools reading two JSON files from disk | 4555.37ms | 85.62ms | 53.20x |
| peak RSS | 139.5 MB | 141.0 MB | 0.99x |
| CPU seconds | 4.553 s | 0.086 s | 53.21x |
The engine's own diff-only time and peak resident memory against pinned deepdiff 9.1.0 (source: perf/RESULTS.md, same machine, median over tier-appropriate runs, diff time excluding process startup and JSON parsing on both sides):
| Fixture | onix diff-only (median, min-max) | deepdiff diff-only (median, min-max) | Speedup | onix peak RSS | deepdiff peak RSS | Memory ratio | ≥5x threshold |
|---|---|---|---|---|---|---|---|
flat_dict_10k |
3.154 ms (3.058 ms-3.220 ms) | 141.155 ms (140.606 ms-142.781 ms) | 44.75x | 5.78 MB | 39.29 MB | 6.79x | ✅ |
flat_dict_100k |
38.440 ms (38.000 ms-38.806 ms) | 1.594 s (1.581 s-1.602 s) | 41.47x | 40.57 MB | 110.82 MB | 2.73x | ✅ |
flat_dict_1m |
460.082 ms (454.820 ms-465.133 ms) | 17.061 s (16.926 s-17.162 s) | 37.08x | 478.15 MB | 753.65 MB | 1.58x | ✅ |
flat_list_100k |
82.907 ms (81.131 ms-84.654 ms) | 4.751 s (4.715 s-4.820 s) | 57.31x | 38.17 MB | 154.95 MB | 4.06x | ✅ |
nested_uniform_d6_b10 |
207.242 ms (205.249 ms-217.027 ms) | 71.458 s (70.959 s-71.599 s) | 344.80x | 227.41 MB | 868.32 MB | 3.82x | ✅ |
api_payloads |
162.489 ms (159.446 ms-178.736 ms) | 93.764 s (93.687 s-94.474 s) | 577.05x | 270.09 MB | 609.93 MB | 2.26x | ✅ |
deep_narrow_d120 |
0.029 ms (0.028 ms-0.030 ms) | 123.650 ms (123.230 ms-125.018 ms) | 4245.55x | 2.15 MB | 41.27 MB | 19.23x | ✅ |
startup_trivial |
0.001 ms (0.001 ms-0.001 ms) | 0.175 ms (0.169 ms-0.183 ms) | 147.75x | 2.15 MB | 32.67 MB | 15.22x | ✅ |
ignore_order_10k |
73.475 ms (71.672 ms-73.940 ms) | 12.976 s (12.900 s-13.005 s) | 176.60x | 60.11 MB | 345.19 MB | 5.74x | ✅ |
identical_1m |
9.254 ms (6.726 ms-9.875 ms) | 15.790 s (15.660 s-15.989 s) | 1706.35x | 315.41 MB | 503.19 MB | 1.60x | ✅ |
Both reports carry their full methodology, fairness rules, and the reproduce command. perf/RESULTS.md is an upper bound (JSON parsed straight into the engine, no Python-object conversion); the bindings table is the product-surface number. Regenerate them with perf/run_bench.sh and crates/onix-py/benchmarks/bench_bindings.py (see CONTRIBUTING.md).
Reference
Python API. The public surface is DeepDiff, diff_json, diff_tables (returning a TableDiff), MaxDepthError, and MAX_DEPTH_CEILING.
DeepDiff(t1, t2, ignore_order=False, max_depth=None): diffs two live Python objects of supported value types —None,bool,int,float,str,dict(withstrkeys),list,tuple,set,frozenset,datetime.datetime,datetime.date,datetime.time, anddatetime.timedelta(see Known limitations for the exact restrictions and exclusions);.to_json()returns the DeepDiff-compatible JSON string,.to_dict()the same report as a dict — with Python types preserved, so a value the diff found in atuple,setorfrozensetcomes back as one and adatetime/date/time/timedeltacomes back as a real one of those — and the instance is falsy when there is no difference. Theset_item_added/set_item_removedcategories are lists of path strings, each ending in the item itself (root['a'][2],root['x'],root[(1, 2)]).diff_json(a, b, ignore_order=False, max_depth=None) -> str: diffs two JSON strings entirely in Rust and returns the report as a JSON string.MaxDepthError(aValueErrorsubclass) is raised when input exceedsmax_depth;MAX_DEPTH_CEILING(20,000) is the hard upper bound onmax_depth.diff_tables(left, right, key=[...]) -> TableDiff: diffs two Arrow tables (see Diffing tables).TableDiff.schemais the list of changed columns,.schema_arrowthe same as an Arrow table,.summary()the schema and row change counts,.to_json()the schema diff as JSON;.rows_added(),.rows_removed(),.cells_changed(), and.duplicate_keys()return Arrow tables.
CLI. onix diff <a.json> <b.json> [--max-depth N] [--ignore-order] [--timing] reads both files as JSON and prints a compact, single-line DeepDiff-compatible report to stdout ({} when there is no difference).
--max-depth Noverrides the recursion-depth bound (default: theONIX_MAX_DEPTHenvironment variable if set, else 512).--ignore-ordercompares every list by hash-based matching instead of by position, mirroringDeepDiff(..., ignore_order=True).--timingprints one line of JSON ({"parse_ns": N, "diff_ns": N}) to stderr.
Exit codes:
| Code | Meaning |
|---|---|
0 |
Diff computed successfully (whether or not the report is empty; differences are carried in the stdout JSON, not the exit code). |
1 |
Usage error (missing/unknown subcommand, wrong argument count, unknown flag, non-numeric --max-depth); details and a usage line go to stderr. |
2 |
I/O error (e.g. a missing input file) or a JSON-parse error on either input. |
3 |
max_depth exceeded; the path that tripped the bound goes to stderr. |
Layout
crates/onix-core # the diff engine (library, no I/O)
crates/onix-cli # the `onix` binary (thin CLI over the core)
crates/onix-arrow # Arrow table diffing (schema diff and keyed row diff)
crates/onix-py # PyO3 bindings, published as `deepdiff-rs`
scripts/ # gen_goldens.py: regenerates tests/golden/ from real DeepDiff
tests/golden # DeepDiff-generated expected outputs (the compatibility corpus)
perf/ # cross-language benchmark harness and RESULTS.md
Known limitations
- Only the core diff is implemented:
exclude_paths,significant_digits, custom operators,verbose_level != 2, and delta/patch are not (yet) supported. - Supported value types are
None,bool,int,float,str,dict(withstrkeys),list,tuple,set,frozenset,datetime.datetime,datetime.date,datetime.time, anddatetime.timedelta; aset/frozensetmember may be any of these except alist,dictorset, matching Python's own hashability rule, transitively through whatever the member nests.ints must fit ini64/u64,floats must be finite, and anything else — a non-strdict key, a custom object, an arbitrary-precisionint, or a non-finitefloat— raisesTypeError/ValueErrornaming the exact path it was found at. The Datetimes and Sets bullets below cover the deliberate divergences for those types. Seecrates/onix-py/src/convert.rsandtests/golden/README.md. - A subclass of a supported type (a
tuple,setorfrozensetsubclass includingnamedtuple, adatetime/date/time/timedeltasubclass such as pandas'Timestamp) raisesTypeErrorrather than being diffed as its base type, because DeepDiff reports each value's own type name. Atype_changesentry'sold_type/new_typeare type names into_dict(), where DeepDiff returns the type objects. Both are described intests/golden/README.md. - Datetimes compare by instant, with a naive value read as UTC, matching DeepDiff. A changed pair is reported normalized to UTC (
to_json()renders...+00:00,to_dict()returns UTC-awaredatetimes); everywhere else a datetime keeps its raw value. Three deliberate departures:to_json()renders adateasYYYY-MM-DDwhere DeepDiff's ownto_json()raisesTypeError(a documented superset); azoneinfo/pytztzinfo comes back fromto_dict()as a fixed-offsetdatetime.timezonecarrying the offset it was in force at, not the original zone object; and a set holding both a naive and an aware value at one instant reports both as members, where DeepDiff's own digest cache can report only one (seecrates/onix-py/src/convert.rs). Comparing two datetimes whose UTC form would leave year 1..=9999 raisesValueErrornaming the path, where DeepDiff raisesOverflowError; underignore_orderDeepDiff's hasher normalizes every datetime and so raises for such a value even when it is only added, removed, or shuffled, where onix hashes by instant and reports it normally (seetests/golden/README.md).truncate_datetimeis not supported; the normalized-versus-raw split is documented there too. Atime/timedelta, unlike a datetime, is never normalized for report (DeepDiff comparestime/date/timedeltawith a plain!=), and a naivetimeis never equal to an aware one;to_json()renders atimeastime.isoformat()'s bytes and atimedeltaasstr(timedelta)'s, both supersets. Underignore_order,DeepHashhashes atimeby whole seconds-of-day only — dropping the microsecond and any offset, a confirmed upstream quirk — while atimedeltahashes exactly; seetests/golden/README.md's "Known DeepDiff quirks" section. - Sets are diffed deterministically, where DeepDiff's own answers depend on the order the running process happens to iterate a set in (hash order, and
PYTHONHASHSEED-dependent forstrmembers) or on how its digest cache/computation handles a tuple, frozenset, or calendar member independently of Python's own==. Each consequence — entry order, which member of an equality class is reported, set-versus-sequence coercion, and a tuple/frozenset member's own (positional, not order-/repetition-insensitive) matching rule — is shown with both tools' output intests/golden/README.md's "Set iteration order" section. A report holding afrozensetvalue also serializes to JSON here, where DeepDiff's ownto_json()raisesTypeError— a superset, not a difference in the findings. - A
strcontaining a lone (unpaired) surrogate code point (e.g.'\udc80', legal in Python but not encodable as UTF-8) raisesValueErrornaming the exact path on either side, before the two values are ever compared — including a pair DeepDiff would call equal and report as no change, since DeepDiff's scalar equality is plain Python==and never hits the encoding problem; DeepDiff does report a plain change for a differing pair, and crashes with an unhandledUnicodeEncodeErrorif such a string is ever hashed (aset/frozensetmember). Seetests/golden/README.md's "Known DeepDiff quirks" section. - A
strinside atupleorfrozensetset item is escaped exactly as Python'srepr()escapes it, against Unicode 16.0.0; on a Python older than 3.14 (an olderunicodedatatable), a code point assigned to Unicode after that Python's own version is escaped by DeepDiff and rendered literally by onix. Seetests/golden/README.md's "Pinned versions" section. - Adversarially deep input raises
MaxDepthErrorinstead of crashing: the defaultmax_depthis 512 and the hard ceiling isMAX_DEPTH_CEILING(20,000). Seecrates/onix-py/src/guard.rs. ignore_orderpairing isO(N^2)in unpaired elements per side and carries a polynomial cost in both time and memory with input depth; it has nomax_passes/max_diffscutoff, so bound the size and depth of untrusted input yourself. Seecrates/onix-core/src/ignore_order/mod.rs.- A
values_changedbetween two multi-line strings runs adifflib-styleO(N*M)line diff on the default path with no opt-out, worst when changes are spread evenly through the text (about 35 s for a heavily edited 1 MB string and growing quadratically, so a few megabytes is minutes), so bound the size of untrusted strings yourself. Seecrates/onix-core/src/unified_diff.rs. - Ordered sequences (
listortuple) of scalars (null, bool, number, string, datetime, date, time, timedelta) run adifflib-styleO(N*M)matcher on the default path with its popular-element (autojunk) purge disabled forDeepDiffparity, worst for sequences of a few repeated values with dense edits (about 620 s for two 8,000-element lists of two repeated values with every other element changed, growing faster than quadratically), so bound the size of untrusted sequences yourself. Seecrates/onix-core/src/lcs.rs. diff_tablesinherits some Arrow-interchange quirks: a column name with an embedded NUL byte (\0) arrives truncated at the NUL through the C Data Interface (the report shows the truncated name; rare in practice); a list of structs named exactlykey/valuewith a nullable key is not distinguished from a real map, so a migration between the two is not reported as a type change (polars exports both as the same Arrow type — seemap_entriesincrates/onix-arrow/src/schema.rs); and a polars all-null (Null-typed) column fails at Arrow C import with aValueError(the datatype "Null" doesn't expect buffer at index 0), so give such a column a concrete type first (a pyarrow all-Nonecolumn, inferred asnull, works and compares as all-null).- In
diff_tables, DuckDB labels aTIMESTAMP WITH TIME ZONEcolumn with the connection's session time zone when it exports to Arrow (a UTC session asTimestamp(µs, "UTC"), anAmerica/New_Yorksession asTimestamp(µs, "America/New_York")), so on a non-UTC machine such a column can be reported as a type change against a UTC column from another library. RunSET TimeZone='UTC'on the DuckDB connection first for a deterministic, machine-independent result. diff_tablesrefuses a column whose Arrow type is nested deeper thanMAX_NESTING_DEPTH(128) with aMaxDepthError, because comparing arbitrarily deep nesting would overflow the native stack; 128 is far beyond any real schema. Importing a schema nested many thousands of levels deep is also slow regardless, a cost of the Arrow C Data Interface itself.diff_tables's row diff costs, per call: RAM for a 32-byte hash per row per side (sorted), so peak memory is linear in row count (about 75 MB at 1M rows/side, 660 MB at 10M) and time isN·log N(about 2 s for a 10M-row pair), plus a second term for the duplicate-key report, which holds the key values of every distinct duplicated key — an all-duplicate 200k-rows/side table (100k distinct duplicated keys) peaks at about 37 MB with 16-byte keys and 1.05 GB with 1 KB keys, 1M rows/side (500k distinct) at about 165 MB with 16-byte keys; a third term for the per-cell diff, which re-reads both inputs, holds the changed rows of both sides, and renders every changed cell to a string held once in the output — so its cost is the number of changed cells times the cell width, not the changed-row count alone (every value is rendered in full). Measured, same method: with two narrowint64columns, 85 MB at 1M rows/side with 2% changed and 629 MB with every row changed; with a 1 KBstringcell changed on every row, 1.18 GB at 100k rows/side and 2.34 GB at 200k (about 11.6 KB per changed row, linear, so on the order of 11.6 GB at 1M). Then temp disk, because each input is re-read several times and so is spooled to an anonymous file (tempfile: unlinked at once, mode 0600, no predictable name — nothing is left on disk even on abnormal exit), both spools resident at once, peaking at the decoded size of both inputs (about 315 MB — 161 + 154 MB uncompressed Arrow IPC — for the 1M-row fixture pair; on the order of 10 GB for the full 5 GB-per-side fixture pair, which on Linux may be a RAM-backedtmpfs), a full temp filesystem raisingValueErrornamingTMPDIR. None of these has a built-in cap: for untrusted input, bound the row count, the changed fraction, and the column widths (key columns for duplicate-heavy data, changed cells — rendered in full — for wide value columns). Figures are the peak resident set ofcargo run -p onix-arrow --release --example row_diff_rss, single run, macOS on an Apple M-series laptop, 2026-09-05, same method as Performance. Seecrates/onix-arrow/src/row_diff.rs.diff_tablescompares scalar columns by value (hashed: null, booleans, every integer, float and decimal width, strings and binary in every encoding, timestamps, dates, times, durations, intervals, and dictionaries of these; refused withValueError: run-end encoded columns and any type-and-unit combination Arrow itself cannot build; nested non-key columns skipped, nested key columns refused), with the exact enumeration in the module doc ofcrates/onix-arrow/src/row_diff.rs. It also refuses a key column whose type differs across the two inputs after encoding normalization (the conservative choice: a primary key that changed type is refused rather than guessed, not coerced). A row whose only difference is a lossless type change — anInt32widened toInt64, a timestamp unit change at the same instant — hashes equal on both sides, so it is in neitherrows_changednorcells_changed; the column's type change is still reported inschema.- Output is byte-identical to DeepDiff except for the cases listed above and two path-rendering quirks;
tests/golden/README.mdenumerates every accepted exception, including integers past2^53(the limit of exactf64representation) inside ordered scalar lists andignore_orderpairing among naive datetimes, which DeepDiff ranks using the process's local timezone while onix reads a naive value as UTC everywhere.
Contributing
Issues and pull requests are welcome. Open an issue to report a bug, a DeepDiff divergence (include both inputs and the report each engine produces), or a question. Building from source, the quality gates, the golden corpus, benchmarking, mutation testing, and publishing are all in CONTRIBUTING.md.
License
MIT: see LICENSE.
onix reimplements algorithms from CPython's difflib (PSF License) and
reproduces the behavior of DeepDiff (MIT); their notices and license texts are
in THIRD-PARTY-NOTICES.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file deepdiff_rs-0.8.1.tar.gz.
File metadata
- Download URL: deepdiff_rs-0.8.1.tar.gz
- Upload date:
- Size: 400.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a3e9510b590cd8a8f946e8df35b0bd2042a40a4a72a4aded6b44a9b86d8eadb
|
|
| MD5 |
399ceac8d24c0bc18ba6d76073a20c9e
|
|
| BLAKE2b-256 |
428a84d8562b907c652784ece922f91d7a9164ae4a4436d0bf2ca839cb87e376
|
Provenance
The following attestation bundles were made for deepdiff_rs-0.8.1.tar.gz:
Publisher:
publish.yml on ksco92/onix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deepdiff_rs-0.8.1.tar.gz -
Subject digest:
2a3e9510b590cd8a8f946e8df35b0bd2042a40a4a72a4aded6b44a9b86d8eadb - Sigstore transparency entry: 2729121065
- Sigstore integration time:
-
Permalink:
ksco92/onix@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ksco92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Trigger Event:
push
-
Statement type:
File details
Details for the file deepdiff_rs-0.8.1-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: deepdiff_rs-0.8.1-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
023744265032d8824739dcd9dd7ff00dd27603c9e2965f27c88314cd64a12424
|
|
| MD5 |
b94a0e0dee183f07c607991635ccd560
|
|
| BLAKE2b-256 |
54ea546372305bce3d7038db602c9880e20ad7e23e1bb388b5748c134fa5c545
|
Provenance
The following attestation bundles were made for deepdiff_rs-0.8.1-cp39-abi3-win_amd64.whl:
Publisher:
publish.yml on ksco92/onix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deepdiff_rs-0.8.1-cp39-abi3-win_amd64.whl -
Subject digest:
023744265032d8824739dcd9dd7ff00dd27603c9e2965f27c88314cd64a12424 - Sigstore transparency entry: 2729121313
- Sigstore integration time:
-
Permalink:
ksco92/onix@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ksco92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Trigger Event:
push
-
Statement type:
File details
Details for the file deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.9+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
89a91ada0473c79efba37f26b19c0830c261e71067d66a0dea6f9fc9575f8718
|
|
| MD5 |
cf388eeb03c62d1f30e3f8395daef237
|
|
| BLAKE2b-256 |
64d698a8a5c171f1b330d098993815810779744c13c24a426554b86318e7d1e3
|
Provenance
The following attestation bundles were made for deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on ksco92/onix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
89a91ada0473c79efba37f26b19c0830c261e71067d66a0dea6f9fc9575f8718 - Sigstore transparency entry: 2729122970
- Sigstore integration time:
-
Permalink:
ksco92/onix@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ksco92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Trigger Event:
push
-
Statement type:
File details
Details for the file deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.2 MB
- Tags: CPython 3.9+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ceab4af9a87f7bfa21b81f13a80307edba93da1df366ab66f91d3e4526b9d2a7
|
|
| MD5 |
7a0298089b8bcfefafd0854e2f897f50
|
|
| BLAKE2b-256 |
cd8405a2805a08304ced88681f0ae2e29dca55214be687861a33a86f0ff91c68
|
Provenance
The following attestation bundles were made for deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_aarch64.whl:
Publisher:
publish.yml on ksco92/onix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deepdiff_rs-0.8.1-cp39-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
ceab4af9a87f7bfa21b81f13a80307edba93da1df366ab66f91d3e4526b9d2a7 - Sigstore transparency entry: 2729121795
- Sigstore integration time:
-
Permalink:
ksco92/onix@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ksco92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Trigger Event:
push
-
Statement type:
File details
Details for the file deepdiff_rs-0.8.1-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: deepdiff_rs-0.8.1-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.0 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc46acfe703498da1d157597952f36028beab85685207ca07afe330803efd611
|
|
| MD5 |
1f605de34ccf4853c98d1d7a9bc022ef
|
|
| BLAKE2b-256 |
be28cd907f97b0acc8407b9729944d0bc5b00ce4b7c2058c618eed3ad5a718a8
|
Provenance
The following attestation bundles were made for deepdiff_rs-0.8.1-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
publish.yml on ksco92/onix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deepdiff_rs-0.8.1-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
dc46acfe703498da1d157597952f36028beab85685207ca07afe330803efd611 - Sigstore transparency entry: 2729122323
- Sigstore integration time:
-
Permalink:
ksco92/onix@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ksco92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Trigger Event:
push
-
Statement type:
File details
Details for the file deepdiff_rs-0.8.1-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: deepdiff_rs-0.8.1-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 3.3 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c77d8991d3587ff3c38be80c02073451ce3d874c4c9049e8587bdb50808d432e
|
|
| MD5 |
642ac85c3f6315834db9a9506f6cf620
|
|
| BLAKE2b-256 |
55e698b82d255e39e8fc133647b1a57b94729857e61af9a55b4b285633280430
|
Provenance
The following attestation bundles were made for deepdiff_rs-0.8.1-cp39-abi3-macosx_10_12_x86_64.whl:
Publisher:
publish.yml on ksco92/onix
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
deepdiff_rs-0.8.1-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
c77d8991d3587ff3c38be80c02073451ce3d874c4c9049e8587bdb50808d432e - Sigstore transparency entry: 2729123298
- Sigstore integration time:
-
Permalink:
ksco92/onix@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ksco92
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f4e7fb8e5f5fe19bea9b55a000f0c5aaee7dd979 -
Trigger Event:
push
-
Statement type: