Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ jobs:
continue-on-error: true

- name: Check types with mypy
if: matrix.python-version != '3.7' && matrix.python-version != '3.8'
run: |
mypy --python-version="${PYTHON_VERSION%t}" # Version only, with no "t" for free-threaded.
env:
Expand All @@ -103,7 +104,6 @@ jobs:
PYTHON_VERSION: ${{ matrix.python-version }}
# With new versions of mypy new issues might arise. This is a problem if there is
# nobody able to fix them, so we have to ignore errors until that changes.
continue-on-error: true

- name: Test with pytest
run: |
Expand Down
6 changes: 2 additions & 4 deletions git/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ def _included_paths(self) -> List[Tuple[str, str]]:
if keyword.endswith("/i"):
value = re.sub(
r"[a-zA-Z]",
lambda m: "[{}{}]".format(m.group().lower(), m.group().upper()),
lambda m: f"[{m.group().lower()!r}{m.group().upper()!r}]",
value,
)
if self._repo.git_dir:
Expand Down Expand Up @@ -633,8 +633,6 @@ def read(self) -> None: # type: ignore[override]
file_path = cast(IO[bytes], file_path)
self._read(file_path, file_path.name)
else:
# Assume a path if it is not a file-object.
file_path = cast(PathLike, file_path)
try:
with open(file_path, "rb") as fp:
file_ok = True
Expand Down Expand Up @@ -768,7 +766,7 @@ def _assure_writable(self, method_name: str) -> None:
if self.read_only:
raise IOError("Cannot execute non-constant method %s.%s" % (self, method_name))

def add_section(self, section: str) -> None:
def add_section(self, section: "cp._SectionName") -> None:
"""Assures added options will stay in order."""
return super().add_section(section)

Expand Down
5 changes: 3 additions & 2 deletions git/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
List,
Match,
Optional,
Sequence,
Tuple,
TYPE_CHECKING,
TypeVar,
Union,
cast,
)
from git.types import Literal, PathLike
from git.types import PathLike, Literal

if TYPE_CHECKING:
from subprocess import Popen
Expand Down Expand Up @@ -289,7 +290,7 @@ class DiffIndex(List[T_Diff]):
The class improves the diff handling convenience.
"""

change_type = ("A", "C", "D", "R", "M", "T")
change_type: Sequence[Literal["A", "C", "D", "R", "M", "T"]] = ("A", "C", "D", "R", "M", "T") # noqa: F821
"""Change type invariant identifying possible ways a blob can have changed:

* ``A`` = Added
Expand Down
4 changes: 2 additions & 2 deletions git/index/typ.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def from_base(cls, base: "BaseIndexEntry") -> "IndexEntry":
Instance of type :class:`BaseIndexEntry`.
"""
time = pack(">LL", 0, 0)
return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0))
return IndexEntry((base.mode, base.binsha, base.flags, base.path, time, time, 0, 0, 0, 0, 0)) # type: ignore[arg-type]

@classmethod
def from_blob(cls, blob: Blob, stage: int = 0) -> "IndexEntry":
Expand All @@ -211,5 +211,5 @@ def from_blob(cls, blob: Blob, stage: int = 0) -> "IndexEntry":
0,
0,
blob.size,
)
) # type: ignore[arg-type]
)
2 changes: 1 addition & 1 deletion git/objects/commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ def co_authors(self) -> List[Actor]:
if self.message:
results = re.findall(
r"^Co-authored-by: (.*) <(.*?)>$",
self.message,
str(self.message),
re.MULTILINE,
)
for author in results:
Expand Down
4 changes: 2 additions & 2 deletions git/objects/submodule/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
if TYPE_CHECKING:
from git.index import IndexFile
from git.objects.commit import Commit
from git.refs import Head
from git.refs import Head, RemoteReference
from git.repo import Repo

# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -355,7 +355,7 @@ def _clone_repo(
module_checkout_path = osp.join(str(repo.working_tree_dir), path)

if url.startswith("../"):
remote_name = repo.active_branch.tracking_branch().remote_name
remote_name = cast("RemoteReference", repo.active_branch.tracking_branch()).remote_name
repo_remote_url = repo.remote(remote_name).url
url = os.path.join(repo_remote_url, url)

Expand Down
6 changes: 1 addition & 5 deletions git/refs/head.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from git.types import Commit_ish, PathLike

if TYPE_CHECKING:
from git.objects import Commit
from git.refs import RemoteReference
from git.repo import Repo

Expand All @@ -44,9 +43,6 @@ class HEAD(SymbolicReference):

__slots__ = ()

# TODO: This can be removed once SymbolicReference.commit has static type hints.
commit: "Commit"

def __init__(self, repo: "Repo", path: PathLike = _HEAD_NAME) -> None:
if path != self._HEAD_NAME:
raise ValueError("HEAD instance must point to %r, got %r" % (self._HEAD_NAME, path))
Expand Down Expand Up @@ -149,7 +145,7 @@ class Head(Reference):
k_config_remote_ref = "merge" # Branch to merge from remote.

@classmethod
def delete(cls, repo: "Repo", *heads: "Union[Head, str]", force: bool = False, **kwargs: Any) -> None:
def delete(cls, repo: "Repo", *heads: "Union[Head, str]", force: bool = False, **kwargs: Any) -> None: # type: ignore[override]
"""Delete the given heads.

