Skip to content

fix: filter_prefixes regex grouping + guard filt_iter's added __len__ - #105

Merged
thorwhalen merged 1 commit into
masterfrom
fix-82-prefix-regex-and-len-guard
Sep 22, 2026
Merged

thorwhalen merged 1 commit into
masterfrom
fix-82-prefix-regex-and-len-guard

Conversation

@thorwhalen

Copy link
Copy Markdown
Member

Summary

Fixes two of the three "related, same area" bugs reported in #82 (the main prefix-relativization corruption bug -- unguarded slicing on mk_relative_path_store/KeyCodecs.prefixed/prefixless_view -- is a larger design question left open; see comment on #82).

  1. filter_prefixes regex grouping: "^" + "|".join(map(re.escape, prefixes)) compiled to e.g. ^logs/|tmp/ for ['logs/', 'tmp/'], which regex parses as (^logs/)|(tmp/) -- so 'zzz/tmp/c' incorrectly matched (only the first prefix was actually anchored to string-start). Grouped as ^(?:...), matching how filter_suffixes right above it already groups its own alternation.
  2. _filt_iter's unconditional __len__: guarded with hasattr(store_cls, "__len__") before adding a counting __len__, so a class that deliberately omits __len__ stays that way when wrapped.

Review

Independent sub-agent review (per crowsnest policy) confirmed both fixes correct with no regressions, and found no other instance of the ungrouped-alternation bug elsewhere in the codebase. It also found that fix #2 is currently a no-op on every path reachable through the public filt_iter() API -- Store (the hardcoded default wrapper) already provides Collection's own __len__ before _filt_iter runs, and filt_iter doesn't expose a wrapper= parameter to override that. So today it's inert but correct/defensive for any future or private caller of _wrap_store/_filt_iter with a custom wrapper. Keeping it since it's harmless and matches the issue's explicit ask.

Test plan

  • pytest --doctest-modules dol/trans.py -> 47 passed
  • pytest (full suite) -> 592 passed, 3 skipped

🤖 Generated with Claude Code

https://claude.ai/code/session_011HSBVhDjRU4apSLcRkavv9

…en__

Two of the three "related, same area" bugs from #82 (the main
prefix-relativization corruption bug is a larger design question, left
open -- see issue comment):

- dol.trans.filter_prefixes built an unanchored/ungrouped regex
  ("^" + "|".join(...)) which for multiple prefixes like ['logs/',
  'tmp/'] compiled to `^logs/|tmp/`, parsed as `(^logs/)|(tmp/)` --
  so a string merely *containing* a later prefix anywhere (e.g.
  'zzz/tmp/c') incorrectly matched. Grouped as `^(?:...)` to fix,
  matching how filter_suffixes already groups its own alternation.

- dol.trans._filt_iter unconditionally added a counting __len__ to
  any wrapped class, even one that deliberately omits __len__.
  Now guarded with hasattr. Verified (and confirmed by independent
  review) this guard is currently a no-op on every path reachable
  through the public filt_iter() API, since the default wrapper=Store
  already provides Collection's own __len__ before _filt_iter runs,
  and filt_iter doesn't expose a wrapper= parameter -- so it's inert
  today but correct/defensive for any future or private caller of
  _wrap_store/_filt_iter with a custom wrapper.

Reviewed by an independent sub-agent before merge (per crowsnest
policy): confirmed both fixes correct, no regressions, found no other
instance of the ungrouped-alternation bug elsewhere in the codebase.

Refs #82 (partial)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@thorwhalen
thorwhalen merged commit f4eeed6 into master Sep 22, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the fix-82-prefix-regex-and-len-guard branch September 22, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kv_walk: docs, tests, tools, and recipes

1 participant