Skip to content

github:, gitlab: and git:

All need the http extra.

pathlib_next.uri.schemes._gitrepo

DEFAULT_TIMEOUT = (10, 60) module-attribute

(connect, read) timeout, in seconds, RepoBackend sends with every request unless the caller supplies timeout (RepoBackend(timeout=...) or per request); timeout=None restores requests' unbounded wait.

BaseRepoBackend

Bases: object

Protocol for issuing an authenticated HTTP request against a GitHub/GitLab REST API. Subclass this to plug in custom auth/session handling; RepoBackend is the real requests-based implementation.

RepoBackend(token=None, session=None, api_base=None, **requests_args)

Bases: BaseRepoBackend

Lazily-used requests.Session + an optional bearer token sent on every request (mirrors HttpBackend.requests_args in http.py). Unauthenticated works fine for public repos, subject to the host's anonymous rate limit (60 req/h for github.com). api_base, when set, overrides the scheme's convention-derived API root entirely (e.g. https://api.github.com/https://{host}/api/v3) -- the seam a test fake (or a reverse-proxied self-hosted setup) plugs into, since the real convention always forces https. Every request gets timeout=DEFAULT_TIMEOUT ((10, 60) seconds) unless requests_args (RepoBackend(timeout=...)) or the call supplies one; timeout=None waits forever.

Source code in src/pathlib_next/uri/schemes/_gitrepo.py
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def __init__(
    self,
    token: str = None,
    session: _req.Session = None,
    api_base: str = None,
    **requests_args,
):
    self.session = session or _req.Session()
    self.token = token or None
    self.api_base = api_base.rstrip("/") if api_base else None
    self.requests_args = requests_args
    # Generic per-backend memoization slot for schemes that need it
    # (GitLabPath's resolved default-branch lookup, see `_resolved_ref`)
    # -- shared across every path instance that shares this backend.
    self.cache = {}

pathlib_next.uri.schemes._gitrepo._RepoApiPath(*uris, **options)

Bases: UriPath

Shared base for github:/gitlab: (<scheme>://host/owner/repo/path /in/repo?ref=<ref>): read-only access to a git-hosting REST API. ref (branch/tag/SHA) is always optional, carried in the ?ref= query string -- omitted, GitHub falls back server-side to the repo's default branch, while GitLab's file endpoints need an explicit ref, so GitLabPath resolves (and caches) the default branch once. host defaults to the public SaaS host; any other host is treated as a self-hosted instance. Auth: a bearer token via with_backend(RepoBackend(token=...)), or embedded in the URI as userinfo -- <scheme>://user:TOKEN@host/... (git's x-access-token:TOKEN / GitLab's oauth2:TOKEN convention: the password slot is the token) or a bare <scheme>://TOKEN@host/... -- the backend kwarg wins if both are given. Because the user slot can be the secret here, str(), repr(), as_uri(sanitize=True) and so every exception message drop the WHOLE userinfo for these schemes (other schemes drop only the password); as_uri() still round-trips it. Read-only: write goes through a separate commits API entirely (out of scope, see docs/divergences.md).

Source code in src/pathlib_next/uri/__init__.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def __init__(self, *uris: UriLike, **options):
    if self._raw_uris or self._initiated:
        return
    _uris: list[str | Uri] = []
    for uri in uris:
        if not uri:
            uri = ""
        if isinstance(uri, Uri):
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.Path, Path)):
            try:
                uri = uri.as_uri()
            except ValueError:
                # as_uri() raises ValueError for a relative path, which
                # joins like a relative PurePath (see _RelativeLocalPath).
                uri = _RelativeLocalPath(_uriencode(uri.as_posix(), safe="/"))
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.PurePath, Pathname)):
            _uris.append(_path_reference(uri.as_posix()))
        elif hasattr(uri, "as_uri"):
            path = uri.as_uri
            if callable(path):
                path = path()
            _uris.append(path)
        elif isinstance(uri, str):
            _uris.append(uri)
        elif isinstance(uri, bytes):
            _uris.append(uri.decode())
        else:
            path = None
            try:
                path = os.fspath(uri)
            except (TypeError, NotImplementedError):
                pass
            if not isinstance(path, str):
                raise TypeError(
                    "argument should be a str or an os.PathLike "
                    "object where __fspath__ returns a str, "
                    f"not {type(path).__name__!r}"
                )
            # Only __fspath__ is guaranteed here -- posix-normalize the
            # string itself rather than assuming an as_posix() method.
            posix = _pathlib.PurePath(path).as_posix()
            _uris.append(_path_reference(posix))
    self._raw_uris = _uris

backend instance-attribute

owner property

ref property

repo property

repo_path property

with_source(source)

Source code in src/pathlib_next/uri/schemes/_gitrepo.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
def with_source(self, source: Source):
    if source and source.scheme == "git" and "git" not in type(self)._schemes():
        # `git:` re-dispatches by host; the base implementation would
        # construct `git:` with no host, which always raised ValueError.
        from .git._base import GitPath

        provider_cls = GitPath._provider_cls(source)
        self._check_inherited_backend()
        same = isinstance(self, provider_cls) and _same_authority(
            source, self.source
        )
        inst = UriPath.__new__(
            provider_cls, backend=self._backend if same else None
        )
        inst._init(source, self.path, self.query, self.fragment)
        return inst
    return super().with_source(source)

