Repository: fsspec/filesystem_spec
Pull request #1640 (2024-06-29 15:01:09)

Update ruff to 0.5.0 & add rules
Updates ruff to latest version and enables a few new useful rules.


Patch:
diff --git a/fsspec/implementations/dirfs.py b/fsspec/implementations/dirfs.py
index 04f7479..6a28909 100644
--- a/fsspec/implementations/dirfs.py
+++ b/fsspec/implementations/dirfs.py
@@ -64,9 +64,15 @@ class DirFileSystem(AsyncFileSystem):
         if isinstance(path, str):
             if not self.path:
                 return path
-            if path == self.path:
+            # We need to account for S3FileSystem returning paths that do not
+            # start with a '/'
+            if path == self.path or (
+                self.path.startswith(self.fs.sep) and path == self.path[1:]
+            ):
                 return ""
             prefix = self.path + self.fs.sep
+            if self.path.startswith(self.fs.sep) and not path.startswith(self.fs.sep):
+                prefix = prefix[1:]
             assert path.startswith(prefix)
             return path[len(prefix) :]
         return [self._relpath(_path) for _path in path]
diff --git a/fsspec/implementations/http.py b/fsspec/implementations/http.py
index c9ab177..7b5a38b 100644
--- a/fsspec/implementations/http.py
+++ b/fsspec/implementations/http.py
@@ -254,7 +254,7 @@ class HTTPFileSystem(AsyncFileSystem):
             if isfilelike(lpath):
                 outfile = lpath
             else:
-                outfile = open(lpath, "wb")  # noqa: ASYNC101
+                outfile = open(lpath, "wb")  # noqa: ASYNC101, ASYNC230
 
             try:
                 chunk = True
@@ -282,7 +282,7 @@ class HTTPFileSystem(AsyncFileSystem):
                 context = nullcontext(lpath)
                 use_seek = False  # might not support seeking
             else:
-                context = open(lpath, "rb")  # noqa: ASYNC101
+                context = open(lpath, "rb")  # noqa: ASYNC101, ASYNC230
                 use_seek = True
 
             with context as f:
@@ -805,7 +805,7 @@ async def get_range(session, url, start, end, file=None, **kwargs):
     async with r:
         out = await r.read()
     if file:
-        with open(file, "r+b") as f:  # noqa: ASYNC101
+        with open(file, "r+b") as f:  # noqa: ASYNC101, ASYNC230
             f.seek(start)
             f.write(out)
     else:
diff --git a/pyproject.toml b/pyproject.toml
index 2dd6052..9638839 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -154,18 +154,20 @@ select = [
     # fix noqas in fsspec/implementations/http.py
     "ASYNC",
     "B",
-    "I",    # isort
     "C4",
     "G",
     "E4",
     "E7",
     "E9",
     "F",
+    "FURB",
     "LOG",
     "PERF",
     "PLC",
     "PLE",
     "PLR1722",
+    "PLR1736",
+    "PLW1501",
     "PLW1510",
     "PLW3301",
     "PIE800",
@@ -175,6 +177,7 @@ select = [
     # "PT", enable in later PR
     "PYI",
     "RUF006",
+    "RUF024",
     "SLOT",
     "SIM101",
 ]


Test patch:
diff --git a/fsspec/implementations/tests/test_dirfs.py b/fsspec/implementations/tests/test_dirfs.py
index c04ba66..990ab11 100644
--- a/fsspec/implementations/tests/test_dirfs.py
+++ b/fsspec/implementations/tests/test_dirfs.py
@@ -82,6 +82,8 @@ def test_dirfs(fs, asyncfs):
         ("", "foo", "foo"),
         ("root", "", "root"),
         ("root", "foo", "root/foo"),
+        ("/root", "", "/root"),
+        ("/root", "foo", "/root/foo"),
     ],
 )
 def test_path(fs, root, rel, full):
@@ -90,6 +92,18 @@ def test_path(fs, root, rel, full):
     assert dirfs._relpath(full) == rel
 
 
+@pytest.mark.parametrize(
+    "root, rel, full",
+    [
+        ("/root", "foo", "root/foo"),
+        ("/root", "", "root"),
+    ],
+)
+def test_path_no_leading_slash(fs, root, rel, full):
+    dirfs = DirFileSystem(root, fs)
+    assert dirfs._relpath(full) == rel
+
+
 def test_sep(mocker, dirfs):
     sep = mocker.Mock()
     dirfs.fs.sep = sep
diff --git a/fsspec/tests/test_utils.py b/fsspec/tests/test_utils.py
index 3a5c2ba..b9167b5 100644
--- a/fsspec/tests/test_utils.py
+++ b/fsspec/tests/test_utils.py
@@ -44,7 +44,7 @@ def test_read_block():
 
 
 def test_read_block_split_before():
-    """Test start/middle/end cases of split_before."""  # noqa: I
+    """Test start/middle/end cases of split_before."""
     d = (
         "#header" + "".join(">foo{i}\nFOOBAR{i}\n".format(i=i) for i in range(100000))
     ).encode()