Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Unreleased
- Added `**kwargs` to `AzureBlobFileSystem.exists()`
- Populate `AzureBlobFile.version_id` on write when `version_aware` is enabled.
- Fixed issue where unawaitable Credential types were incorrectly awaited (#431)
- Fixed bug where `fs.ls(detail=True)` returned Etag formatted without double quotes.[#544](https://github.com/fsspec/adlfs/pull/544)

2026.2.0
--------
Expand Down
6 changes: 6 additions & 0 deletions adlfs/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,12 @@ async def _details(
for key in FORWARDED_BLOB_PROPERTIES
if content.has_key(key) # NOQA
}

# Normalize etag to always return a string with quotes for consistency
if data.get("etag") and data["etag"] is not None:
Comment thread
wonwuakpa-msft marked this conversation as resolved.
Outdated
etagVal = data["etag"]
Comment thread
wonwuakpa-msft marked this conversation as resolved.
Outdated
if not etagVal.startswith('"') and not etagVal.endswith('"'):
data["etag"] = f'"{etagVal}"'
Comment thread
wonwuakpa-msft marked this conversation as resolved.
Outdated
if self.version_aware:
data.update(
(key, content[key])
Expand Down
25 changes: 25 additions & 0 deletions adlfs/tests/test_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -2571,3 +2571,28 @@ class TestCloseCredential:
async def test_close_credential(self, credential):
file_obj = SimpleNamespace(credential=credential)
await close_credential(file_obj)


def test_etag_normalized_form(storage):
"""
Tests a consistent quoted etag format with ls() and info() calls.
"""
fs = AzureBlobFileSystem(
account_name=storage.account_name,
connection_string=CONN_STR,
)
path = "data/root/a/file.txt"
Comment thread
wonwuakpa-msft marked this conversation as resolved.
# Get etag info from ls(detail = True) and info()
ls_results = fs.ls(path, detail=True, refresh=True)
ls_etag = [f["etag"] for f in ls_results if f["name"] == path][0]

info_etag = fs.info(path, refresh=True)["etag"]

assert info_etag == ls_etag

# Validate both etags are quoted
assert ls_etag.startswith('"') and info_etag.startswith('"')
assert ls_etag.endswith('"') and info_etag.endswith('"')

# Validate etag from info() is not double quoted
assert not info_etag.startswith('""') and not info_etag.endswith('""')
Comment thread
wonwuakpa-msft marked this conversation as resolved.
Outdated
Loading