Skip to content

Stop collapsing three-character drive-relative paths to the drive root - #2143

Merged
martindurant merged 1 commit into
fsspec:masterfrom
itzzdev09:fix/make-path-posix-drive-root
Sep 14, 2026
Merged

Stop collapsing three-character drive-relative paths to the drive root#2143
martindurant merged 1 commit into
fsspec:masterfrom
itzzdev09:fix/make-path-posix-drive-root

Conversation

@itzzdev09

Copy link
Copy Markdown
Contributor

Problem

On Windows, make_path_posix turns a three-character drive-relative path into the drive root, dropping the name:

>>> from fsspec.implementations.local import make_path_posix
>>> make_path_posix("C:x")
'C:/'            # a different, real location; "x" is gone
>>> make_path_posix("C:xy")
'C:xy'           # a longer drive-relative path keeps its name
>>> make_path_posix("C:.")
'C:/'

C:x names x relative to the current directory on drive C (ntpath.abspath("C:x") resolves it that way). Returning C:/ is worse than leaving the path alone: it looks absolute and valid, so a call like fs.rm("C:x") or fs.ls("D:a") quietly operates on the drive root instead of failing or using the intended path.

Cause

if path[1:2] == ":":
    if len(path) <= 3:
        # nt root (something like c:/)
        return path[0] + ":/"

The length check is meant for the roots c:, c:/ and c:\, but any three-character path with a colon in second place matches, including c:x, D:a and e:..

Change

Only treat X: and X: followed by / or \ as the root. A three-character drive-relative path now falls through to the same handling as a longer one, so C:x behaves like C:xy.

This deliberately does not make drive-relative paths absolute. test_make_path_posix_returns_absolute_paths already marks "f:foo" as xfail(WIN, reason="unsupported"), and this change leaves that case as it was. It only removes the silent redirect to the root.

Tests

test_make_path_posix_short_drive_relative_path_is_not_the_root, Windows-only, for c:x, D:a and e:.. All three fail against master and pass with the change.

test_local.py: 160 passed, 4 skipped, 8 xfailed — the existing root cases (C:\, e:) still resolve to the root, and the f:foo xfail is unchanged, with no unexpected passes.

ruff 0.14.3 (the pre-commit pin), ruff format and codespell are clean.

🤖 Generated with Claude Code

make_path_posix treated any Windows path of length 3 or less with a
colon in second place as a drive root. That covers "c:", "c:/" and
"c:\", but also "c:x", which names "x" relative to drive c. Those
paths came back as "c:/", silently pointing at a different, real
location and dropping the name, while a longer drive-relative path
such as "c:xy" is returned unchanged.

Only treat "X:" and "X:" followed by a separator as the root, so a
short drive-relative path is handled like a longer one. Making
drive-relative paths absolute stays out of scope; test_local already
marks that case as unsupported.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@martindurant
martindurant merged commit 2f7dc0c into fsspec:master Sep 14, 2026
11 checks passed
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.

2 participants