Initial draft#2
Merged
Merged
Conversation
…Replace assert-based guards in Editor.original/document with\n explicit RuntimeError raises (survives python -O)\n- Remove useless return None in Editor.__exit__\n- Fix Union[str, int] -> str | int (UP007)\n- Remove empty TYPE_CHECKING blocks\n- Fix unused imports in test files\n- Fix ambiguous variable names and list-comprehension-as-index patterns\n- Narrow pytest.raises(Exception) to pytest.raises(KeyError)\n- Combine nested with statements (SIM117)\n- Add todo tickets for 20 identified codebase issues
…_(\"typing\").TYPE_CHECKING hack with standard\n pattern in editor.py\n- Remove empty TYPE_CHECKING block in __init__.py\n- Delete resolved todo tickets (006, 018, 019)\n- Add todo ticket 021 (README)
…ublic methods in Document and Editor\n- Move test-local imports to top-level (PLC0415)\n- Fix multi-statement pytest.raises blocks (PT012)\n- Fix string literal exceptions (EM101)\n- Delete resolved todo tickets (007, 008)
…valid_raises was a pass stub. Now tests that\n_core.Document raises ValueError on malformed YAML input.
…al in (None, {}, [])` with explicit\n`parent_val is None or parent_val in ({}, [])` to separate\nidentity check from equality checks.
…same _core.Route across existence check and operation\nin __getitem__, query, and replace instead of building it twice.
…hould support equality comparison\nand hashing based on source text. Adds tests for equality,\ninequality, cross-type comparison, and set deduplication.
…fusing PyO3 downcast error with a clear TypeError:\n\"updates must be a dict, got <type>\".
… converted to YAML sequences, matching\nthe existing list behavior. Previously raised TypeError.
…e awkward (\"name\",) in doc with \"name\" in doc.\nBoth forms work, but bare strings are more Pythonic and\nestablish the canonical usage pattern.
…utes since they are class-level,\nnot instance-level. Add __eq__, __int__, __repr__ method\nsignatures that PyO3 provides at runtime.
…Component, Route, and Feature are now\nhashable and support equality comparison. This allows them to\nbe used in sets and as dict keys.
…lls now go through _apply() which\nconverts RuntimeError to PatchError. query_exact KeyError is\nwrapped as QueryError, and parse_value ValueError/KeyError\nis wrapped as QueryError. Users never see raw Rust exceptions\nthrough the public Python API.
… build all patches upfront and apply them in a\nsingle apply_patches call instead of looping with one patch per\niteration. This avoids O(n) full reparses for n items.
…s now a method on PyDocument that reuses the\nalready-parsed tree-sitter tree. The standalone function\nremains as a convenience wrapper. Document.__getitem__ now\ncalls self._core_doc.parse_value(route) instead of the\nstandalone _core.parse_value(source, route).
… installation, quick start, full API overview (Document,\nEditor, error hierarchy), known limitations (multi-document,\ntags, anchors), and development setup.
Construct the Document before assigning any instance fields so that a ParseError leaves the Editor in a clean state for potential reuse.
All yamltrip exceptions now suppress the Rust RuntimeError cause chain with 'from None' for clean user-facing tracebacks. The _apply_patches method was the only inconsistent site using 'from e'.
Assertions are stripped with python -O. Use if/raise TypeError instead for the str type narrowing after _check_no_int_keys_for_creation.
Deduplicate the ancestor-based and root-level creation paths by extracting the shared nested value construction and patching logic into a _create_at method. Reduces upsert from 40+ lines to ~15.
Files with non-UTF-8 content now raise ParseError instead of a bare UnicodeDecodeError, so callers can catch all yamltrip errors uniformly via YAMLTripError.
Expose the operation type as a string ('replace', 'add', 'remove',
'append', 'merge_into') so Op instances can be inspected from Python
without parsing repr strings.
A tuple like (3.14,) passed _normalize_keys unchecked, then crashed with an opaque Rust TypeError. Now each element is validated to be str or int, giving a clear Python-side TypeError.
The previous contract had only one layer (errors) and ignored both document and editor, checking nothing. Define proper layers matching the actual dependency direction. Ignore the unavoidable document -> yamltrip __init__ transitive import (Python loads parent __init__ for any submodule import).
Test Location, FeatureKind, Component, and Route conversions to yamlpath types. These are pure Rust tests that don't require the Python GIL.
The old formula (span.0 - nl - 1) calculated bytes from the newline character, not from the line start. Use (nl + 1) as the line start position for a correct column offset. Add comments documenting why serde re-parsing is architecturally necessary.
Add TODO comment noting the dependency is deprecated and should be migrated to serde_yml once yamlpatch drops its serde_yaml dependency.
…dd, repr, and guard properties
…emove double-parse - Add cross-reference comments between duplicated patch-application sites (#2) - Add 9 tests for parse_value dedent logic on block scalars (#3) - Change Any -> object on __getitem__/__contains__/__setitem__ signatures (#4) - Document empty-tuple root access behavior on Document (#5) - Document TOCTOU best-effort nature of Editor.__exit__ (#6) - Remove redundant double-parse in Editor.__enter__ (#7)
- load -> mutate -> dump -> reload round-trips - Editor context manager end-to-end (success, exception, multi-op)
- Use __new__ instead of __init__ for PyO3 constructors - Add @Final to non-subclassable classes - Make __eq__ parameters positional-only - Add __all__, Component.Key/Index nested classes with properties - Add stubtest as a pytest test (with mypy in test deps)
Use source.get(start..end) instead of source[start..end] to avoid a Rust panic when byte offsets land inside a multi-byte UTF-8 codepoint. Returns a clean ValueError instead of crashing the process. Includes a regression test with a cross-document Feature on emoji YAML.
parse_value() byte spans come from tree-sitter on the same document, so mid-codepoint slicing is not exploitable via the public API. Keep idiomatic Rust panicking slices (the contract is that tree-sitter produces char-aligned spans). Add tests for multi-byte UTF-8 keys, values, nested paths, and multiline dedenting.
Add undocumented constraints: UTF-8 only, non-finite float rejection, integer key creation restriction, i64 integer range, no negative indices, non-atomic Editor write-back, and line ending preservation.
- py_to_yaml_value: fall back to u64 extraction when i64 overflows, so large unsigned integers (i64::MAX+1 .. u64::MAX) round-trip correctly - Route::new: detect negative integers explicitly and raise ValueError instead of a misleading TypeError claiming the value is not an int
- python-test.yml: pytest across Python 3.10-3.14 on ubuntu/macos/windows - rust-test.yml: cargo test on stable + beta (beta is informational) - static-checks.yml: prek, cargo fmt, cargo clippy - release.yml: maturin build + PyPI trusted publishing - zizmor.yml: GitHub Actions security scanning
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
…est compat - rust-test.yml, static-checks.yml: add actions/setup-python so PyO3 can link against libpython during cargo test and clippy - src/*.rs: cargo fmt, replace deprecated PyObject with Py<PyAny>, replace downcast() with cast() - tests/test_stubs.py: conditionally use --ignore-disjoint-bases only when the installed mypy version supports it (fixes min-deps matrix)
PyO3's extension-module feature skips linking against libpython, which is correct for building the .so/.pyd extension but breaks cargo test. Move extension-module behind a Cargo feature flag (enabled by default so maturin builds are unaffected) and use --no-default-features in CI for cargo test and clippy.
…ns, add acknowledgements
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.