v3.1.0: agent-friendly API, test coverage, and tooling refresh#8
Merged
Conversation
Implements the v3.1.0 epic (tbd strif-9nyk). The Windows/macOS CI matrix
bead (strif-dzxb) is intentionally deferred to a separate effort.
API additions (agent/IDE ergonomics):
- atomic_write_text() / atomic_write_bytes(): one-call wrappers around
atomic_output_file() for the common whole-value write case.
- __version__ exposed on the package via importlib.metadata.
- Insertion / Replacement are now NamedTuples with named fields
(offset/text and start/end/text). Runtime-compatible with positional
tuples; see note below on static typing.
- HashAlgorithm Literal type on hash_string()/hash_file() params for
autocomplete; default stays "sha1" (no behavior change).
- Removed the unreachable abbreviate_str/abbreviate_list aliases (they
were never exported from the public package).
Tests (43 total, up from 26):
- New tests/test_atomic_var.py: AtomicVar set/swap/update, copy vs
deepcopy independence, updates() context manager + immutable guard,
truthiness, value_is_immutable, and a real concurrency test (10
threads x 1000 increments) that would fail without the lock.
- hash_file: binary content + >8KB chunked-read path vs hashlib;
unsupported-algorithm error.
- New tests/test_ids.py: new_uid charset/length-bits math; timestamped
uid sorts by creation time.
- atomic_output_file {timestamp} backups don't clobber each other.
- atomic_write_text/bytes round-trip, make_parents, backup.
- Tightened test_string_replace.py: named-field construction, dropped
redundant assert messages (per testing guidelines).
Tooling:
- Bump softprops/action-gh-release v2.6.2 -> v3.0.0 (Node 24 runtime;
clears the Node 20 deprecation warning). SHA-pinned.
- Bump astral-sh/setup-uv v7.6.0 -> v8.1.0 in CI and publish. SHA-pinned.
README:
- Document atomic_write_text/bytes; add "Using strif with LLM Agents"
subsection; note Insertion/Replacement named fields; version banner.
BACKWARD COMPATIBILITY NOTE: The NamedTuple change is fully
runtime-compatible (NamedTuple subclasses tuple, so positional
construction, unpacking, and indexing all still work). However, callers
who statically type a value as list[Insertion]/list[Replacement] and
assign bare tuple literals will now see a type error and should switch
to the named constructors. Removing the abbreviate_* aliases is a
breaking change only for code importing them from the private
strif.strif submodule.
Was writing to a relative tmp/ dir (gitignored, but pollutes cwd and is inconsistent with the other tmp_path-based tests in the same file). Same assertions, cleaner isolation.
From external review of PR #8: - hash_file(): remove the `algorithm not in hashlib.algorithms_available` precheck. It rejected valid hashlib spellings like "SHA1" and "sha-1" (which are NOT in algorithms_available but DO work via hashlib.new), and was inconsistent with hash_string(). hashlib.new() still raises ValueError for genuinely unknown algorithms, so the contract is unchanged for callers. - pyproject.toml: add [tool.hatch.build.targets.sdist] exclude so the published source distribution no longer ships .claude/.tbd/.github/ .copier-answers.yml agent+tooling state. - tests/test_ids.py: make the timestamped-uid test deterministic. Assert the sortable timestamp-prefix format and base36 suffix plus uniqueness, instead of comparing two rapidly-created ids (which could tie on timestamp precision and fall through to the random suffix). - README.md: fix sf.write -> f.write typo in the backup_suffix example. Not changed: kept the abbreviate_str/abbreviate_list removal (maintainer confirmed); will be noted in the v3.1.0 release notes.
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.
Summary
Implements the v3.1.0 epic (tbd
strif-9nyk). All planned beads except the Windows/macOS CI matrix (strif-dzxb, intentionally deferred to a separate effort per request). Tests: 43 total (up from 26), all green; lint clean. Zero runtime dependencies preserved.API additions (agent / IDE ergonomics)
atomic_write_text()/atomic_write_bytes()— one-call wrappers aroundatomic_output_file()for the common "write a whole string/bytes atomically" case (replaces the nested-withboilerplate that's awkward for agents).__version__exposed on the package viaimportlib.metadata(graceful fallback when run from an uninstalled source tree).Insertion/Replacement→NamedTuplewith named fields (offset/text,start/end/text).HashAlgorithmLiteraltype onhash_string()/hash_file()for autocomplete. Default stays"sha1"(no behavior change; changing the default is deferred to a future major).abbreviate_str/abbreviate_listaliases (never exported from the public package).Tests
tests/test_atomic_var.py—AtomicVarhad zero coverage. Covers set/swap/update (returning + in-place), copy vs deepcopy independence,updates()context manager + immutable guard, truthiness,value_is_immutable, and a real concurrency test (10 threads × 1000 increments) that fails without the lock.hash_file— binary content + a >8KB payload to exercise the chunked-read loop (vshashlib); unsupported-algorithm error.tests/test_ids.py—new_uidcharset + length/bits math;new_timestamped_uidsorts by creation time.atomic_output_file—{timestamp}backups don't clobber each other.atomic_write_text/bytes— round-trip,make_parents, backup.test_string_replace.pyto use named constructors and dropped redundant assert messages (per the tbd Python testing guidelines).Tooling
softprops/action-gh-releasev2.6.2 → v3.0.0 (Node 24 runtime — clears the Node 20 deprecation warning seen on the v3.0.2 release; deadline was June 2 2026). SHA-pinned.astral-sh/setup-uvv7.6.0 → v8.1.0 in both CI and publish workflows. SHA-pinned.README
atomic_write_text/bytes; adds a "Using strif with LLM Agents" subsection; notes theInsertion/Replacementnamed fields; updates the version banner (now Python 3.10–3.14).NamedTuplechange is runtime-compatible — positional construction, unpacking, and indexing all still work (NamedTuple subclasses tuple). Static-typing caveat: callers who annotate a value aslist[Insertion]/list[Replacement]and assign bare tuple literals will now get a type-checker error and should switch to the named constructors. (This surfaced in our own tests, which I updated.)abbreviate_*breaks only code importing them from the privatestrif.strifsubmodule (they were never in the publicstrifAPI).Deferred
strif-dzxb: add Windows + macOS to the CI matrix — kept as a separate follow-up since cross-OSos.replacesemantics may surface real (fixable) bugs that shouldn't block this release.Test plan
uv run pytest— 43/43 passuv run python devtools/lint.py— codespell + ruff + basedpyright clean__version__, atomic_write_*, named tuples,HashAlgorithm)v3.1.0to trigger the (now Node 24) publish workflowhttps://claude.ai/code/session_01Td1N9waEtmcArZh5jNBdLH
Generated by Claude Code