Skip to content

Commit 76d5b55

Browse files
authored
Fix DataPath error handling for unsupported methods (#517)
* upath._flavours: adjust flavour for DataPath * upath.implementations.data: adjust DataPath to fix error handling
1 parent a6fac3d commit 76d5b55

4 files changed

Lines changed: 73 additions & 4 deletions

File tree

dev/fsspec_inspector/generate_flavours.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,15 @@ def _fix_azure_blob_file_system(x: str) -> str:
142142
return x
143143

144144

145+
def _fix_data_file_system(x: str) -> str:
146+
return re.sub(
147+
"sep = '/'",
148+
"sep = '' # type: ignore[assignment]\n "
149+
"altsep = ' ' # type: ignore[assignment]",
150+
x,
151+
)
152+
153+
145154
def _fix_memfs_file_system(x: str) -> str:
146155
return re.sub(
147156
"_MemFS",
@@ -184,6 +193,7 @@ def _fix_xrootd_file_system(x: str) -> str:
184193
FIX_SOURCE = {
185194
"AbstractFileSystem": _fix_abstract_file_system,
186195
"AzureBlobFileSystem": _fix_azure_blob_file_system,
196+
"DataFileSystem": _fix_data_file_system,
187197
"MemFS": _fix_memfs_file_system,
188198
"MemoryFileSystem": _fix_memory_file_system,
189199
"OSSFileSystem": _fix_oss_file_system,

upath/_flavour.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def sep(self) -> str: # type: ignore[override]
274274

275275
@property
276276
def altsep(self) -> str | None: # type: ignore[override]
277-
return None
277+
return getattr(self._spec, "altsep", None)
278278

279279
def isabs(self, path: JoinablePathLike) -> bool:
280280
path = self.strip_protocol(path)

upath/_flavour_sources.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ class DataFileSystemFlavour(AbstractFileSystemFlavour):
341341
__orig_version__ = '2025.10.0'
342342
protocol = ('data',)
343343
root_marker = ''
344-
sep = '/'
344+
sep = "" # type: ignore[assignment]
345+
altsep = " " # type: ignore[assignment]
345346

346347

347348
class DatabricksFileSystemFlavour(AbstractFileSystemFlavour):

upath/implementations/data.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
from __future__ import annotations
22

33
import sys
4+
from collections.abc import Iterator
45
from collections.abc import Sequence
56
from typing import TYPE_CHECKING
7+
from urllib.parse import quote_plus
68

9+
from upath._protocol import get_upath_protocol
710
from upath.core import UnsupportedOperation
811
from upath.core import UPath
912
from upath.types import JoinablePathLike
@@ -45,10 +48,49 @@ def __str__(self) -> str:
4548
return self.parser.join(*self._raw_urlpaths)
4649

4750
def with_segments(self, *pathsegments: JoinablePathLike) -> Self:
48-
raise UnsupportedOperation("path operation not supported by DataPath")
51+
try:
52+
(segment,) = pathsegments
53+
except ValueError:
54+
raise UnsupportedOperation("join not supported by DataPath")
55+
if get_upath_protocol(segment) != "data":
56+
raise ValueError(f"requires a data URI, got: {segment!r}")
57+
return type(self)(segment, protocol="data", **self.storage_options)
58+
59+
@property
60+
def name(self) -> str:
61+
return quote_plus(self.path)
62+
63+
@property
64+
def stem(self) -> str:
65+
return quote_plus(self.path)
66+
67+
@property
68+
def suffix(self) -> str:
69+
return ""
70+
71+
@property
72+
def suffixes(self) -> list[str]:
73+
return []
74+
75+
def with_name(self, name: str) -> Self:
76+
raise UnsupportedOperation("with_name not supported by DataPath")
4977

5078
def with_suffix(self, suffix: str) -> Self:
51-
raise UnsupportedOperation("path operation not supported by DataPath")
79+
raise UnsupportedOperation("with_suffix not supported by DataPath")
80+
81+
def with_stem(self, stem: str) -> Self:
82+
raise UnsupportedOperation("with_stem not supported by DataPath")
83+
84+
@property
85+
def parent(self) -> Self:
86+
return self
87+
88+
@property
89+
def parents(self) -> Sequence[Self]:
90+
return []
91+
92+
def full_match(self, pattern, *, case_sensitive: bool | None = None) -> bool:
93+
return super().full_match(pattern, case_sensitive=case_sensitive)
5294

5395
def mkdir(
5496
self, mode: int = 0o777, parents: bool = False, exist_ok: bool = False
@@ -66,3 +108,19 @@ def write_text(
66108
newline: str | None = None,
67109
) -> int:
68110
raise UnsupportedOperation("DataPath does not support writing")
111+
112+
def iterdir(self) -> Iterator[Self]:
113+
raise NotADirectoryError
114+
115+
def glob(
116+
self, pattern, *, case_sensitive=None, recurse_symlinks=False
117+
) -> Iterator[Self]:
118+
return iter([])
119+
120+
def rglob(
121+
self, pattern, *, case_sensitive=None, recurse_symlinks=False
122+
) -> Iterator[Self]:
123+
return iter([])
124+
125+
def unlink(self, missing_ok: bool = False) -> None:
126+
raise UnsupportedOperation

0 commit comments

Comments
 (0)