From 8314a65746c4d62c9263d7d98007a8b54f971dc5 Mon Sep 17 00:00:00 2001 From: Andreas Poehlmann Date: Thu, 8 Feb 2024 22:12:02 +0100 Subject: [PATCH] Add GitHubPath (#155) Co-authored-by: juftin Co-authored-by: ap-- --- upath/implementations/github.py | 23 +++++++ upath/registry.py | 1 + upath/tests/implementations/test_github.py | 71 ++++++++++++++++++++++ upath/tests/test_registry.py | 1 + 4 files changed, 96 insertions(+) create mode 100644 upath/implementations/github.py create mode 100644 upath/tests/implementations/test_github.py diff --git a/upath/implementations/github.py b/upath/implementations/github.py new file mode 100644 index 0000000..741dfa1 --- /dev/null +++ b/upath/implementations/github.py @@ -0,0 +1,23 @@ +""" +GitHub file system implementation +""" + +import upath.core + + +class GitHubPath(upath.core.UPath): + """ + GitHubPath supporting the fsspec.GitHubFileSystem + """ + + @property + def path(self) -> str: + pth = super().path + if pth == ".": + return "" + return pth + + def iterdir(self): + if self.is_file(): + raise NotADirectoryError(str(self)) + yield from super().iterdir() diff --git a/upath/registry.py b/upath/registry.py index f93feeb..745867c 100644 --- a/upath/registry.py +++ b/upath/registry.py @@ -78,6 +78,7 @@ class _Registry(MutableMapping[str, "type[upath.UPath]"]): "webdav": "upath.implementations.webdav.WebdavPath", "webdav+http": "upath.implementations.webdav.WebdavPath", "webdav+https": "upath.implementations.webdav.WebdavPath", + "github": "upath.implementations.github.GitHubPath", } if TYPE_CHECKING: diff --git a/upath/tests/implementations/test_github.py b/upath/tests/implementations/test_github.py new file mode 100644 index 0000000..81db812 --- /dev/null +++ b/upath/tests/implementations/test_github.py @@ -0,0 +1,71 @@ +import os +import platform +import sys + +import pytest + +from upath import UPath +from upath.implementations.github import GitHubPath +from upath.tests.cases import BaseTests + +pytestmark = pytest.mark.skipif( + os.environ.get("CI") + and (sys.version_info not in {(3, 8), (3, 12)} and platform.system() != "Linux"), + reason="Skipping GitHubPath tests to prevent rate limiting on GitHub API.", +) + + +class TestUPathGitHubPath(BaseTests): + """ + Unit-tests for the GitHubPath implementation of UPath. + """ + + @pytest.fixture(autouse=True) + def path(self): + """ + Fixture for the UPath instance to be tested. + """ + path = "github://ap--:universal_pathlib@test_data/data" + self.path = UPath(path) + + def test_is_GitHubPath(self): + """ + Test that the path is a GitHubPath instance. + """ + assert isinstance(self.path, GitHubPath) + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_mkdir(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_mkdir_exists_ok_false(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_mkdir_parents_true_exists_ok_false(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_rename(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_rename2(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_touch_unlink(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_write_bytes(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_write_text(self): + pass + + @pytest.mark.skip(reason="GitHub filesystem is read-only") + def test_fsspec_compat(self): + pass diff --git a/upath/tests/test_registry.py b/upath/tests/test_registry.py index 58c2b16..dbd6ae7 100644 --- a/upath/tests/test_registry.py +++ b/upath/tests/test_registry.py @@ -24,6 +24,7 @@ "webdav", "webdav+http", "webdav+https", + "github", }