Skip to content

Commit 823af24

Browse files
committed
Improve typing: add References to Repository
pygit2 was removed from the python typeshed, but the built in types of pygit2 are not complete. This change tries to improve this situation, by fixing type errors that occur when activating typing for the tests. So first the test functions (for the public API) in test/test_refs.py were adapted, in order to activate mypy type checking. Then _pygit2.pyi was adapted to fix those mypy type checking errors. The skeleton was provided by: stubgen -m pygit2.references -o /tmp/pygit2 The following command mypy test returned the following summary before this change: Found 289 errors in 10 files (checked 50 source files) and after this change: Found 289 errors in 10 files (checked 50 source files)
1 parent bc0cf9f commit 823af24

File tree

2 files changed

+52
-29
lines changed

2 files changed

+52
-29
lines changed

pygit2/_pygit2.pyi

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Iterator, Literal, Optional, overload
1+
from typing import Iterator, Literal, Optional, overload, Type
22
from io import IOBase
33
from . import Index
44
from .enums import (
@@ -20,6 +20,8 @@ from .enums import (
2020
SortMode,
2121
)
2222

23+
from .repository import BaseRepository
24+
2325
GIT_OBJ_BLOB = Literal[3]
2426
GIT_OBJ_COMMIT = Literal[1]
2527
GIT_OBJ_TAG = Literal[4]
@@ -73,15 +75,15 @@ class Reference:
7375
def delete(self) -> None: ...
7476
def log(self) -> Iterator[RefLogEntry]: ...
7577
@overload
76-
def peel(self, type: 'Literal[GIT_OBJ_COMMIT]') -> 'Commit': ...
78+
def peel(self, type: 'Literal[GIT_OBJ_COMMIT] | Type[Commit]') -> 'Commit': ...
7779
@overload
78-
def peel(self, type: 'Literal[GIT_OBJ_TREE]') -> 'Tree': ...
80+
def peel(self, type: 'Literal[GIT_OBJ_TREE] | Type[Tree]') -> 'Tree': ...
7981
@overload
80-
def peel(self, type: 'Literal[GIT_OBJ_TAG]') -> 'Tag': ...
82+
def peel(self, type: 'Literal[GIT_OBJ_TAG] | Type[Tag]') -> 'Tag': ...
8183
@overload
82-
def peel(self, type: 'Literal[GIT_OBJ_BLOB]') -> 'Blob': ...
84+
def peel(self, type: 'Literal[GIT_OBJ_BLOB] | Type[Blob]') -> 'Blob': ...
8385
@overload
84-
def peel(self, type: 'None') -> 'Commit|Tree|Blob': ...
86+
def peel(self, type: 'None' = None) -> 'Commit|Tree|Tag|Blob': ...
8587
def rename(self, new_name: str) -> None: ...
8688
def resolve(self) -> Reference: ...
8789
def set_target(self, target: _OidArg, message: str = ...) -> None: ...
@@ -329,6 +331,21 @@ class RefdbBackend:
329331
class RefdbFsBackend(RefdbBackend):
330332
def __init__(self, *args, **kwargs) -> None: ...
331333

334+
class References:
335+
def __init__(self, repository: BaseRepository) -> None: ...
336+
def __getitem__(self, name: str) -> Reference: ...
337+
def get(self, key: str) -> Reference: ...
338+
def __iter__(self) -> Iterator[str]: ...
339+
def iterator(
340+
self, references_return_type: ReferenceFilter = ...
341+
) -> Iterator[Reference]: ...
342+
def create(self, name: str, target: _OidArg, force: bool = False) -> Reference: ...
343+
def delete(self, name: str) -> None: ...
344+
def __contains__(self, name: str) -> bool: ...
345+
@property
346+
def objects(self) -> list[Reference]: ...
347+
def compress(self) -> None: ...
348+
332349
class Repository:
333350
_pointer: bytes
334351
default_signature: Signature
@@ -342,10 +359,12 @@ class Repository:
342359
path: str
343360
refdb: Refdb
344361
workdir: str
362+
references: References
345363
def __init__(self, *args, **kwargs) -> None: ...
346364
def TreeBuilder(self, src: Tree | _OidArg = ...) -> TreeBuilder: ...
347365
def _disown(self, *args, **kwargs) -> None: ...
348366
def _from_c(self, *args, **kwargs) -> None: ...
367+
def __getitem__(self, key: str | bytes | Oid | Reference) -> Commit: ...
349368
def add_worktree(self, name: str, path: str, ref: Reference = ...) -> Worktree: ...
350369
def applies(
351370
self,
@@ -394,6 +413,9 @@ class Repository:
394413
ref: str = 'refs/notes/commits',
395414
force: bool = False,
396415
) -> Oid: ...
416+
def create_reference(
417+
self, name: str, target: _OidArg, force: bool = False
418+
) -> Reference: ...
397419
def create_reference_direct(
398420
self, name: str, target: _OidArg, force: bool, message: Optional[str] = None
399421
) -> Reference: ...
@@ -443,6 +465,7 @@ class Repository:
443465
def revparse(self, revspec: str) -> RevSpec: ...
444466
def revparse_ext(self, revision: str) -> tuple[Object, Reference]: ...
445467
def revparse_single(self, revision: str) -> Object: ...
468+
def set_ident(self, name: str, email: str) -> None: ...
446469
def set_odb(self, odb: Odb) -> None: ...
447470
def set_refdb(self, refdb: Refdb) -> None: ...
448471
def status(

test/test_refs.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
import pytest
3131

32-
from pygit2 import Commit, Signature, Tree, reference_is_valid_name
32+
from pygit2 import Commit, Signature, Tree, reference_is_valid_name, Repository
3333
from pygit2 import AlreadyExistsError, GitError, InvalidSpecError
3434
from pygit2.enums import ReferenceType
3535

@@ -45,7 +45,7 @@ def test_refs_list_objects(testrepo):
4545
]
4646

4747

48-
def test_refs_list(testrepo):
48+
def test_refs_list(testrepo: Repository) -> None:
4949
# Without argument
5050
assert sorted(testrepo.references) == ['refs/heads/i18n', 'refs/heads/master']
5151

@@ -58,13 +58,13 @@ def test_refs_list(testrepo):
5858
]
5959