pathlib_next.uri.schemes.github.GitHubPath(*uris, **options)

Bases: _RepoApiPath

github: scheme: read-only access to a GitHub repository tree via the REST contents API (GET /repos/{owner}/{repo}/contents/{path}). host defaults to github.com (API at api.github.com); any other host is treated as GitHub Enterprise (API at https://{host}/api/v3). File bodies are fetched with the raw media type (skips base64 and its ~1MB inline-content cap) instead of the default JSON+base64 envelope. symlink/submodule tree entries are treated as plain files (no special handling -- see docs/divergences.md). No mtime (would need a separate commits-history call per path). Requires the http extra (plain requests, no PyGithub SDK).

Source code in src/pathlib_next/uri/__init__.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def __init__(self, *uris: UriLike, **options):
    if self._raw_uris or self._initiated:
        return
    _uris: list[str | Uri] = []
    for uri in uris:
        if not uri:
            uri = ""
        if isinstance(uri, Uri):
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.Path, Path)):
            try:
                uri = uri.as_uri()
            except ValueError:
                # as_uri() raises ValueError for a relative path, which
                # joins like a relative PurePath (see _RelativeLocalPath).
                uri = _RelativeLocalPath(_uriencode(uri.as_posix(), safe="/"))
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.PurePath, Pathname)):
            _uris.append(_path_reference(uri.as_posix()))
        elif hasattr(uri, "as_uri"):
            path = uri.as_uri
            if callable(path):
                path = path()
            _uris.append(path)
        elif isinstance(uri, str):
            _uris.append(uri)
        elif isinstance(uri, bytes):
            _uris.append(uri.decode())
        else:
            path = None
            try:
                path = os.fspath(uri)
            except (TypeError, NotImplementedError):
                pass
            if not isinstance(path, str):
                raise TypeError(
                    "argument should be a str or an os.PathLike "
                    "object where __fspath__ returns a str, "
                    f"not {type(path).__name__!r}"
                )
            # Only __fspath__ is guaranteed here -- posix-normalize the
            # string itself rather than assuming an as_posix() method.
            posix = _pathlib.PurePath(path).as_posix()
            _uris.append(_path_reference(posix))
    self._raw_uris = _uris

pathlib_next.uri.schemes.gitlab.GitLabPath(*uris, **options)

Bases: _RepoApiPath

gitlab: scheme: read-only access to a GitLab project's repository tree via the REST API v4 (project identified as URL-encoded owner/repo). A project in a subgroup is addressed with GitLab's own /-/ separator, as in its web URLs: gitlab://host/group/subgroup/project/-/path/in/repo; without the separator the first two segments are owner/repo. host defaults to gitlab.com; a self-hosted instance is just a different host (and port), always at https://{host}/api/v4 (no enterprise/SaaS API-path split like GitHub). The tree-listing endpoint doesn't carry file size, so _scandir() only pre-seeds a stat hint for tree (directory) entries (size=0 is truthful for a directory, not a placeholder) -- blob (file) entries get a real stat() lazily instead of guessing a size that could poison a caller trusting the hint. No mtime. Requires the http extra (plain requests, no python-gitlab SDK).

Source code in src/pathlib_next/uri/__init__.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def __init__(self, *uris: UriLike, **options):
    if self._raw_uris or self._initiated:
        return
    _uris: list[str | Uri] = []
    for uri in uris:
        if not uri:
            uri = ""
        if isinstance(uri, Uri):
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.Path, Path)):
            try:
                uri = uri.as_uri()
            except ValueError:
                # as_uri() raises ValueError for a relative path, which
                # joins like a relative PurePath (see _RelativeLocalPath).
                uri = _RelativeLocalPath(_uriencode(uri.as_posix(), safe="/"))
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.PurePath, Pathname)):
            _uris.append(_path_reference(uri.as_posix()))
        elif hasattr(uri, "as_uri"):
            path = uri.as_uri
            if callable(path):
                path = path()
            _uris.append(path)
        elif isinstance(uri, str):
            _uris.append(uri)
        elif isinstance(uri, bytes):
            _uris.append(uri.decode())
        else:
            path = None
            try:
                path = os.fspath(uri)
            except (TypeError, NotImplementedError):
                pass
            if not isinstance(path, str):
                raise TypeError(
                    "argument should be a str or an os.PathLike "
                    "object where __fspath__ returns a str, "
                    f"not {type(path).__name__!r}"
                )
            # Only __fspath__ is guaranteed here -- posix-normalize the
            # string itself rather than assuming an as_posix() method.
            posix = _pathlib.PurePath(path).as_posix()
            _uris.append(_path_reference(posix))
    self._raw_uris = _uris

pathlib_next.uri.schemes.git._base.GitPath(*uris, **options)

Bases: UriPath

git: catch-all scheme for public Git hosts.

