Skip to content

Commit 0e95587

Browse files
committed
fix and silence typing in repository
1 parent 0df1e17 commit 0e95587

File tree

3 files changed

+38
-31
lines changed

3 files changed

+38
-31
lines changed

docs/objects.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ implements a subset of the mapping interface.
3333
>>> repo = Repository('path/to/pygit2')
3434
>>> obj = repo.get("101715bf37440d32291bde4f58c3142bcf7d8adb")
3535
>>> obj
36-
<_pygit2.Commit object at 0x7ff27a6b60f0>
36+
<pygit2.Object{commit:101715bf37440d32291bde4f58c3142bcf7d8adb}>
3737

3838
.. method:: Repository.__getitem__(id)
3939

pygit2/_pygit2.pyi

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,15 +284,17 @@ class Object:
284284
type: 'Literal[GIT_OBJ_COMMIT] | Literal[GIT_OBJ_TREE] | Literal[GIT_OBJ_TAG] | Literal[GIT_OBJ_BLOB]'
285285
type_str: "Literal['commit'] | Literal['tree'] | Literal['tag'] | Literal['blob']"
286286
@overload
287-
def peel(self, target_type: 'Literal[GIT_OBJ_COMMIT]') -> 'Commit': ...
287+
def peel(
288+
self, target_type: 'Literal[GIT_OBJ_COMMIT] | Type[Commit]'
289+
) -> 'Commit': ...
288290
@overload
289-
def peel(self, target_type: 'Literal[GIT_OBJ_TREE]') -> 'Tree': ...
291+
def peel(self, target_type: 'Literal[GIT_OBJ_TREE] | Type[Tree]') -> 'Tree': ...
290292
@overload
291-
def peel(self, target_type: 'Literal[GIT_OBJ_TAG]') -> 'Tag': ...
293+
def peel(self, target_type: 'Literal[GIT_OBJ_TAG] | Type[Tag]') -> 'Tag': ...
292294
@overload
293-
def peel(self, target_type: 'Literal[GIT_OBJ_BLOB]') -> 'Blob': ...
295+
def peel(self, target_type: 'Literal[GIT_OBJ_BLOB] | Type[Blob]') -> 'Blob': ...
294296
@overload
295-
def peel(self, target_type: 'None') -> 'Commit|Tree|Blob': ...
297+
def peel(self, target_type: 'None') -> 'Commit|Tree|Tag|Blob': ...
296298
def read_raw(self) -> bytes: ...
297299
def __eq__(self, other) -> bool: ...
298300
def __ge__(self, other) -> bool: ...
@@ -664,7 +666,7 @@ class Repository:
664666
def TreeBuilder(self, src: Tree | _OidArg = ...) -> TreeBuilder: ...
665667
def _disown(self, *args, **kwargs) -> None: ...
666668
def _from_c(self, *args, **kwargs) -> None: ...
667-
def __getitem__(self, key: str | bytes | Oid | Reference) -> Commit: ...
669+
def __getitem__(self, key: str | Oid) -> Object: ...
668670
def add_worktree(self, name: str, path: str, ref: Reference = ...) -> Worktree: ...
669671
def applies(
670672
self,

pygit2/repository.py

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@
2929
from time import time
3030
import tarfile
3131
import typing
32+
from typing import Optional
3233

3334
# Import from pygit2
3435
from ._pygit2 import Repository as _Repository, init_file_backend
35-
from ._pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN
36+
from ._pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN, Object
3637
from ._pygit2 import Reference, Tree, Commit, Blob, Signature
3738
from ._pygit2 import InvalidSpecError
3839

@@ -187,20 +188,20 @@ def __iter__(self):
187188
#
188189
# Mapping interface
189190
#
190-
def get(self, key, default=None):
191+
def get(self, key: str, default: Optional[Commit] = None) -> Object:
191192
value = self.git_object_lookup_prefix(key)
192193
return value if (value is not None) else default
193194

194-
def __getitem__(self, key):
195+
def __getitem__(self, key: str | Oid) -> Object:
195196
value = self.git_object_lookup_prefix(key)
196197
if value is None:
197198
raise KeyError(key)
198199
return value
199200

200-
def __contains__(self, key):
201+
def __contains__(self, key: str | Oid) -> bool:
201202
return self.git_object_lookup_prefix(key) is not None
202203

203-
def __repr__(self):
204+
def __repr__(self) -> str:
204205
return f'pygit2.Repository({repr(self.path)})'
205206

206207
#
@@ -529,22 +530,22 @@ def diff(
529530

530531
# Case 1: Diff tree to tree
531532
if isinstance(a, Tree) and isinstance(b, Tree):
532-
return a.diff_to_tree(b, **options)
533+
return a.diff_to_tree(b, **options) # type: ignore[arg-type]
533534

534535
# Case 2: Index to workdir
535536
elif a is None and b is None:
536-
return self.index.diff_to_workdir(**options)
537+
return self.index.diff_to_workdir(**options) # type: ignore[arg-type]
537538

538539
# Case 3: Diff tree to index or workdir
539540
elif isinstance(a, Tree) and b is None:
540541
if cached:
541-
return a.diff_to_index(self.index, **options)
542+
return a.diff_to_index(self.index, **options) # type: ignore[arg-type]
542543
else:
543-
return a.diff_to_workdir(**options)
544+
return a.diff_to_workdir(**options) # type: ignore[arg-type]
544545

545546
# Case 4: Diff blob to blob
546547
if isinstance(a, Blob) and isinstance(b, Blob):
547-
return a.diff(b, **options)
548+
return a.diff(b, **options) # type: ignore[arg-type]
548549

549550
raise ValueError('Only blobs and treeish can be diffed')
550551

@@ -559,7 +560,7 @@ def state(self) -> RepositoryState:
559560
return RepositoryState(cstate)
560561
except ValueError:
561562
# Some value not in the IntEnum - newer libgit2 version?
562-
return cstate
563+
return cstate # type: ignore[return-value]
563564

564565
def state_cleanup(self):
565566
"""Remove all the metadata associated with an ongoing command like
@@ -770,9 +771,15 @@ def merge_commits(
770771
cindex = ffi.new('git_index **')
771772

772773
if isinstance(ours, (str, Oid)):
773-
ours = self[ours]
774+
ours_object = self[ours]
775+
if not isinstance(ours_object, Commit):
776+
raise TypeError(f'expected Commit, got {type(ours_object)}')
777+
ours = ours_object
774778
if isinstance(theirs, (str, Oid)):
775-
theirs = self[theirs]
779+
theirs_object = self[theirs]
780+
if not isinstance(theirs_object, Commit):
781+
raise TypeError(f'expected Commit, got {type(theirs_object)}')
782+
theirs = theirs_object
776783

777784
ours = ours.peel(Commit)
778785
theirs = theirs.peel(Commit)
@@ -827,16 +834,9 @@ def merge_trees(
827834
theirs_ptr = ffi.new('git_tree **')
828835
cindex = ffi.new('git_index **')
829836

830-
if isinstance(ancestor, (str, Oid)):
831-
ancestor = self[ancestor]
832-
if isinstance(ours, (str, Oid)):
833-
ours = self[ours]
834-
if isinstance(theirs, (str, Oid)):
835-
theirs = self[theirs]
836-
837-
ancestor = ancestor.peel(Tree)
838-
ours = ours.peel(Tree)
839-
theirs = theirs.peel(Tree)
837+
ancestor = self.__ensure_tree(ancestor)
838+
ours = self.__ensure_tree(ours)
839+
theirs = self.__ensure_tree(theirs)
840840

841841
opts = self._merge_options(favor, flags, file_flags)
842842

@@ -890,7 +890,7 @@ def merge(
890890
if isinstance(source, Reference):
891891
# Annotated commit from ref
892892
cptr = ffi.new('struct git_reference **')
893-
ffi.buffer(cptr)[:] = source._pointer[:]
893+
ffi.buffer(cptr)[:] = source._pointer[:] # type: ignore[attr-defined]
894894
commit_ptr = ffi.new('git_annotated_commit **')
895895
err = C.git_annotated_commit_from_ref(commit_ptr, self._repo, cptr[0])
896896
check_error(err)
@@ -1615,6 +1615,11 @@ def amend_commit(
16151615

16161616
return Oid(raw=bytes(ffi.buffer(coid)[:]))
16171617

1618+
def __ensure_tree(self, maybe_tree: str | Oid | Tree) -> Tree:
1619+
if isinstance(maybe_tree, Tree):
1620+
return maybe_tree
1621+
return self[maybe_tree].peel(Tree)
1622+
16181623

16191624
class Repository(BaseRepository):
16201625
def __init__(

0 commit comments

Comments
 (0)