:param force:
Expand Down
2 changes: 1 addition & 1 deletion git/refs/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def from_line(cls, line: bytes) -> "RefLogEntry":
actor = Actor._from_string(info[82 : email_end + 1])
time, tz_offset = parse_date(info[email_end + 2 :]) # skipcq: PYL-W0621

return RefLogEntry((oldhexsha, newhexsha, actor, (time, tz_offset), msg))
return RefLogEntry((oldhexsha, newhexsha, actor, (time, tz_offset), msg)) # type: ignore [arg-type]


class RefLog(List[RefLogEntry], Serializable):
Expand Down
3 changes: 1 addition & 2 deletions git/refs/symbolic.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,8 +916,7 @@ def from_path(cls: Type[T_References], repo: "Repo", path: PathLike) -> T_Refere
SymbolicReference,
):
try:
instance: T_References
instance = ref_type(repo, path)
instance = cast(T_References, ref_type(repo, path))
if instance.__class__ is SymbolicReference and instance.is_detached:
raise ValueError("SymbolicRef was detached, we drop it")
else:
Expand Down
8 changes: 4 additions & 4 deletions git/refs/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class TagReference(Reference):
_common_default = "tags"
_common_path_default = Reference._common_path_default + "/" + _common_default

@property
def commit(self) -> "Commit": # type: ignore[override] # LazyMixin has unrelated commit method
@property # type: ignore[misc]
def commit(self) -> "Commit": # LazyMixin has unrelated commit method
""":return: Commit object the tag ref points to

:raise ValueError:
Expand Down Expand Up @@ -80,8 +80,8 @@ def tag(self) -> Union["TagObject", None]:
return None

# Make object read-only. It should be reasonably hard to adjust an existing tag.
@property
def object(self) -> AnyGitObject: # type: ignore[override]
@property # type: ignore[misc]
def object(self) -> AnyGitObject:
return Reference._get_object(self)

@classmethod
Expand Down
10 changes: 3 additions & 7 deletions git/repo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,11 +684,7 @@ def _config_reader(
git_dir: Optional[PathLike] = None,
) -> GitConfigParser:
if config_level is None:
files = [
self._get_config_path(cast(Lit_config_levels, f), git_dir)
for f in self.config_level
if cast(Lit_config_levels, f)
]
files = [self._get_config_path(f, git_dir) for f in self.config_level if f]
else:
files = [self._get_config_path(config_level, git_dir)]
return GitConfigParser(files, read_only=True, repo=self)
Expand Down Expand Up @@ -1484,7 +1480,7 @@ def clone(
self.common_dir,
path,
type(self.odb),
progress,
progress, # type: ignore[arg-type]
multi_options,
allow_unsafe_protocols=allow_unsafe_protocols,
allow_unsafe_options=allow_unsafe_options,
Expand Down Expand Up @@ -1545,7 +1541,7 @@ def clone_from(
url,
to_path,
GitCmdObjectDB,
progress,
progress, # type: ignore[arg-type]
multi_options,
allow_unsafe_protocols=allow_unsafe_protocols,
allow_unsafe_options=allow_unsafe_options,
Expand Down
2 changes: 1 addition & 1 deletion git/repo/fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def rev_parse(repo: "Repo", rev: str) -> AnyGitObject:
# END handle refname
else:
if ref is not None:
obj = cast("Commit", ref.commit)
obj = ref.commit
# END handle ref
# END initialize obj on first token

Expand Down
4 changes: 2 additions & 2 deletions git/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
Sequence as Sequence,
Tuple,
TYPE_CHECKING,
Type,
TypeVar,
Union,
)
Expand Down Expand Up @@ -130,7 +129,8 @@
https://git-scm.com/docs/gitglossary#def_object_type
"""

