Skip to content

Commit 0e55fb3

Browse files
committed
add typing for blame.py and add _ctyping
1 parent 720881e commit 0e55fb3

File tree

3 files changed

+53
-19
lines changed

3 files changed

+53
-19
lines changed

pygit2/_ctyping.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# placeholder for pyright

pygit2/_ctyping.pyi

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from _cffi_backend import _CDataBase
2+
3+
class CData(_CDataBase): ... # type: ignore
4+
5+
class _CSignatureTime(CData):
6+
time: int
7+
offset: int
8+
9+
class _CSignature(CData):
10+
name: CData
11+
email: CData
12+
when: _CSignatureTime
13+
14+
class _COid(CData):
15+
id: CData
16+
17+
class _CHunk(CData):
18+
boundary: CData
19+
final_commit_id: _COid
20+
final_signature: _CSignature
21+
final_start_line_number: int
22+
lines_in_hunk: int
23+
orig_commit_id: _COid
24+
orig_path: str
25+
orig_signature: _CSignature
26+
orig_start_line_number: int
27+

pygit2/blame.py

+25-19
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,42 @@
2323
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
2424
# Boston, MA 02110-1301, USA.
2525

26+
from __future__ import annotations
27+
28+
from typing import TYPE_CHECKING, cast
29+
2630
# Import from pygit2
2731
from ._pygit2 import Oid, Signature
2832
from .ffi import C, ffi
29-
from .utils import GenericIterator
33+
from .utils import GenericIterator, buffer_to_bytes, maybe_string
34+
35+
if TYPE_CHECKING:
36+
from _cffi_backend import _CDataBase as CData
3037

38+
from ._ctyping import _CHunk, _CSignature
39+
from .repository import BaseRepository
3140

32-
def wrap_signature(csig):
41+
42+
def wrap_signature(csig: _CSignature):
3343
if not csig:
3444
return None
3545

3646
return Signature(
37-
ffi.string(csig.name).decode('utf-8'),
38-
ffi.string(csig.email).decode('utf-8'),
47+
cast(str, maybe_string(csig.name)),
48+
cast(str, maybe_string(csig.email)),
3949
csig.when.time,
4050
csig.when.offset,
4151
'utf-8',
4252
)
4353

4454

4555
class BlameHunk:
56+
if TYPE_CHECKING:
57+
_blame: Blame
58+
_hunk: _CHunk
59+
4660
@classmethod
47-
def _from_c(cls, blame, ptr):
61+
def _from_c(cls, blame: Blame, ptr: _CHunk):
4862
hunk = cls.__new__(cls)
4963
hunk._blame = blame
5064
hunk._hunk = ptr
@@ -73,9 +87,7 @@ def final_committer(self):
7387

7488
@property
7589
def final_commit_id(self):
76-
return Oid(
77-
raw=bytes(ffi.buffer(ffi.addressof(self._hunk, 'final_commit_id'))[:])
78-
)
90+
return Oid(raw=buffer_to_bytes(ffi.addressof(self._hunk, 'final_commit_id')))
7991

8092
@property
8193
def orig_start_line_number(self):
@@ -89,23 +101,17 @@ def orig_committer(self):
89101

90102
@property
91103
def orig_commit_id(self):
92-
return Oid(
93-
raw=bytes(ffi.buffer(ffi.addressof(self._hunk, 'orig_commit_id'))[:])
94-
)
104+
return Oid(raw=buffer_to_bytes(ffi.addressof(self._hunk, 'orig_commit_id')))
95105

96106
@property
97107
def orig_path(self):
98108
"""Original path"""
99-
path = self._hunk.orig_path
100-
if not path:
101-
return None
102-
103-
return ffi.string(path).decode('utf-8')
109+
return maybe_string(self._hunk.orig_path)
104110

105111

106112
class Blame:
107113
@classmethod
108-
def _from_c(cls, repo, ptr):
114+
def _from_c(cls, repo: BaseRepository, ptr: CData):
109115
blame = cls.__new__(cls)
110116
blame._repo = repo
111117
blame._blame = ptr
@@ -117,14 +123,14 @@ def __del__(self):
117123
def __len__(self):
118124
return C.git_blame_get_hunk_count(self._blame)
119125

120-
def __getitem__(self, index):
126+
def __getitem__(self, index: int):
121127
chunk = C.git_blame_get_hunk_byindex(self._blame, index)
122128
if not chunk:
123129
raise IndexError
124130

125131
return BlameHunk._from_c(self, chunk)
126132

127-
def for_line(self, line_no):
133+
def for_line(self, line_no: int) -> BlameHunk:
128134
"""
129135
Returns the <BlameHunk> object for a given line given its number in the
130136
current Blame.

0 commit comments

Comments
 (0)