Skip to content

Commit

Permalink
pygit2: bump to 1.14.0 (#312)
Browse files Browse the repository at this point in the history
* pygit2: bump to 1.14.0

* pygit2: replace pygit2.remote with pygit2.remotes

* Drop Python 3.8

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fixup! [pre-commit.ci] auto fixes from pre-commit.com hooks

* Add support for Python 3.12

* Upgrade pytest-docker to v2

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
0x2b3bfa0 and pre-commit-ci[bot] authored Jan 28, 2024
1 parent 6e44250 commit 0d23565
Show file tree
Hide file tree
Showing 28 changed files with 137 additions and 157 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-20.04, windows-latest, macos-latest]
pyv: ['3.8', '3.9', '3.10', '3.11']
pyv: ['3.9', '3.10', '3.11', '3.12']

steps:
- name: Check out the repository
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Request features on the `Issue Tracker`_.
How to set up your development environment
------------------------------------------

You need Python 3.8+ and the following tools:
You need Python 3.9+ and the following tools:

- Nox_

Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
locations = "src", "tests"


@nox.session(python=["3.8", "3.9", "3.10", "3.11"])
@nox.session(python=["3.9", "3.10", "3.11", "3.12"])
def tests(session: nox.Session) -> None:
session.install(".[tests]")
session.run(
Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ license = {text = "Apache-2.0"}
authors = [{ name = "Iterative", email = "support@dvc.org" }]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Development Status :: 4 - Beta",
]
requires-python = ">=3.8"
requires-python = ">=3.9"
dynamic = ["version"]
dependencies = [
"gitpython>3",
"dulwich>=0.21.6",
"pygit2>=1.13.3",
"pygit2>=1.14.0",
"pygtrie>=2.3.2",
"fsspec>=2021.7.0",
"pathspec>=0.9.0",
Expand All @@ -48,7 +48,7 @@ tests = [
"pytest-test-utils==0.0.8",
"pytest-asyncio==0.18.3",
# https://github.com/docker/docker-py/issues/2902
"pytest-docker==0.12.0; python_version < '3.10' and implementation_name != 'pypy'",
"pytest-docker==2.2.0; python_version < '3.10' and implementation_name != 'pypy'",
"mock==5.1.0",
"paramiko==3.3.1",
"types-certifi==2021.10.8.3",
Expand Down
6 changes: 3 additions & 3 deletions src/scmrepo/asyn.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import asyncio
import os
import threading
from typing import Any, List, Optional
from typing import Any, Optional

from fsspec.asyn import ( # noqa: F401, pylint:disable=unused-import
_selector_policy,
Expand All @@ -11,9 +11,9 @@
)

# dedicated async IO thread
iothread: List[Optional[threading.Thread]] = [None]
iothread: list[Optional[threading.Thread]] = [None]
# global DVC event loop
default_loop: List[Optional[asyncio.AbstractEventLoop]] = [None]
default_loop: list[Optional[asyncio.AbstractEventLoop]] = [None]
lock = threading.Lock()


Expand Down
8 changes: 4 additions & 4 deletions src/scmrepo/fs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import errno
import os
import posixpath
from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Dict, Optional, Tuple
from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Optional

from fsspec.callbacks import _DEFAULT_CALLBACK
from fsspec.spec import AbstractFileSystem
Expand Down Expand Up @@ -169,7 +169,7 @@ def relparts(self, path, start=None):
def as_posix(cls, path):
return path

def _get_key(self, path: str) -> Tuple[str, ...]:
def _get_key(self, path: str) -> tuple[str, ...]:
path = self.abspath(path)
if path == self.root_marker:
return ()
Expand All @@ -184,7 +184,7 @@ def _open(
mode: str = "rb",
block_size: Optional[int] = None,
autocommit: bool = True,
cache_options: Optional[Dict] = None,
cache_options: Optional[dict] = None,
raw: bool = False,
**kwargs: Any,
) -> BinaryIO:
Expand All @@ -204,7 +204,7 @@ def _open(
errno.EISDIR, os.strerror(errno.EISDIR), path
) from exc

def info(self, path: str, **kwargs: Any) -> Dict[str, Any]:
def info(self, path: str, **kwargs: Any) -> dict[str, Any]:
key = self._get_key(path)
try:
# NOTE: to avoid wasting time computing object size, trie.info
Expand Down
18 changes: 7 additions & 11 deletions src/scmrepo/git/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,14 @@
import re
import typing
from collections import OrderedDict
from collections.abc import Mapping
from collections.abc import Iterable, Mapping
from contextlib import contextmanager
from functools import partialmethod
from typing import (
TYPE_CHECKING,
Callable,
ClassVar,
Dict,
Iterable,
Optional,
Tuple,
Type,
Union,
)

Expand Down Expand Up @@ -44,14 +40,14 @@

logger = logging.getLogger(__name__)

BackendCls = Type[BaseGitBackend]
BackendCls = type[BaseGitBackend]


_LOW_PRIO_BACKENDS = ("gitpython",)


class GitBackends(Mapping):
DEFAULT: ClassVar[Dict[str, BackendCls]] = {
DEFAULT: ClassVar[dict[str, BackendCls]] = {
"dulwich": DulwichBackend,
"pygit2": Pygit2Backend,
"gitpython": GitPythonBackend,
Expand All @@ -72,7 +68,7 @@ def __init__(self, selected: Optional[Iterable[str]], *args, **kwargs) -> None:
selected = selected or list(self.DEFAULT)
self.backends = OrderedDict((key, self.DEFAULT[key]) for key in selected)

self.initialized: Dict[str, BaseGitBackend] = {}
self.initialized: dict[str, BaseGitBackend] = {}

self.args = args
self.kwargs = kwargs
Expand Down Expand Up @@ -169,7 +165,7 @@ def is_sha(cls, rev):
return rev and cls.RE_HEXSHA.search(rev)

@classmethod
def split_ref_pattern(cls, ref: str) -> Tuple[str, str]:
def split_ref_pattern(cls, ref: str) -> tuple[str, str]:
name = cls.BAD_REF_CHARS_RE.split(ref, maxsplit=1)[0]
return name, ref[len(name) :]

Expand Down Expand Up @@ -492,8 +488,8 @@ def describe(
base: Optional[str] = None,
match: Optional[str] = None,
exclude: Optional[str] = None,
) -> Dict[str, Optional[str]]:
results: Dict[str, Optional[str]] = {}
) -> dict[str, Optional[str]]:
results: dict[str, Optional[str]] = {}
remained_revs = set()
if base == "refs/heads":
current_rev = self.get_rev()
Expand Down
7 changes: 4 additions & 3 deletions src/scmrepo/git/backend/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os
from abc import ABC, abstractmethod
from collections.abc import Iterable, Mapping
from enum import Enum
from typing import TYPE_CHECKING, Callable, Iterable, Mapping, Optional, Tuple, Union
from typing import TYPE_CHECKING, Callable, Optional, Union

from scmrepo.exceptions import SCMError
from scmrepo.git.objects import GitObject
Expand Down Expand Up @@ -281,7 +282,7 @@ def _stash_push(
ref: str,
message: Optional[str] = None,
include_untracked: bool = False,
) -> Tuple[Optional[str], bool]:
) -> tuple[Optional[str], bool]:
"""Push a commit onto the specified stash.
Returns a tuple of the form (rev, need_reset) where need_reset
Expand Down Expand Up @@ -347,7 +348,7 @@ def checkout_index(
@abstractmethod
def status(
self, ignored: bool = False, untracked_files: str = "all"
) -> Tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
) -> tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
"""Return tuple of (staged_files, unstaged_files, untracked_files).
staged_files will be a dict mapping status (add, delete, modify) to a
Expand Down
39 changes: 17 additions & 22 deletions src/scmrepo/git/backend/dulwich/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,15 @@
import os
import re
import stat
from collections.abc import Iterable, Iterator, Mapping
from contextlib import closing
from functools import partial
from io import BytesIO, StringIO
from typing import (
TYPE_CHECKING,
Any,
Callable,
Dict,
Iterable,
Iterator,
List,
Mapping,
Optional,
Tuple,
Union,
)

Expand Down Expand Up @@ -151,18 +146,18 @@ def encoding(self) -> str:
return self._config.encoding
return self._config.backends[0].encoding

def get(self, section: Tuple[str, ...], name: str) -> str:
def get(self, section: tuple[str, ...], name: str) -> str:
"""Return the specified setting as a string."""
return self._config.get(section, name).decode(self.encoding)

def get_bool(self, section: Tuple[str, ...], name: str) -> bool:
def get_bool(self, section: tuple[str, ...], name: str) -> bool:
"""Return the specified setting as a boolean."""
value = self._config.get_boolean(section, name)
if value is None:
raise ValueError("setting is not a valid boolean")
return value

def get_multivar(self, section: Tuple[str, ...], name: str) -> Iterator[str]:
def get_multivar(self, section: tuple[str, ...], name: str) -> Iterator[str]:
"""Iterate over string values in the specified multivar setting."""
for value in self._config.get_multivar(section, name):
yield value.decode(self.encoding)
Expand Down Expand Up @@ -199,17 +194,17 @@ def __init__( # pylint:disable=W0231
except NotGitRepository as exc:
raise SCMError(f"{root_dir} is not a git repository") from exc

self._submodules: Dict[str, str] = self._find_submodules()
self._submodules: dict[str, str] = self._find_submodules()
self._stashes: dict = {}

def _find_submodules(self) -> Dict[str, str]:
def _find_submodules(self) -> dict[str, str]:
"""Return dict mapping submodule names to submodule paths.
Submodule paths will be relative to Git repo root.
"""
from dulwich.config import ConfigFile, parse_submodules

submodules: Dict[str, str] = {}
submodules: dict[str, str] = {}
config_path = os.path.join(self.root_dir, ".gitmodules")
if os.path.isfile(config_path):
config = ConfigFile.from_path(config_path)
Expand Down Expand Up @@ -332,7 +327,7 @@ def add(
self.repo.stage(list(self.repo.open_index()))
return

files: List[bytes] = [
files: list[bytes] = [
os.fsencode(fpath) for fpath in self._expand_paths(paths, force=force)
]
if update:
Expand All @@ -348,7 +343,7 @@ def add(
else:
self.repo.stage(files)

def _expand_paths(self, paths: List[str], force: bool = False) -> Iterator[str]:
def _expand_paths(self, paths: list[str], force: bool = False) -> Iterator[str]:
for path in paths:
if not os.path.isabs(path) and self._submodules:
# NOTE: If path is inside a submodule, Dulwich expects the
Expand Down Expand Up @@ -459,7 +454,7 @@ def is_tracked(self, path: str) -> bool:
return any(p == rel or p.startswith(rel_dir) for p in self.repo.open_index())

def is_dirty(self, untracked_files: bool = False) -> bool:
kwargs: Dict[str, Any] = {} if untracked_files else {"untracked_files": "no"}
kwargs: dict[str, Any] = {} if untracked_files else {"untracked_files": "no"}
return any(self.status(**kwargs))

def active_branch(self) -> str:
Expand Down Expand Up @@ -707,9 +702,9 @@ def fetch_refspecs(
fetch_refs = []

def determine_wants(
remote_refs: Dict[bytes, bytes],
remote_refs: dict[bytes, bytes],
depth: Optional[int] = None, # pylint: disable=unused-argument
) -> List[bytes]:
) -> list[bytes]:
fetch_refs.extend(
parse_reftuples(
DictRefsContainer(remote_refs),
Expand Down Expand Up @@ -782,7 +777,7 @@ def _stash_push(
ref: str,
message: Optional[str] = None,
include_untracked: bool = False,
) -> Tuple[Optional[str], bool]:
) -> tuple[Optional[str], bool]:
from dulwich.repo import InvalidUserIdentity

from scmrepo.git import Stash
Expand Down Expand Up @@ -836,8 +831,8 @@ def _describe(
) -> Mapping[str, Optional[str]]:
if not base:
base = "refs/tags"
rev_mapping: Dict[str, Optional[str]] = {}
results: Dict[str, Optional[str]] = {}
rev_mapping: dict[str, Optional[str]] = {}
results: dict[str, Optional[str]] = {}
for ref in self.iter_refs(base=base):
if (match and not fnmatch.fnmatch(ref, match)) or (
exclude and fnmatch.fnmatch(ref, exclude)
Expand Down Expand Up @@ -877,7 +872,7 @@ def checkout_index(

def status(
self, ignored: bool = False, untracked_files: str = "all"
) -> Tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
) -> tuple[Mapping[str, Iterable[str]], Iterable[str], Iterable[str]]:
from dulwich.porcelain import Error
from dulwich.porcelain import status as git_status

Expand Down Expand Up @@ -978,7 +973,7 @@ def check_attr(
_IDENTITY_RE = re.compile(r"(?P<name>.+)\s+<(?P<email>.+)>")


def _parse_identity(identity: str) -> Tuple[str, str]:
def _parse_identity(identity: str) -> tuple[str, str]:
m = _IDENTITY_RE.match(identity)
if not m:
raise SCMError("Could not parse tagger identity '{identity}'")
Expand Down
Loading

0 comments on commit 0d23565

Please sign in to comment.