nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: fsspec/gcsfs
Pull request #631 (2024-07-18 05:25:44)

Handle case when error message is a string.
Fixes https://github.com/fsspec/gcsfs/issues/630.

martindurant: Thanks for getting this in.

Patch:
diff --git a/gcsfs/retry.py b/gcsfs/retry.py
index 1c4012b..0d787a4 100644
--- a/gcsfs/retry.py
+++ b/gcsfs/retry.py
@@ -99,7 +99,11 @@ def validate_response(status, content, path, args=None):
             content = content.decode()
         try:
             error = json.loads(content)["error"]
-            msg = error["message"]
+            # Sometimes the error message is a string.
+            if isinstance(error, str):
+                msg = error
+            else:
+                msg = error["message"]
         except json.decoder.JSONDecodeError:
             msg = content
 
@@ -109,7 +113,7 @@ def validate_response(status, content, path, args=None):
             raise requests.exceptions.ProxyError()
         elif "invalid" in str(msg):
             raise ValueError(f"Bad Request: {path}\n{msg}")
-        elif error:
+        elif error and not isinstance(error, str):
             raise HttpError(error)
         elif status:
             raise HttpError({"code": status, "message": msg})  # text-like


Test patch:
diff --git a/gcsfs/tests/test_retry.py b/gcsfs/tests/test_retry.py
index 79058f5..e5d4ed4 100644
--- a/gcsfs/tests/test_retry.py
+++ b/gcsfs/tests/test_retry.py
@@ -103,6 +103,15 @@ def test_validate_response():
         validate_response(502, b"", "/path")
 
 
