Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## 0.4.0

### Features

- Added `Document.insert()` and `Editor.insert()` for inserting an item at a specific position in a sequence. Uses Python `list.insert()` semantics (negative indices count from end, out-of-range clamps).
- Added `Document.get()` and `Editor.get()` for non-raising value access. This returns a default (defaults to `None`) when the path doesn't exist, similar to `dict.get()`.
- Added `Document.sync()` and `Editor.sync()` that diffs the current value at a path against a desired value and applies the minimal set of patches. Supports recursive mapping diffing and `SequenceMatcher`-based list diffing to preserve comments and formatting on unchanged elements.

### Internal

- Introduced `OpInner` enum in Rust to support local ops (like `insert_at`) alongside yamlpatch-delegated operations.
- Extracted `KeyPart` type alias to `_types.py`.

## 0.3.0

### Features
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "yamltrip"
version = "0.3.0"
version = "0.4.0"
edition = "2024"
license = "MIT"

Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ doc["items"] # ["a", "b"]
doc["items", 0] # "a"
("items", 0) in doc # True

doc.get("items", 0) # "a" (returns None if missing)
doc.get("missing", default=42) # 42

doc.replace("items", 0, value="x")
doc.replace("items", value=["x", "y"]) # dicts and lists accepted
doc.add("items", key="c", value=3)
Expand All @@ -73,8 +76,10 @@ doc.upsert("config", value={"debug": True}) # dicts and lists accepted
doc.remove("items", 0)
doc.prune_remove("a", "b", "c") # remove + prune empty parents
doc.append("items", value="c")
doc.insert("items", index=1, value="between") # positional insert
doc.extend_list("items", values=["d", "e"])
doc.remove_from_list("items", values=["a"])
doc.sync("items", value=["a", "new", "b"]) # minimal diff-and-patch

doc.query("items") # Feature with location info
doc.query_pretty("items") # Feature with surrounding context
Expand All @@ -94,7 +99,9 @@ with yamltrip.edit("config.yml") as ed:
ed.replace("version", value="2.0")
ed.upsert("new_key", value="new_value")
ed.remove("old_key")
ed.sync("deps", value={"a": "1.0", "b": "2.0"}) # minimal patching
print(ed["version"]) # "2.0"
print(ed.get("missing")) # None
print(ed.original["version"]) # original value before edits
```

Expand Down Expand Up @@ -131,8 +138,9 @@ All yamltrip errors inherit from `YAMLTripError`:
- **Integer keys cannot create structures.** `upsert()` with integer path
components can update existing sequence entries but cannot create new
intermediate mappings. Only string keys create new mappings.
- **No negative sequence indices.** Python-style negative indexing is not
supported.
- **No negative sequence indices for lookup.** Python-style negative indexing
is not supported for `[]` access or `replace()`/`remove()`. However,
`insert()` accepts negative indices (matching `list.insert()` semantics).
- **Line endings preserved as-is.** No CRLF/LF normalization. Mixed line
endings pass through unchanged.

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ requires = [ "maturin>=1.0,<2.0" ]

[project]
name = "yamltrip"
version = "0.3.0"
version = "0.4.0"
description = "A round-tripping YAML library for Python"
readme = "README.md"
authors = [ { name = "Nathan McDougall", email = "nathan.j.mcdougall@gmail.com" } ]
Expand Down
Loading