48 lines
2.3 KiB
Markdown
48 lines
2.3 KiB
Markdown
# jsonpatch — RFC 6901 JSON Pointer + RFC 6902 JSON Patch (stdlib only)
|
|
|
|
Two files, no third-party imports:
|
|
|
|
| file | role |
|
|
|---|---|
|
|
| `jsonptr_patch.py` | the engine: pointer syntax/eval + the six patch operations + CLI |
|
|
| `test_jsonptr_patch.py` | the verification battery (6 stages, exit code = verdict) |
|
|
| `_vendor_json-patch-tests_*.json` | the official upstream test suite, vendored + sha256-pinned |
|
|
|
|
## What it does
|
|
|
|
* `decode_pointer` / `unescape_token` / `escape_token` / `pointer_to_string` / `resolve`
|
|
implement RFC 6901 §3/§4 (empty pointer = whole document, `~1` → `/`, `~0` → `~`,
|
|
leading-zero array indices rejected, illegal escapes rejected).
|
|
* `apply_patch(doc, patch)` implements RFC 6902 §4 `add`, `remove`, `replace`, `move`,
|
|
`copy`, `test` and returns a **new** document — the caller's document is never mutated.
|
|
* `json_equal` is RFC 6902 `test` equality: `1 == 1.0`, `true != 1`, `null == null`,
|
|
object member order irrelevant, array order significant.
|
|
|
|
Semantics that the official suite forced (they are the interesting part):
|
|
|
|
* `add` **never** creates missing intermediate objects — `add /a/b` against `{}` is an
|
|
error (`spec_tests.json` "A.12. Adding to a Non-existent Target"). A first draft of
|
|
this engine created parents on the fly and passed its own Appendix-A cases; the
|
|
vendored suite caught it.
|
|
* array `add`: index `== len` is legal, `> len` is an error, `-` appends.
|
|
* `move` into a strict descendant of `from` is an error; `move /a → /a` is a no-op.
|
|
* a patch is atomic: if any op fails, nothing is applied.
|
|
|
|
## Run it
|
|
|
|
```sh
|
|
python3 test_jsonptr_patch.py # full battery, incl. mutation teeth (≈15 s)
|
|
python3 test_jsonptr_patch.py --no-teeth # skip stage 6
|
|
python3 jsonptr_patch.py --selftest # engine's own Appendix-A + 6901 cases
|
|
python3 jsonptr_patch.py --doc doc.json --patch patch.json
|
|
```
|
|
|
|
CLI exit codes: `0` success, `1` RFC 6901/6902 error, `2` usage error.
|
|
|
|
## Verification
|
|
|
|
See `EVIDENCE.txt` for the measured numbers and the exact commands that produced them.
|
|
The battery exits non-zero if any of the following regresses: the vendored suite's
|
|
sha256, any of the 108 official cases, the 54 selftest cases, the atomicity/purity
|
|
checks, the seeded fuzz invariants, or if any of the 8 source mutants survives.
|