6060

61-
def test_head(testrepo):
61+
def test_head(testrepo: Repository) -> None:
6262
head = testrepo.head
6363
assert LAST_COMMIT == testrepo[head.target].id
6464
assert LAST_COMMIT == testrepo[head.raw_target].id
6565

6666

67-
def test_refs_getitem(testrepo):
67+
def test_refs_getitem(testrepo: Repository) -> None:
6868
refname = 'refs/foo'
6969
# Raise KeyError ?
7070
with pytest.raises(KeyError):
@@ -78,37 +78,37 @@ def test_refs_getitem(testrepo):
7878
assert reference.name == 'refs/heads/master'
7979

8080

81-
def test_refs_get_sha(testrepo):
81+
def test_refs_get_sha(testrepo: Repository) -> None:
8282
reference = testrepo.references['refs/heads/master']
8383
assert reference.target == LAST_COMMIT
8484

8585

86-
def test_refs_set_sha(testrepo):
86+
def test_refs_set_sha(testrepo: Repository) -> None:
8787
NEW_COMMIT = '5ebeeebb320790caf276b9fc8b24546d63316533'
8888
reference = testrepo.references.get('refs/heads/master')
8989
reference.set_target(NEW_COMMIT)
9090
assert reference.target == NEW_COMMIT
9191

9292

93-
def test_refs_set_sha_prefix(testrepo):
93+
def test_refs_set_sha_prefix(testrepo: Repository) -> None:
9494
NEW_COMMIT = '5ebeeebb320790caf276b9fc8b24546d63316533'
9595
reference = testrepo.references.get('refs/heads/master')
9696
reference.set_target(NEW_COMMIT[0:6])
9797
assert reference.target == NEW_COMMIT
9898

9999

100-
def test_refs_get_type(testrepo):
100+
def test_refs_get_type(testrepo: Repository) -> None:
101101
reference = testrepo.references.get('refs/heads/master')
102102
assert reference.type == ReferenceType.DIRECT
103103

104104

105-
def test_refs_get_target(testrepo):
105+
def test_refs_get_target(testrepo: Repository) -> None:
106106
reference = testrepo.references.get('HEAD')
107107
assert reference.target == 'refs/heads/master'
108108
assert reference.raw_target == b'refs/heads/master'
109109

110110

111-
def test_refs_set_target(testrepo):
111+
def test_refs_set_target(testrepo: Repository) -> None:
112112
reference = testrepo.references.get('HEAD')
113113
assert reference.target == 'refs/heads/master'
114114
assert reference.raw_target == b'refs/heads/master'
@@ -117,14 +117,14 @@ def test_refs_set_target(testrepo):
117117
assert reference.raw_target == b'refs/heads/i18n'
118118

119119

120-
def test_refs_get_shorthand(testrepo):
120+
def test_refs_get_shorthand(testrepo: Repository) -> None:
121121
reference = testrepo.references.get('refs/heads/master')
122122
assert reference.shorthand == 'master'
123123
reference = testrepo.references.create('refs/remotes/origin/master', LAST_COMMIT)
124124
assert reference.shorthand == 'origin/master'
125125

126126

