API Reference
The public API is small: two ways to obtain patches (diff and produce), two ways to apply them (apply and iapply), and serialization helpers. All of these can be imported directly from patchdiff. The Pointer class lives in patchdiff.pointer.
Diffing
patchdiff.diff.diff
Compute the difference between two objects as JSON patch operations.
Recursively compares input and output and returns operations in
both directions. Dicts, lists and sets are compared structurally;
any other value (scalars, but also tuples and frozensets) is treated
as atomic and replaced wholesale when it differs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input
|
Diffable
|
The source object. |
required |
output
|
Diffable
|
The target object. |
required |
ptr
|
Pointer | None
|
Pointer prefix for the emitted operations; used internally
during recursion. Leave as |
None
|
Returns:
| Type | Description |
|---|---|
list[Operation]
|
A tuple |
list[Operation]
|
|
tuple[list[Operation], list[Operation]]
|
again. Each operation is a dict with an |
tuple[list[Operation], list[Operation]]
|
|
tuple[list[Operation], list[Operation]]
|
|
tuple[list[Operation], list[Operation]]
|
add/replace operations. |
Applying patches
patchdiff.apply.apply
patchdiff.apply.iapply
Apply a list of patches to an object, in place.
Patch values are deep-copied as they are written, so mutating the patched object afterwards never writes through into the patch list (and vice versa).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Diffable
|
The object to mutate. |
required |
patches
|
list[Operation]
|
required |
Returns:
| Type | Description |
|---|---|
Diffable
|
The same object, mutated. |
Proxy-based patch generation
patchdiff.produce.produce
Produce a new state by applying mutations, tracking patches along the way.
This is an alternative to the diff() function that uses proxy objects to track mutations in real-time instead of comparing before/after snapshots.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
base
|
Any
|
The base object to mutate (dict, list, or set) |
required |
recipe
|
Callable[[Any], None]
|
A function that receives a proxy-wrapped draft and mutates it |
required |
in_place
|
bool
|
If True, mutate the original object directly (useful for reactive objects like observ). If False (default), operate on a deep copy and leave the original unchanged. |
False
|
Returns:
| Type | Description |
|---|---|
Any
|
A tuple of (result, patches, reverse_patches) where: |
list[Operation]
|
|
list[Operation]
|
|
tuple[Any, list[Operation], list[Operation]]
|
|
Example
base = {"count": 0, "items": []} def increment(draft): ... draft["count"] += 1 ... draft["items"].append("new") result, patches, reverse = produce(base, increment) print(result) {"count": 1, "items": ["new"]} print(patches) [{"op": "replace", "path": "/count", "value": 1}, {"op": "add", "path": "/items/-", "value": "new"}]
Example with in_place=True for reactive objects: >>> from observ import reactive >>> state = reactive({"count": 0}) >>> result, patches, reverse = produce(state, lambda d: d.setitem("count", 5), in_place=True) >>> # state["count"] is now 5, and watchers were triggered
Serialization
patchdiff.serialize.to_json
Serialize a list of operations to a JSON patch (RFC 6902) string.
Pointer paths are rendered as JSON pointer strings; any keyword
arguments (like indent) are forwarded to json.dumps.
patchdiff.serialize.to_str_paths
Return a copy of the operations with each path rendered as a string.
The Pointer objects in the "path"
fields are replaced by their escaped JSON pointer (RFC 6901) string
form; the operations themselves are not mutated.
Pointers
patchdiff.pointer.Pointer
A JSON pointer (RFC 6901): a path into a nested structure.
A pointer is an immutable sequence of reference tokens;
append returns a new pointer
rather than mutating. str() renders the escaped JSON pointer
string form and from_str
parses one back. Unlike strict RFC 6901, tokens can be arbitrary
hashable values (not just strings), so pointers can address set
members and integer list indices directly.
from_str
staticmethod
Parse an escaped JSON pointer string (e.g. "/a/0/b") into a Pointer.
All tokens are parsed as strings; numeric list indices become
string tokens, which evaluate and iapply convert back as
needed.
evaluate
Resolve the pointer against an object.
Returns:
| Type | Description |
|---|---|
Diffable | None
|
A tuple |
Hashable
|
addressed leaf, the leaf's key within that container, and |
Any
|
the leaf's current value — |
tuple[Diffable | None, Hashable, Any]
|
exist yet (the target of an |
tuple[Diffable | None, Hashable, Any]
|
the |
patchdiff.pointer.escape
Encode a reference token for a JSON pointer string (~ → ~0, / → ~1).