Repository: fsspec/universal_pathlib (python)

Issue:
samefile() is not implemented
Is there a plan for implementing `UPath.samefile()`? I can see how such a method might be difficult to define universally, and that it isn't the same thing as `UPath.__eq__()`, which is implemented, but this broke some code of mine that was usually using `Path.samefile()` and then failed when I passed it a `UPath` instead of a `Path`.

If this is a TODO, then is there anything I can do to help?

Pull request description:
Implement UPath.samefile
Closes #246 

Patch:
diff --git a/upath/_stat.py b/upath/_stat.py
index 5a4f0b1..c2ef5a0 100644
--- a/upath/_stat.py
+++ b/upath/_stat.py
@@ -142,6 +142,12 @@ class UPathStatResult:
         seq_attrs = ", ".join(map("{0[0]}={0[1]}".format, zip(self._fields, self)))
         return f"{cls_name}({seq_attrs}, info={self._info!r})"
 
+    def __eq__(self, other):
+        if not isinstance(other, UPathStatResult):
+            return NotImplemented
+        else:
+            return self._info == other._info
+
     # --- access to the fsspec info dict ------------------------------
 
     @classmethod
diff --git a/upath/core.py b/upath/core.py
index 3e11dfa..5650819 100644
--- a/upath/core.py
+++ b/upath/core.py
@@ -803,7 +803,12 @@ class UPath(PathlibPathShim, Path):
         return False
 
     def samefile(self, other_path) -> bool:
-        raise NotImplementedError
+        st = self.stat()
+        if isinstance(other_path, UPath):
+            other_st = other_path.stat()
+        else:
+            other_st = self.with_segments(other_path).stat()
+        return st == other_st
 
     @overload  # type: ignore[override]
     def open(


Test patch:
diff --git a/upath/tests/cases.py b/upath/tests/cases.py
index d865d53..1d50af5 100644
--- a/upath/tests/cases.py
+++ b/upath/tests/cases.py
@@ -317,9 +317,6 @@ class BaseTests:
         expected = [*pathlib_base.rglob(pattern)]
         assert len(result) == len(expected)
 
-    def test_samefile(self):
-        pass
-
     def test_symlink_to(self):
         pass
 
@@ -545,3 +542,12 @@ class BaseTests:
         assert p0 == p1
         assert p0 != p2
         assert p1 != p2
+
+    def test_samefile(self):
+        f1 = self.path.joinpath("file1.txt")
+        f2 = self.path.joinpath("file2.txt")
+
+        assert f1.samefile(f2) is False
+        assert f1.samefile(f2.path) is False
+        assert f1.samefile(f1) is True
+        assert f1.samefile(f1.path) is True
diff --git a/upath/tests/implementations/test_data.py b/upath/tests/implementations/test_data.py
index 90e1f8a..6fb1132 100644
--- a/upath/tests/implementations/test_data.py
+++ b/upath/tests/implementations/test_data.py
@@ -199,3 +199,8 @@ class TestUPathDataPath(BaseTests):
     def test_rmdir_not_empty(self):
         with pytest.raises(NotADirectoryError):
             self.path.rmdir()
+
+    def test_samefile(self):
+        f1 = self.path
+
+        assert f1.samefile(f1) is True