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.
Files changed (40) hide show
  1. jsonatapy-2.1.7/CHANGELOG.md +133 -0
  2. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/Cargo.lock +3 -3
  3. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/Cargo.toml +1 -1
  4. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/PKG-INFO +24 -55
  5. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/README.md +23 -54
  6. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/pyproject.toml +1 -1
  7. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/python/jsonatapy/__init__.py +133 -22
  8. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/ast_transform.rs +804 -108
  9. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/evaluator.rs +619 -82
  10. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/lib.rs +104 -23
  11. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/parser.rs +100 -1
  12. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/vm.rs +178 -20
  13. jsonatapy-2.1.7/tests/integration_test.rs +1720 -0
  14. jsonatapy-2.1.6/CHANGELOG.md +0 -45
  15. jsonatapy-2.1.6/tests/integration_test.rs +0 -687
  16. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.gitignore +0 -0
  17. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.gitmodules +0 -0
  18. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/.gitignore +0 -0
  19. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/architecture.md +0 -0
  20. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/conventions.md +0 -0
  21. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/core.md +0 -0
  22. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/memory_maintenance.md +0 -0
  23. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/suggested_commands.md +0 -0
  24. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/task_completion.md +0 -0
  25. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/memories/tech_stack.md +0 -0
  26. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/.serena/project.yml +0 -0
  27. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/LICENSE +0 -0
  28. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/benches/evaluator_bench.rs +0 -0
  29. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/examples/evaluator_demo.rs +0 -0
  30. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/examples/parser_demo.rs +0 -0
  31. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/python/jsonatapy/py.typed +0 -0
  32. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/ast.rs +0 -0
  33. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/compiler.rs +0 -0
  34. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/datetime.rs +0 -0
  35. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/functions.rs +0 -0
  36. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/parser/README.md +0 -0
  37. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/signature.rs +0 -0
  38. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/src/value.rs +0 -0
  39. {jsonatapy-2.1.6 → jsonatapy-2.1.7}/tests/datetime_picture_suite.rs +0 -0
  40. {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.18"
258
+ version = "0.9.20"
259
259
  source = "registry+https://github.com/rust-lang/crates.io-index"
260
- checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
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.6"
486
+ version = "2.1.7"
487
487
  dependencies = [
488
488
  "base64",
489
489
  "chrono",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonata-core"
3
- version = "2.1.6"
3
+ version = "2.1.7"
4
4
  edition = "2021"
5
5
  authors = ["txjmb <txjmb@users.noreply.github.com>"]
6
6
  description = "High-performance Rust implementation of JSONata query and transformation language"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jsonatapy
3
- Version: 2.1.6
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
- > Much of this project was built with human guidance using Claude Code. 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.
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
  [![Crates.io](https://img.shields.io/crates/v/jsonata-core.svg)](https://crates.io/crates/jsonata-core)
56
58
  [![PyPI version](https://badge.fury.io/py/jsonatapy.svg)](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.2" # pure Rust, no Python dependency
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.2", default-features = false }
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) # 4–15x faster than evaluate(dict)
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
- | Category | vs JavaScript (V8) | vs jsonata-python |
176
- |----------|--------------------|-------------------|
177
- | Simple paths | **5–8x faster** (array index access: roughly tied) | ~20–40x faster |
178
- | Conditionals | **15x faster** | ~40x faster |
179
- | String operations | **8–15x faster** | ~30–45x faster |
180
- | Complex transformations | **5–15x faster** | ~20–40x faster |
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
- ### The Python boundary
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
- With pre-converted data, realistic workloads (filtering, transforming, aggregating over
199
- 100-object arrays) run **~5–8x faster than V8**, not slower — even the raw `evaluate(dict)`
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.13
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
- > Much of this project was built with human guidance using Claude Code. 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.
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
  [![Crates.io](https://img.shields.io/crates/v/jsonata-core.svg)](https://crates.io/crates/jsonata-core)
11
13
  [![PyPI version](https://badge.fury.io/py/jsonatapy.svg)](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.2" # pure Rust, no Python dependency
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.2", default-features = false }
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) # 4–15x faster than evaluate(dict)
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
- | Category | vs JavaScript (V8) | vs jsonata-python |
131
- |----------|--------------------|-------------------|
132
- | Simple paths | **5–8x faster** (array index access: roughly tied) | ~20–40x faster |
133
- | Conditionals | **15x faster** | ~40x faster |
134
- | String operations | **8–15x faster** | ~30–45x faster |
135
- | Complex transformations | **5–15x faster** | ~20–40x faster |
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
- ### The Python boundary
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
- With pre-converted data, realistic workloads (filtering, transforming, aggregating over
154
- 100-object arrays) run **~5–8x faster than V8**, not slower — even the raw `evaluate(dict)`
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.13
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.6"
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"}