127-
def test_refs_set_target_with_message(testrepo):
127+
def test_refs_set_target_with_message(testrepo: Repository) -> None:
128128
reference = testrepo.references.get('HEAD')
129129
assert reference.target == 'refs/heads/master'
130130
assert reference.raw_target == b'refs/heads/master'
@@ -139,7 +139,7 @@ def test_refs_set_target_with_message(testrepo):
139139
assert first.committer == sig
140140

141141

142-
def test_refs_delete(testrepo):
142+
def test_refs_delete(testrepo: Repository) -> None:
143143
# We add a tag as a new reference that points to "origin/master"
144144
reference = testrepo.references.create('refs/tags/version1', LAST_COMMIT)
145145
assert 'refs/tags/version1' in testrepo.references
@@ -163,7 +163,7 @@ def test_refs_delete(testrepo):
163163
reference.rename('refs/tags/version2')
164164

165165

166-
def test_refs_rename(testrepo):
166+
def test_refs_rename(testrepo: Repository) -> None:
167167
# We add a tag as a new reference that points to "origin/master"
168168
reference = testrepo.references.create('refs/tags/version1', LAST_COMMIT)
169169
assert reference.name == 'refs/tags/version1'
@@ -177,7 +177,7 @@ def test_refs_rename(testrepo):
177177
reference.rename('b1')
178178

179179

180-
# def test_reload(testrepo):
180+
# def test_reload(testrepo: Repository) -> None:
181181
# name = 'refs/tags/version1'
182182
# ref = testrepo.create_reference(name, "refs/heads/master", symbolic=True)
183183
# ref2 = testrepo.lookup_reference(name)
@@ -187,21 +187,21 @@ def test_refs_rename(testrepo):
187187
# with pytest.raises(GitError): getattr(ref2, 'name')
188188

189189

190-
def test_refs_resolve(testrepo):
190+
def test_refs_resolve(testrepo: Repository) -> None:
191191
reference = testrepo.references.get('HEAD')
192192
assert reference.type == ReferenceType.SYMBOLIC
193193
reference = reference.resolve()
194194
assert reference.type == ReferenceType.DIRECT
195195
assert reference.target == LAST_COMMIT
196196

197197

198-
def test_refs_resolve_identity(testrepo):
198+
def test_refs_resolve_identity(testrepo: Repository) -> None:
199199
head = testrepo.references.get('HEAD')
200200
ref = head.resolve()
201201
assert ref.resolve() is ref
202202

203203

204-
def test_refs_create(testrepo):
204+
def test_refs_create(testrepo: Repository) -> None:
205205
# We add a tag as a new reference that points to "origin/master"
206206
reference = testrepo.references.create('refs/tags/version1', LAST_COMMIT)
207207
refs = testrepo.references
@@ -220,7 +220,7 @@ def test_refs_create(testrepo):
220220
assert reference.target == LAST_COMMIT
221221

222222

223-
def test_refs_create_symbolic(testrepo):
223+
def test_refs_create_symbolic(testrepo: Repository) -> None:
224224
# We add a tag as a new symbolic reference that always points to
225225
# "refs/heads/master"
226226
reference = testrepo.references.create('refs/tags/beta', 'refs/heads/master')
@@ -241,11 +241,11 @@ def test_refs_create_symbolic(testrepo):
241241
assert reference.raw_target == b'refs/heads/master'
242242

243243

244-
# def test_packall_references(testrepo):
244+
# def test_packall_references(testrepo: Repository) -> None:
245245
# testrepo.packall_references()
246246

247247

248-
def test_refs_peel(testrepo):
248+
def test_refs_peel(testrepo: Repository) -> None:
249249
ref = testrepo.references.get('refs/heads/master')
250250
assert testrepo[ref.target].id == ref.peel().id
251251
assert testrepo[ref.raw_target].id == ref.peel().id
@@ -254,7 +254,7 @@ def test_refs_peel(testrepo):
254254
assert commit.tree.id == ref.peel(Tree).id
255255

256256

257-
def test_refs_equality(testrepo):
257+
def test_refs_equality(testrepo: Repository) -> None:
258258
ref1 = testrepo.references.get('refs/heads/master')
259259
ref2 = testrepo.references.get('refs/heads/master')
260260
ref3 = testrepo.references.get('refs/heads/i18n')
@@ -267,7 +267,7 @@ def test_refs_equality(testrepo):
267267
assert not ref1 == ref3
268268

269269

270-
def test_refs_compress(testrepo):
270+
def test_refs_compress(testrepo: Repository) -> None:
271271
packed_refs_file = Path(testrepo.path) / 'packed-refs'
272272
assert not packed_refs_file.exists()
273273
old_refs = [(ref.name, ref.target) for ref in testrepo.references.objects]

0 commit comments

Comments
 (0)