Skip to content

Fix: zipp/glob.py's Translator.translate_core() translated a non-trailing... - #161

Open
M001N wants to merge 1 commit into
jaraco:mainfrom
M001N:oss-engine/05e96a03-5b87db57
Open

Fix: zipp/glob.py's Translator.translate_core() translated a non-trailing...#161
M001N wants to merge 1 commit into
jaraco:mainfrom
M001N:oss-engine/05e96a03-5b87db57

Conversation

@M001N

@M001N M001N commented Aug 17, 2026

Copy link
Copy Markdown

Summary

Added Translator.mark_any_dirs(), which replaces each non-trailing '' + separator occurrence with a sentinel ('\x00') before the rest of the pattern is translated (so the sentinel survives star_not_empty/separate/replace untouched). translate_core() then expands the sentinel into '(?:.*[/])?', an optional non-capturing group matching zero or more path segments. A trailing bare '' is left alone since it already becomes '.*', which matches zero or more of anything including directories.

Problem

jaraco/zipp issue reference: #102

Root Cause

zipp/glob.py's Translator.translate_core() translated a non-trailing '/' segment via star_not_empty + separate + replace, turning '' into '.*' and leaving the following '/' as a literal required separator -- requiring at least one directory level. This didn't match stdlib glob/pathlib (3.13+) semantics, where a non-trailing '**' segment must optionally match zero directory levels too.

Testing

PASS - all 5 standalone tests pass (parametrized over **, **/, **/.txt, *.txt, plus a direct root-file regression check) and all 5 doctests in zipp/glob.py pass.

Related Issue

#102

zipp.Path.glob('**/*.txt') previously required at least one directory
level for a non-trailing '**' segment, so root-level files were never
matched -- inconsistent with the stdlib glob module and with
pathlib.Path.glob on Python 3.13+, both of which document '**' as
matching zero or more directories.

Translator.mark_any_dirs() now replaces each non-trailing '**/' segment
(one followed by a separator and more pattern) with a sentinel before
the rest of translate_core''s per-segment translation runs, then expands
the sentinel afterwards into an optional (?:.*[/])? alternative. A
trailing bare '**' is left as-is; it already translates to '.*', which
matches zero or more of anything.

Adds tests/test_glob_standalone.py, a self-contained pytest module that
compares zipp.Path.glob() against pathlib.Path.glob() (real tmp_path)
for **, **/*, **/*.txt, and *.txt over a root file + nested dir layout.
It is standalone (only zipp/zipfile/pathlib/io) because
tests/test_path.py's fixtures depend on tests/compat/py39.py ->
jaraco.test.cpython.from_test_support -> the stdlib's private
test.support package, which is not importable in this environment
(confirmed ModuleNotFoundError, unrelated to this change).
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.

1 participant