jsonatapy 2.1.6__tar.gz → 2.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jsonatapy-2.1.7/CHANGELOG.md +133 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/Cargo.lock +3 -3
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/Cargo.toml +1 -1
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/PKG-INFO +24 -55
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/README.md +23 -54
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/pyproject.toml +1 -1
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/python/jsonatapy/__init__.py +133 -22
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/ast_transform.rs +804 -108
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/evaluator.rs +619 -82
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/lib.rs +104 -23
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/parser.rs +100 -1
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/vm.rs +178 -20
- jsonatapy-2.1.7/tests/integration_test.rs +1720 -0
- jsonatapy-2.1.6/CHANGELOG.md +0 -45
- jsonatapy-2.1.6/tests/integration_test.rs +0 -687
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.gitignore +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.gitmodules +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/.gitignore +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/architecture.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/conventions.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/core.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/memory_maintenance.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/suggested_commands.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/task_completion.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/tech_stack.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/project.yml +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/LICENSE +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/benches/evaluator_bench.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/examples/evaluator_demo.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/examples/parser_demo.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/python/jsonatapy/py.typed +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/ast.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/compiler.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/datetime.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/functions.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/parser/README.md +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/signature.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/value.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/tests/datetime_picture_suite.rs +0 -0
- {jsonatapy-2.1.6 → jsonatapy-2.1.7}/tests/parent_and_focus_binding_suite.rs +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
### Deprecated
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
### Security
|
|
21
|
+
|
|
22
|
+
## [2.1.7] - 2026-07-08
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Guardrails: `timeout` (ms, error code `D1012`), `max_stack_depth` (error code `D1011`), and
|
|
26
|
+
`max_sequence_length` (error code `D2015`) keyword arguments on `compile()` and every
|
|
27
|
+
`evaluate*()` call, enforced consistently across all three execution engines (tree-walker,
|
|
28
|
+
compiled-expression fast path, bytecode VM). All default to `None` (unlimited) — no behavior
|
|
29
|
+
change unless configured. See [Guardrails](docs/api.md#guardrails). (jsonata-js 2.2.1 Phase 2, #56)
|
|
30
|
+
- Documented the guardrails API in `docs/api.md`, `docs/usage.md`, and `docs/error-handling.md`
|
|
31
|
+
(previously shipped with accurate Python docstrings but no user-facing docs), and corrected
|
|
32
|
+
`docs/migration-from-js.md`'s stale claim that Python had no built-in timeout support.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- A deeply-nested expression (arithmetic chains, parenthesized/grouped expressions) no longer
|
|
36
|
+
crashes the whole process (previously a native stack overflow) — now raises a graceful `U1002`
|
|
37
|
+
error instead, via a depth guard in the parser and a second, defense-in-depth guard in the
|
|
38
|
+
post-parse AST pass.
|
|
39
|
+
- `Instr::MakeArray`/`MakeObject`/`BlockEnd`'s bytecode operands (and `CallBuiltin`'s argument
|
|
40
|
+
count, and internal constant-pool bookkeeping) no longer silently produce wrong, truncated
|
|
41
|
+
results for oversized literals/blocks/calls (e.g. array literals with more than 65,535
|
|
42
|
+
elements) — such cases now fall back to the always-correct tree-walker instead.
|
|
43
|
+
- `ast_transform.rs`'s depth-guard error messages no longer imply `%`/`@`/`#` ancestor-operator
|
|
44
|
+
usage (e.g. "...while resolving ancestor/path metadata") when the guard fires for any
|
|
45
|
+
sufficiently-nested expression, including plain arithmetic.
|
|
46
|
+
- Release workflow now fails loudly on a fresh dispatch when the target version tag already
|
|
47
|
+
exists at a different commit, instead of silently reusing the wrong commit (#53).
|
|
48
|
+
|
|
49
|
+
## [2.1.6] - 2026-07-07
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
- `%` (parent-reference) and `@`/`#` (focus/index binding) operators.
|
|
53
|
+
- jsonata-js 2.2.1 Phase 1: signature engine rewrite adding `+`/`-` arity support (#36).
|
|
54
|
+
- Versioned documentation via `mike`, fixing a gh-pages deploy race (#39).
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
- Reference test-suite coverage gaps: loader fix, datetime picture-strings,
|
|
58
|
+
`formatInteger`/`parseInteger` (Phases 0-2), and array-constructor/`distinct` stragglers
|
|
59
|
+
(Phase 5, #44).
|
|
60
|
+
- `release.yml` never actually built macOS wheels, due to a broken `actions/setup-python`
|
|
61
|
+
invocation (#41).
|
|
62
|
+
- Several benchmark accuracy/fairness corrections (await `jsonata-js` calls properly, substantiate
|
|
63
|
+
pre-converted-data speedup claims, use clean CI-sourced numbers, use jsonata-python's `Context`
|
|
64
|
+
for fair repeated-eval timing) (#45, #46, #49, #50).
|
|
65
|
+
|
|
66
|
+
### Changed
|
|
67
|
+
- macOS temporarily dropped from the main release matrix pending a self-hosted runner fix (#45,
|
|
68
|
+
#47) — later restored via a self-hosted Mac Mini runner.
|
|
69
|
+
|
|
70
|
+
## [2.1.5] - 2026-07-04
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
- Native stack overflow on deep recursion — replaced with a graceful, coded error (fixes #34).
|
|
74
|
+
- Lambda IDs are now generated from a monotonic counter instead of an AST pointer address, fixing
|
|
75
|
+
a ~0.5%-frequency wrong-closure bug from id aliasing across recursive/repeated evaluation
|
|
76
|
+
(fixes #35).
|
|
77
|
+
- Tree-walker missing-path/field access now correctly produces `Undefined` instead of `Null` in
|
|
78
|
+
the ~20 sites that predated the `Null`/`Undefined` distinction (fixes #32).
|
|
79
|
+
- CI repairs following the default-branch rename to `main`; patched `RUSTSEC-2026-0097`.
|
|
80
|
+
|
|
81
|
+
### Changed
|
|
82
|
+
- Bumped `pyo3` to 0.29 and `rand` to 0.10.
|
|
83
|
+
|
|
84
|
+
## [2.1.4] - 2026-03-22
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
- `cargo publish` step in the release workflow.
|
|
88
|
+
|
|
89
|
+
### Fixed
|
|
90
|
+
- Release workflow is now idempotent for version-bump and tag-creation steps.
|
|
91
|
+
- Corrected an incorrect expected value in the `substring` test suite.
|
|
92
|
+
|
|
93
|
+
## [2.1.3] - 2026-03-22
|
|
94
|
+
|
|
95
|
+
> Versions 2.1.1 and 2.1.2 were bumped internally but never published as standalone tagged
|
|
96
|
+
> releases — their changes are folded into this entry, the next version actually released.
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
- Bytecode VM (`compiler.rs` + `vm.rs`, "Phase 4") restored and wired into the Python execution
|
|
100
|
+
path, with Criterion benchmarks comparing it against the tree-walker.
|
|
101
|
+
- `pyo3` made an optional dependency; Rust crate renamed to `jsonata-core` and published to
|
|
102
|
+
crates.io independently of the `jsonatapy` PyPI package.
|
|
103
|
+
|
|
104
|
+
### Fixed
|
|
105
|
+
- PyO3 0.28 compatibility (`PyObject` → `Py<PyAny>`).
|
|
106
|
+
- Clippy deprecations and `cargo-deny` license-check failures.
|
|
107
|
+
- Upgraded Pillow (dev/docs dependency) to 12.1.1 for a CVE fix.
|
|
108
|
+
|
|
109
|
+
### Changed
|
|
110
|
+
- Multiple benchmark documentation and accuracy corrections.
|
|
111
|
+
|
|
112
|
+
## [2.1.0] - 2026-02-08
|
|
113
|
+
|
|
114
|
+
### Added
|
|
115
|
+
- Initial public release: Rust-based JSONata implementation targeting jsonata-js v2.1.0 semantics.
|
|
116
|
+
- Full jsonata-js v2.1.0 reference test-suite compatibility.
|
|
117
|
+
- Python bindings (PyO3), published as `jsonatapy` on PyPI.
|
|
118
|
+
- Rust core, published as `jsonata-core` on crates.io.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Reference Implementation Tracking
|
|
123
|
+
|
|
124
|
+
This project tracks the [jsonata-js](https://github.com/jsonata-js/jsonata) reference implementation.
|
|
125
|
+
|
|
126
|
+
**Current status:** Full test-suite compatibility with jsonata-js v2.1.0 (+3 commits). jsonata-js
|
|
127
|
+
v2.2.1 compatibility work is in progress — Phase 1 (signature engine, `+`/`-` arity support) and
|
|
128
|
+
Phase 2 (resource guardrails) are done; see
|
|
129
|
+
`docs/superpowers/specs/2026-07-04-jsonata-2.2.1-design.md` for the authoritative, up-to-date
|
|
130
|
+
status of this effort.
|
|
131
|
+
|
|
132
|
+
### Version History
|
|
133
|
+
- Target tracking v2.1.0 - Project initialization (2025-01-17)
|
|
@@ -255,9 +255,9 @@ dependencies = [
|
|
|
255
255
|
|
|
256
256
|
[[package]]
|
|
257
257
|
name = "crossbeam-epoch"
|
|
258
|
-
version = "0.9.
|
|
258
|
+
version = "0.9.20"
|
|
259
259
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
260
|
-
checksum = "
|
|
260
|
+
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
|
|
261
261
|
dependencies = [
|
|
262
262
|
"crossbeam-utils",
|
|
263
263
|
]
|
|
@@ -483,7 +483,7 @@ dependencies = [
|
|
|
483
483
|
|
|
484
484
|
[[package]]
|
|
485
485
|
name = "jsonata-core"
|
|
486
|
-
version = "2.1.
|
|
486
|
+
version = "2.1.7"
|
|
487
487
|
dependencies = [
|
|
488
488
|
"base64",
|
|
489
489
|
"chrono",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jsonatapy
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.7
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -47,10 +47,12 @@ Project-URL: Repository, https://github.com/txjmb/jsonata-core
|
|
|
47
47
|
|
|
48
48
|
High-performance [JSONata](https://jsonata.org/) implementation in Rust, with Python bindings.
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
Much of this project was built using Claude Code with significant human oversight. There was no performant
|
|
51
|
+
JSONata implementation in Python, so the goal was to port JSONata to Rust (with a PyO3 wrapper
|
|
52
|
+
for Python) and see how fast it could go. The answer: faster than V8 for most expression
|
|
53
|
+
workloads, and faster than the next pure-Rust implementation.
|
|
54
|
+
|
|
55
|
+
Many, many thanks to the incredible work of all the maintainers of the [JSONata](https://github.com/jsonata-js/jsonata) reference library. JSONata is a very powerful, well-designed, and useful language that has made an impact on many projects. This project leverages their outstanding work to extend that capability to Python and Rust and would not be possible without that project. The implementation in Rust was strongly influenced by their implementation. The 1600+ tests they created provided the scaffolding and validation for all of this project. This project will continue to follow and be a derivative of the reference project as the JSONata reference library evolves.
|
|
54
56
|
|
|
55
57
|
[](https://crates.io/crates/jsonata-core)
|
|
56
58
|
[](https://pypi.org/project/jsonatapy/)
|
|
@@ -91,10 +93,10 @@ let result = Evaluator::new().evaluate(&ast, &data)?;
|
|
|
91
93
|
```toml
|
|
92
94
|
# Cargo.toml
|
|
93
95
|
[dependencies]
|
|
94
|
-
jsonata-core = "2.1.
|
|
96
|
+
jsonata-core = "2.1.6" # pure Rust, no Python dependency
|
|
95
97
|
|
|
96
98
|
# Optional: disable SIMD for constrained targets
|
|
97
|
-
jsonata-core = { version = "2.1.
|
|
99
|
+
jsonata-core = { version = "2.1.6", default-features = false }
|
|
98
100
|
```
|
|
99
101
|
|
|
100
102
|
---
|
|
@@ -124,10 +126,10 @@ print(result) # 2450
|
|
|
124
126
|
|
|
125
127
|
# Pre-convert data once for maximum throughput
|
|
126
128
|
data = jsonatapy.JsonataData(large_dataset)
|
|
127
|
-
result = expr.evaluate_with_data(data) #
|
|
129
|
+
result = expr.evaluate_with_data(data) # 3–15x faster than evaluate(dict)
|
|
128
130
|
```
|
|
129
131
|
|
|
130
|
-
Supports Python 3.10, 3.11, 3.12, 3.13 on Linux, macOS (Intel & ARM), and Windows.
|
|
132
|
+
Supports Python 3.10, 3.11, 3.12, 3.13, 3.14 on Linux, macOS (Intel & ARM), and Windows.
|
|
131
133
|
|
|
132
134
|
---
|
|
133
135
|
|
|
@@ -148,58 +150,25 @@ See [official JSONata docs](https://docs.jsonata.org/) for the full language ref
|
|
|
148
150
|
## Performance
|
|
149
151
|
|
|
150
152
|
`jsonata-core` passes **1682/1682** JSONata reference tests and is the fastest JSONata
|
|
151
|
-
implementation available in either Rust or Python
|
|
152
|
-
|
|
153
|
-
### Pure Rust (Criterion benchmarks, no Python overhead)
|
|
154
|
-
|
|
155
|
-
| Category | jsonata-core | vs jsonata-rs |
|
|
156
|
-
|----------|-------------|----------------|
|
|
157
|
-
| Simple path lookup | 81 ns | ~40x faster |
|
|
158
|
-
| Arithmetic expression | 140 ns | ~40x faster |
|
|
159
|
-
| Conditional | 106 ns | ~30x faster |
|
|
160
|
-
| String operations | 126–284 ns | ~30x faster |
|
|
161
|
-
| $sum (100 elements) | 287 ns | ~70x faster |
|
|
162
|
-
| Filter predicate (100 objects) | 7.9 µs | ~50x faster |
|
|
163
|
-
| Realistic workload (100 products) | 9–44 µs | ~40x faster |
|
|
164
|
-
|
|
165
|
-
Run the benchmarks yourself:
|
|
166
|
-
```bash
|
|
167
|
-
cargo bench --no-default-features --features simd
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Python path (`jsonatapy`)
|
|
171
|
-
|
|
172
|
-
`jsonatapy` is the fastest Python JSONata implementation by a large margin, and faster than
|
|
173
|
-
the JavaScript reference implementation for most pure expression workloads:
|
|
153
|
+
implementation available in either Rust or Python:
|
|
174
154
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
| Higher-order functions | **12–19x faster** | ~50–70x faster |
|
|
182
|
-
| Array-heavy workloads | **~1–3x slower to ~4x faster**, depending on access pattern | ~10–50x faster |
|
|
155
|
+
- **~6x faster on average** than the JavaScript reference implementation (V8), across all
|
|
156
|
+
benchmark categories — up to ~16x for complex transformations and string operations
|
|
157
|
+
- **~40x faster** than jsonata-rs (the next pure-Rust JSONata implementation) on pure-Rust
|
|
158
|
+
Criterion benchmarks with no Python overhead on either side (`cargo bench`)
|
|
159
|
+
- **hundreds of times faster** than jsonata-python, even when it reuses its fastest
|
|
160
|
+
(`Context`-based) repeated-evaluation path
|
|
183
161
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
For large array workloads, the dominant cost is converting Python dicts to Rust values
|
|
187
|
-
on each `evaluate()` call — not expression evaluation itself. Two API paths avoid this:
|
|
162
|
+
For large array workloads, pre-convert data once with `jsonatapy.JsonataData` and reuse it
|
|
163
|
+
across queries — this avoids the Python↔Rust conversion cost that otherwise dominates:
|
|
188
164
|
|
|
189
165
|
```python
|
|
190
|
-
# Path 1: Pre-convert data once, reuse across many queries (4–15x faster than evaluate(dict))
|
|
191
166
|
data = jsonatapy.JsonataData(large_dataset)
|
|
192
|
-
result = expr.evaluate_with_data(data)
|
|
193
|
-
|
|
194
|
-
# Path 2: Data arrives as a raw JSON string — pass it directly
|
|
195
|
-
result_str = expr.evaluate_json(raw_json_string)
|
|
167
|
+
result = expr.evaluate_with_data(data) # 3–15x faster than evaluate(dict)
|
|
196
168
|
```
|
|
197
169
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
path without pre-conversion is roughly at parity with V8 (0.5–2x either direction).
|
|
201
|
-
|
|
202
|
-
See [Performance docs](docs/performance.md) for full benchmark results and methodology.
|
|
170
|
+
See [Performance docs](docs/performance.md) for the full category-by-category breakdown and
|
|
171
|
+
benchmark methodology.
|
|
203
172
|
|
|
204
173
|
---
|
|
205
174
|
|
|
@@ -208,7 +177,7 @@ See [Performance docs](docs/performance.md) for full benchmark results and metho
|
|
|
208
177
|
- **1682/1682 JSONata reference tests passing**
|
|
209
178
|
- **Pure Rust core** — no JavaScript runtime, no Node.js dependency
|
|
210
179
|
- **Optional Python bindings** — PyO3/maturin, zero-copy where possible
|
|
211
|
-
- **Cross-platform** — Linux, macOS (Intel & ARM), Windows; Python 3.10–3.
|
|
180
|
+
- **Cross-platform** — Linux, macOS (Intel & ARM), Windows; Python 3.10–3.14
|
|
212
181
|
- **SIMD-accelerated JSON parsing** — via `simd-json` (optional feature)
|
|
213
182
|
|
|
214
183
|
---
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
High-performance [JSONata](https://jsonata.org/) implementation in Rust, with Python bindings.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Much of this project was built using Claude Code with significant human oversight. There was no performant
|
|
6
|
+
JSONata implementation in Python, so the goal was to port JSONata to Rust (with a PyO3 wrapper
|
|
7
|
+
for Python) and see how fast it could go. The answer: faster than V8 for most expression
|
|
8
|
+
workloads, and faster than the next pure-Rust implementation.
|
|
9
|
+
|
|
10
|
+
Many, many thanks to the incredible work of all the maintainers of the [JSONata](https://github.com/jsonata-js/jsonata) reference library. JSONata is a very powerful, well-designed, and useful language that has made an impact on many projects. This project leverages their outstanding work to extend that capability to Python and Rust and would not be possible without that project. The implementation in Rust was strongly influenced by their implementation. The 1600+ tests they created provided the scaffolding and validation for all of this project. This project will continue to follow and be a derivative of the reference project as the JSONata reference library evolves.
|
|
9
11
|
|
|
10
12
|
[](https://crates.io/crates/jsonata-core)
|
|
11
13
|
[](https://pypi.org/project/jsonatapy/)
|
|
@@ -46,10 +48,10 @@ let result = Evaluator::new().evaluate(&ast, &data)?;
|
|
|
46
48
|
```toml
|
|
47
49
|
# Cargo.toml
|
|
48
50
|
[dependencies]
|
|
49
|
-
jsonata-core = "2.1.
|
|
51
|
+
jsonata-core = "2.1.6" # pure Rust, no Python dependency
|
|
50
52
|
|
|
51
53
|
# Optional: disable SIMD for constrained targets
|
|
52
|
-
jsonata-core = { version = "2.1.
|
|
54
|
+
jsonata-core = { version = "2.1.6", default-features = false }
|
|
53
55
|
```
|
|
54
56
|
|
|
55
57
|
---
|
|
@@ -79,10 +81,10 @@ print(result) # 2450
|
|
|
79
81
|
|
|
80
82
|
# Pre-convert data once for maximum throughput
|
|
81
83
|
data = jsonatapy.JsonataData(large_dataset)
|
|
82
|
-
result = expr.evaluate_with_data(data) #
|
|
84
|
+
result = expr.evaluate_with_data(data) # 3–15x faster than evaluate(dict)
|
|
83
85
|
```
|
|
84
86
|
|
|
85
|
-
Supports Python 3.10, 3.11, 3.12, 3.13 on Linux, macOS (Intel & ARM), and Windows.
|
|
87
|
+
Supports Python 3.10, 3.11, 3.12, 3.13, 3.14 on Linux, macOS (Intel & ARM), and Windows.
|
|
86
88
|
|
|
87
89
|
---
|
|
88
90
|
|
|
@@ -103,58 +105,25 @@ See [official JSONata docs](https://docs.jsonata.org/) for the full language ref
|
|
|
103
105
|
## Performance
|
|
104
106
|
|
|
105
107
|
`jsonata-core` passes **1682/1682** JSONata reference tests and is the fastest JSONata
|
|
106
|
-
implementation available in either Rust or Python
|
|
107
|
-
|
|
108
|
-
### Pure Rust (Criterion benchmarks, no Python overhead)
|
|
109
|
-
|
|
110
|
-
| Category | jsonata-core | vs jsonata-rs |
|
|
111
|
-
|----------|-------------|----------------|
|
|
112
|
-
| Simple path lookup | 81 ns | ~40x faster |
|
|
113
|
-
| Arithmetic expression | 140 ns | ~40x faster |
|
|
114
|
-
| Conditional | 106 ns | ~30x faster |
|
|
115
|
-
| String operations | 126–284 ns | ~30x faster |
|
|
116
|
-
| $sum (100 elements) | 287 ns | ~70x faster |
|
|
117
|
-
| Filter predicate (100 objects) | 7.9 µs | ~50x faster |
|
|
118
|
-
| Realistic workload (100 products) | 9–44 µs | ~40x faster |
|
|
119
|
-
|
|
120
|
-
Run the benchmarks yourself:
|
|
121
|
-
```bash
|
|
122
|
-
cargo bench --no-default-features --features simd
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### Python path (`jsonatapy`)
|
|
126
|
-
|
|
127
|
-
`jsonatapy` is the fastest Python JSONata implementation by a large margin, and faster than
|
|
128
|
-
the JavaScript reference implementation for most pure expression workloads:
|
|
108
|
+
implementation available in either Rust or Python:
|
|
129
109
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
| Higher-order functions | **12–19x faster** | ~50–70x faster |
|
|
137
|
-
| Array-heavy workloads | **~1–3x slower to ~4x faster**, depending on access pattern | ~10–50x faster |
|
|
110
|
+
- **~6x faster on average** than the JavaScript reference implementation (V8), across all
|
|
111
|
+
benchmark categories — up to ~16x for complex transformations and string operations
|
|
112
|
+
- **~40x faster** than jsonata-rs (the next pure-Rust JSONata implementation) on pure-Rust
|
|
113
|
+
Criterion benchmarks with no Python overhead on either side (`cargo bench`)
|
|
114
|
+
- **hundreds of times faster** than jsonata-python, even when it reuses its fastest
|
|
115
|
+
(`Context`-based) repeated-evaluation path
|
|
138
116
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
For large array workloads, the dominant cost is converting Python dicts to Rust values
|
|
142
|
-
on each `evaluate()` call — not expression evaluation itself. Two API paths avoid this:
|
|
117
|
+
For large array workloads, pre-convert data once with `jsonatapy.JsonataData` and reuse it
|
|
118
|
+
across queries — this avoids the Python↔Rust conversion cost that otherwise dominates:
|
|
143
119
|
|
|
144
120
|
```python
|
|
145
|
-
# Path 1: Pre-convert data once, reuse across many queries (4–15x faster than evaluate(dict))
|
|
146
121
|
data = jsonatapy.JsonataData(large_dataset)
|
|
147
|
-
result = expr.evaluate_with_data(data)
|
|
148
|
-
|
|
149
|
-
# Path 2: Data arrives as a raw JSON string — pass it directly
|
|
150
|
-
result_str = expr.evaluate_json(raw_json_string)
|
|
122
|
+
result = expr.evaluate_with_data(data) # 3–15x faster than evaluate(dict)
|
|
151
123
|
```
|
|
152
124
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
path without pre-conversion is roughly at parity with V8 (0.5–2x either direction).
|
|
156
|
-
|
|
157
|
-
See [Performance docs](docs/performance.md) for full benchmark results and methodology.
|
|
125
|
+
See [Performance docs](docs/performance.md) for the full category-by-category breakdown and
|
|
126
|
+
benchmark methodology.
|
|
158
127
|
|
|
159
128
|
---
|
|
160
129
|
|
|
@@ -163,7 +132,7 @@ See [Performance docs](docs/performance.md) for full benchmark results and metho
|
|
|
163
132
|
- **1682/1682 JSONata reference tests passing**
|
|
164
133
|
- **Pure Rust core** — no JavaScript runtime, no Node.js dependency
|
|
165
134
|
- **Optional Python bindings** — PyO3/maturin, zero-copy where possible
|
|
166
|
-
- **Cross-platform** — Linux, macOS (Intel & ARM), Windows; Python 3.10–3.
|
|
135
|
+
- **Cross-platform** — Linux, macOS (Intel & ARM), Windows; Python 3.10–3.14
|
|
167
136
|
- **SIMD-accelerated JSON parsing** — via `simd-json` (optional feature)
|
|
168
137
|
|
|
169
138
|
---
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "jsonatapy"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.7"
|
|
8
8
|
description = "High-performance Python/Rust implementation of JSONata query and transformation language"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "txjmb", email = "txjmb@users.noreply.github.com"}
|