+def test_validate_response_error_is_string():
+    # HttpError with JSON body
+    j = '{"error": "Too Many Requests"}'
+    with pytest.raises(HttpError) as e:
+        validate_response(429, j, "/path")
+    assert e.value.code == 429
+    assert e.value.message == "Too Many Requests, 429"
+
+
 @pytest.mark.parametrize(
     ["file_path", "validate_get_error", "validate_list_error", "expected_error"],
     [
Repository: fsspec/gcsfs
Pull request #646 (2024-10-30 21:27:51)

Handle cache_timeout = 0 in GCSFileSystem
Fixes https://github.com/fsspec/gcsfs/issues/645

martindurant: A test for this would be nice.
amyewang: @martindurant added a test to `test_expiry_keyword` & passes as expected. let me know if you think it should live somewhere else! 

Patch:
diff --git a/gcsfs/core.py b/gcsfs/core.py
index 6fd05ea..73dbceb 100644
--- a/gcsfs/core.py
+++ b/gcsfs/core.py
@@ -285,7 +285,7 @@ class GCSFileSystem(asyn.AsyncFileSystem):
         version_aware=False,
         **kwargs,
     ):
-        if cache_timeout:
+        if cache_timeout is not None:
             kwargs["listings_expiry_time"] = cache_timeout
         super().__init__(
             self,


Test patch:
diff --git a/gcsfs/tests/test_core.py b/gcsfs/tests/test_core.py
index 28f1a1d..2a0b4c0 100644
--- a/gcsfs/tests/test_core.py
+++ b/gcsfs/tests/test_core.py
@@ -1428,6 +1428,8 @@ def test_expiry_keyword():
     assert gcs.dircache.listings_expiry_time == 1
     gcs = GCSFileSystem(cache_timeout=1, token="anon")
     assert gcs.dircache.listings_expiry_time == 1
+    gcs = GCSFileSystem(cache_timeout=0, token="anon")
+    assert gcs.dircache.listings_expiry_time == 0
 
 
 def test_copy_cache_invalidated(gcs):
Repository: fsspec/filesystem_spec
Pull request #855 (2021-12-14 18:07:37)

Fix a bug in `CachingFileSystem.pop_from_cache()`
`pop_from_cache()` would crash if asked to pop a path that wasn't in the cache.  This PR fixes that.


Patch:
diff --git a/fsspec/implementations/cached.py b/fsspec/implementations/cached.py
index dcd137e..eef7491 100644
--- a/fsspec/implementations/cached.py
+++ b/fsspec/implementations/cached.py
@@ -235,9 +235,10 @@ class CachingFileSystem(AbstractFileSystem):
         raises PermissionError
         """
         path = self._strip_protocol(path)
-        _, fn = self._check_file(path)
-        if fn is None:
+        details = self._check_file(path)
+        if not details:
             return
+        _, fn = details
         if fn.startswith(self.storage[-1]):
             # is in in writable cache
             os.remove(fn)


Test patch:
diff --git a/fsspec/implementations/tests/test_cached.py b/fsspec/implementations/tests/test_cached.py
index e1ce4bd..5232c05 100644
--- a/fsspec/implementations/tests/test_cached.py
+++ b/fsspec/implementations/tests/test_cached.py
@@ -180,6 +180,7 @@ def test_pop():
     with pytest.raises(PermissionError):
         fs.pop_from_cache(f1)
     fs.pop_from_cache(f2)
+    fs.pop_from_cache(os.path.join(origin, "uncached-file"))
     assert len(os.listdir(cache2)) == 1
     assert not fs._check_file(f2)
     assert fs._check_file(f1)
Repository: fsspec/filesystem_spec
Pull request #887 (2022-01-13 17:47:52)

Slice of Openfiles should also be Openfiles


Patch:
diff --git a/fsspec/core.py b/fsspec/core.py
index 8515de6..ac65c7a 100644
--- a/fsspec/core.py
+++ b/fsspec/core.py
@@ -204,6 +204,12 @@ class OpenFiles(list):
                     break
         [s.__exit__(*args) for s in self]
 
+    def __getitem__(self, item):
+        out = super().__getitem__(item)
+        if isinstance(item, slice):
+            return OpenFiles(out, mode=self.mode, fs=self.fs)
+        return out
+
     def __repr__(self):
         return "<List of %s OpenFile instances>" % len(self)
 


Test patch:
diff --git a/fsspec/tests/test_core.py b/fsspec/tests/test_core.py
index 23a2cdd..d4cb636 100644
--- a/fsspec/tests/test_core.py
+++ b/fsspec/tests/test_core.py
@@ -184,6 +184,8 @@ def test_multi_context(tmpdir):
     assert isinstance(files, OpenFiles)
     assert isinstance(files[0], OpenFile)
     assert len(files) == 2
+    assert isinstance(files[:1], OpenFiles)
+    assert len(files[:1]) == 1
     with files as of:
         assert len(of) == 2
         assert not of[0].closed
Repository: fsspec/filesystem_spec
Pull request #1112 (2022-11-11 20:22:47)

Add extra case to make_path_posix for ./path/...


Patch:
diff --git a/fsspec/implementations/local.py b/fsspec/implementations/local.py
index 7c3b5db..c1ed241 100644
--- a/fsspec/implementations/local.py
+++ b/fsspec/implementations/local.py
@@ -229,6 +229,8 @@ def make_path_posix(path, sep=os.sep):
         # most common fast case for posix
         if path.startswith("/"):
             return path
+        if path.startswith("./"):
+            path = path[2:]
         return os.getcwd() + "/" + path
     if (
         (sep not in path and "/" not in path)


Test patch:
diff --git a/fsspec/implementations/tests/test_local.py b/fsspec/implementations/tests/test_local.py
index e1b6ab7..37f8ec9 100644
--- a/fsspec/implementations/tests/test_local.py
+++ b/fsspec/implementations/tests/test_local.py
@@ -480,6 +480,8 @@ def test_make_path_posix():
         )
     assert "/" in make_path_posix("rel\\path")
 
+    assert "." not in make_path_posix("./path")
+
 
 def test_linked_files(tmpdir):
     tmpdir = str(tmpdir)
Repository: fsspec/filesystem_spec
Pull request #1117 (2022-11-16 10:26:19)

Fix LocalFileSystem put of file to directory
This is a candidate fix for issue #967, which is a `LocalFileSystem.put()` of a file to a directory.

There are a number of places that a fix could be applied. I have traced the problem to `AbstractFileSystem.put()` which calls `other_paths()` on the target path. This wasn't passing an `is_dir` kwarg which I think is the fundamental bug behind the OP's issue.

The fix is to pass the `is_dir` kwarg but bearing in mind the `other_paths` docstring which states
```
is_dir: bool (optional)
    For the special case where the input in one element, whether to regard the value
    as the target path, or as a directory to put a file path within. If None, a
    directory is inferred if the path ends in '/'
```
so `is_dir` is only passed as True if the length of the source paths is 1.

I've added a specific test for the OP's issue, which fails before this PR and passes with it. 

This definitely needs to be checked by someone with more `fsspec` experience than I have to confirm the fix doesn't cause problems elsewhere.

martindurant: I think this is right.

Also, for further reference, similar issues in gcsfs and s3fs probably come down to the early stripping of "/" before hading to `other_paths`, and so might be easily fixed. https://github.com/fsspec/s3fs/issues/659

Patch:
diff --git a/fsspec/spec.py b/fsspec/spec.py
index aeb7963..b728599 100644
--- a/fsspec/spec.py
+++ b/fsspec/spec.py
@@ -910,8 +910,12 @@ class AbstractFileSystem(metaclass=_Cached):
             lpath = make_path_posix(lpath)
         fs = LocalFileSystem()
         lpaths = fs.expand_path(lpath, recursive=recursive)
+        isdir = isinstance(rpath, str) and self.isdir(rpath)
         rpaths = other_paths(
-            lpaths, rpath, exists=isinstance(rpath, str) and self.isdir(rpath)
+            lpaths,
+            rpath,
+            exists=isdir,
+            is_dir=isdir and len(lpaths) == 1,
         )
 
         callback.set_size(len(rpaths))


Test patch:
diff --git a/fsspec/implementations/tests/test_local.py b/fsspec/implementations/tests/test_local.py
index 37f8ec9..434f37a 100644
--- a/fsspec/implementations/tests/test_local.py
+++ b/fsspec/implementations/tests/test_local.py
@@ -809,3 +809,17 @@ def test_symlink(tmpdir):
 
     fs.symlink(target, link)
     assert fs.islink(link)
+
+
+# https://github.com/fsspec/filesystem_spec/issues/967
+def test_put_file_to_dir(tmpdir):
+    src_file = os.path.join(str(tmpdir), "src")
+    target_dir = os.path.join(str(tmpdir), "target")
+    target_file = os.path.join(target_dir, "src")
+
+    fs = LocalFileSystem()
+    fs.touch(src_file)
+    fs.mkdir(target_dir)
+    fs.put(src_file, target_dir)
+
+    assert fs.isfile(target_file)