Lit_commit_ish: Type[Literal["commit", "tag"]]
if TYPE_CHECKING:
Lit_commit_ish = Literal["commit", "tag"]
"""Deprecated. Type of literal strings identifying typically-commitish git object types.

Prior to a bugfix, this type had been defined more broadly. Any usage is in practice
Expand Down
8 changes: 5 additions & 3 deletions git/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,7 @@ def _obtain_lock(self) -> None:
# END endless loop


class IterableList(List[T_IterableObj]):
class IterableList(List[T_IterableObj]): # type: ignore[type-var]
"""List of iterable objects allowing to query an object by id or by named index::
heads = repo.heads
Expand Down Expand Up @@ -1214,14 +1214,16 @@ def __getitem__(self, index: Union[SupportsIndex, int, slice, str]) -> T_Iterabl
raise ValueError("Index should be an int or str")
else:
try:
if not isinstance(index, str):
raise AttributeError(f"{index} is not a valid attribute")
return getattr(self, index)
except AttributeError as e:
raise IndexError("No item found with id %r" % (self._prefix + index)) from e
raise IndexError(f"No item found with id {self._prefix}{index}") from e
# END handle getattr

def __delitem__(self, index: Union[SupportsIndex, int, slice, str]) -> None:
delindex = cast(int, index)
if not isinstance(index, int):
if isinstance(index, str):
delindex = -1
name = self._prefix + index
for i, item in enumerate(self):
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ testpaths = "test" # Space separated list of paths from root e.g test tests doc
# filterwarnings ignore::WarningType # ignores those warnings

[tool.mypy]
python_version = "3.8"
files = ["git/", "test/deprecation/"]
disallow_untyped_defs = true
no_implicit_optional = true
Expand Down
2 changes: 1 addition & 1 deletion test-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
coverage[toml]
ddt >= 1.1.1, != 1.4.3
mock ; python_version < "3.8"
mypy
mypy==1.18.2 ; python_version >= "3.9" # pin mypy version to avoid new errors
pre-commit
pytest >= 7.3.1
pytest-cov
Expand Down
2 changes: 1 addition & 1 deletion test/deprecation/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_can_access_lit_commit_ish_but_it_is_not_usable() -> None:
assert 'Literal["commit", "tag"]' in message, "Has new definition."
assert "GitObjectTypeString" in message, "Has new type name for old definition."

_: Lit_commit_ish = "commit" # type: ignore[valid-type]
_: Lit_commit_ish = "commit"

# It should be as documented (even though deliberately unusable in static checks).
assert Lit_commit_ish == Literal["commit", "tag"]
Expand Down
4 changes: 2 additions & 2 deletions test/lib/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def repo_creator(self):
os.chdir(rw_repo.working_dir)
try:
return func(self, rw_repo)
except: # noqa: E722 B001
except: # noqa: E722
_logger.info("Keeping repo after failure: %s", repo_dir)
repo_dir = None
raise
Expand Down Expand Up @@ -309,7 +309,7 @@ def remote_repo_creator(self):
with cwd(rw_repo.working_dir):
try:
return func(self, rw_repo, rw_daemon_repo)
except: # noqa: E722 B001
except: # noqa: E722
_logger.info(
"Keeping repos after failure: \n rw_repo_dir: %s \n rw_daemon_repo_dir: %s",
rw_repo_dir,
Expand Down
5 changes: 4 additions & 1 deletion test/test_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
class TestRemoteProgress(RemoteProgress):
__slots__ = ("_seen_lines", "_stages_per_op", "_num_progress_messages")

def __init__(self):
def __init__(self) -> None:
super().__init__()
self._seen_lines = []
self._stages_per_op = {}
Expand Down Expand Up @@ -103,6 +103,9 @@ def assert_received_message(self):
assert self._num_progress_messages


TestRemoteProgress.__test__ = False # type: ignore


class TestRemote(TestBase):
def tearDown(self):
gc.collect()
Expand Down
3 changes: 2 additions & 1 deletion test/test_submodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def update(self, op, cur_count, max_count, message=""):
print(op, cur_count, max_count, message)


TestRootProgress.__test__ = False
prog = TestRootProgress()


Expand Down Expand Up @@ -932,7 +933,7 @@ def assert_exists(sm, value=True):
csm.repo.index.commit("Have to commit submodule change for algorithm to pick it up")
assert csm.url == "bar"

self.assertRaises(
self.assertRaises( # noqa: B017
Exception,
rsm.update,
recursive=True,
Expand Down
Loading