Repository navigation
fix(storage): yield only direct children from FsspecStore.list_dir - #4402
Merged
d-v-b merged 5 commits intoSep 24, 2026
Merged
Conversation
An HTTP listing is scraped from the links on an HTML index page. A link to
the site root ("/") becomes a self-link that list_dir reduced to "", so a
group listed itself as a member named "". In-page anchors ("#usage") became
keys whose metadata fetch returned the HTML page, and directories carried a
trailing "/".
list_dir now skips http(s) entries with a fragment or query, strips the
trailing "/", drops empty or nested names, and yields each name once.
Closes zarr-developers#3575
Assisted-by: ClaudeCode:claude-opus-5-5
Assisted-by: ClaudeCode:claude-opus-5-5
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4402 +/- ##
=======================================
Coverage 94.35% 94.36%
=======================================
Files 93 93
Lines 13131 13142 +11
=======================================
+ Hits 12390 12401 +11
Misses 741 741
🚀 New features to boost your workflow:
|
The "#"/"?" check ran on the whole URL, so a store rooted at a URL containing either character would list nothing. It now runs on the name left after stripping the prefix. HTTP names are also normalized with posixpath.normpath, so "./a" lists as "a" and "./" no longer lists as ".". Assisted-by: ClaudeCode:claude-opus-5-5
d-v-b
marked this pull request as ready for review
September 24, 2026 15:44
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.
AI PR that ensures that
FspecStore.list_dirdoesn't return garbage for http stores🤖 AI text below 🤖
Closes #3575.
Problem
Over HTTP, fsspec builds a directory listing by scraping the links on an HTML index page. Some of those links aren't children of the directory, and
FsspecStore.list_dirpassed them through as keys:href="/") is treated by fsspec as relative and joined onto the directory URL, producing the directory itself.list_dirstripped that down to"", andGroup.getitem("")resolves to the group itself, so the group listed itself as a member named"". This is the bug reported in Zarr over https returns an empty string inkeys()#3575.href="#usage") became keys like#usage. Fetching metadata under such a key drops the fragment and returns the HTML page, so on the ECMWF dataset from the issue, whose page has since gained anchor links,keys()now raisesJSONDecodeError./(count/), contrary to theStore.list_dircontract.Fix
list_dirnow:http(s)://entries that contain#or?, since they name the index page rather than an object (other filesystems are unaffected, so a key containing#on S3 or local disk is still listed);/;/;The fsspec behaviour that turns
href="/"into a self-link is arguably an fsspec bug too, but zarr shouldn't depend on it being fixed.Test
test_list_dir_http_yields_only_childrenserves an index page from a localhttp.serverwith links/,../,#,#usage,?sort=name,a/,a,b,/group/c/, and checks thatlist_dir("")returns exactlya,b,c. It fails onmainwith['', '#', '#usage', 'a', 'a/', ...].🤖 Generated with Claude Code