git://github.com/... and git://gitlab.com/... auto-select the existing github:/gitlab: providers by host. Self-hosted or enterprise instances are intentionally ambiguous here and must use git+github:/git+gitlab: or the explicit github:/gitlab: schemes.

Source code in src/pathlib_next/uri/__init__.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def __init__(self, *uris: UriLike, **options):
    if self._raw_uris or self._initiated:
        return
    _uris: list[str | Uri] = []
    for uri in uris:
        if not uri:
            uri = ""
        if isinstance(uri, Uri):
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.Path, Path)):
            try:
                uri = uri.as_uri()
            except ValueError:
                # as_uri() raises ValueError for a relative path, which
                # joins like a relative PurePath (see _RelativeLocalPath).
                uri = _RelativeLocalPath(_uriencode(uri.as_posix(), safe="/"))
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.PurePath, Pathname)):
            _uris.append(_path_reference(uri.as_posix()))
        elif hasattr(uri, "as_uri"):
            path = uri.as_uri
            if callable(path):
                path = path()
            _uris.append(path)
        elif isinstance(uri, str):
            _uris.append(uri)
        elif isinstance(uri, bytes):
            _uris.append(uri.decode())
        else:
            path = None
            try:
                path = os.fspath(uri)
            except (TypeError, NotImplementedError):
                pass
            if not isinstance(path, str):
                raise TypeError(
                    "argument should be a str or an os.PathLike "
                    "object where __fspath__ returns a str, "
                    f"not {type(path).__name__!r}"
                )
            # Only __fspath__ is guaranteed here -- posix-normalize the
            # string itself rather than assuming an as_posix() method.
            posix = _pathlib.PurePath(path).as_posix()
            _uris.append(_path_reference(posix))
    self._raw_uris = _uris

pathlib_next.uri.schemes.git.github.GitHubGitPath(*uris, **options)

Bases: GitHubPath

git+github: explicit GitHub-hosted repository scheme.

Source code in src/pathlib_next/uri/__init__.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def __init__(self, *uris: UriLike, **options):
    if self._raw_uris or self._initiated:
        return
    _uris: list[str | Uri] = []
    for uri in uris:
        if not uri:
            uri = ""
        if isinstance(uri, Uri):
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.Path, Path)):
            try:
                uri = uri.as_uri()
            except ValueError:
                # as_uri() raises ValueError for a relative path, which
                # joins like a relative PurePath (see _RelativeLocalPath).
                uri = _RelativeLocalPath(_uriencode(uri.as_posix(), safe="/"))
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.PurePath, Pathname)):
            _uris.append(_path_reference(uri.as_posix()))
        elif hasattr(uri, "as_uri"):
            path = uri.as_uri
            if callable(path):
                path = path()
            _uris.append(path)
        elif isinstance(uri, str):
            _uris.append(uri)
        elif isinstance(uri, bytes):
            _uris.append(uri.decode())
        else:
            path = None
            try:
                path = os.fspath(uri)
            except (TypeError, NotImplementedError):
                pass
            if not isinstance(path, str):
                raise TypeError(
                    "argument should be a str or an os.PathLike "
                    "object where __fspath__ returns a str, "
                    f"not {type(path).__name__!r}"
                )
            # Only __fspath__ is guaranteed here -- posix-normalize the
            # string itself rather than assuming an as_posix() method.
            posix = _pathlib.PurePath(path).as_posix()
            _uris.append(_path_reference(posix))
    self._raw_uris = _uris

pathlib_next.uri.schemes.git.gitlab.GitLabGitPath(*uris, **options)

Bases: GitLabPath

git+gitlab: explicit GitLab-hosted repository scheme.

Source code in src/pathlib_next/uri/__init__.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def __init__(self, *uris: UriLike, **options):
    if self._raw_uris or self._initiated:
        return
    _uris: list[str | Uri] = []
    for uri in uris:
        if not uri:
            uri = ""
        if isinstance(uri, Uri):
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.Path, Path)):
            try:
                uri = uri.as_uri()
            except ValueError:
                # as_uri() raises ValueError for a relative path, which
                # joins like a relative PurePath (see _RelativeLocalPath).
                uri = _RelativeLocalPath(_uriencode(uri.as_posix(), safe="/"))
            _uris.append(uri)
        elif isinstance(uri, (_pathlib.PurePath, Pathname)):
            _uris.append(_path_reference(uri.as_posix()))
        elif hasattr(uri, "as_uri"):
            path = uri.as_uri
            if callable(path):
                path = path()
            _uris.append(path)
        elif isinstance(uri, str):
            _uris.append(uri)
        elif isinstance(uri, bytes):
            _uris.append(uri.decode())
        else:
            path = None
            try:
                path = os.fspath(uri)
            except (TypeError, NotImplementedError):
                pass
            if not isinstance(path, str):
                raise TypeError(
                    "argument should be a str or an os.PathLike "
                    "object where __fspath__ returns a str, "
                    f"not {type(path).__name__!r}"
                )
            # Only __fspath__ is guaranteed here -- posix-normalize the
            # string itself rather than assuming an as_posix() method.
            posix = _pathlib.PurePath(path).as_posix()
            _uris.append(_path_reference(posix))
    self._raw_uris = _uris