Skip to content

Commit

Permalink
add typing for blame.py and add _ctyping
Browse files Browse the repository at this point in the history
  • Loading branch information
DinhHuy2010 committed Dec 30, 2024
1 parent 720881e commit 0e55fb3
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 19 deletions.
1 change: 1 addition & 0 deletions pygit2/_ctyping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# placeholder for pyright
27 changes: 27 additions & 0 deletions pygit2/_ctyping.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from _cffi_backend import _CDataBase

class CData(_CDataBase): ... # type: ignore

class _CSignatureTime(CData):
time: int
offset: int

class _CSignature(CData):
name: CData
email: CData
when: _CSignatureTime

class _COid(CData):
id: CData

class _CHunk(CData):
boundary: CData
final_commit_id: _COid
final_signature: _CSignature
final_start_line_number: int
lines_in_hunk: int
orig_commit_id: _COid
orig_path: str
orig_signature: _CSignature
orig_start_line_number: int

44 changes: 25 additions & 19 deletions pygit2/blame.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,42 @@
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.

from __future__ import annotations

from typing import TYPE_CHECKING, cast

# Import from pygit2
from ._pygit2 import Oid, Signature
from .ffi import C, ffi
from .utils import GenericIterator
from .utils import GenericIterator, buffer_to_bytes, maybe_string

if TYPE_CHECKING:
from _cffi_backend import _CDataBase as CData

from ._ctyping import _CHunk, _CSignature
from .repository import BaseRepository

def wrap_signature(csig):

def wrap_signature(csig: _CSignature):
if not csig:
return None

return Signature(
ffi.string(csig.name).decode('utf-8'),
ffi.string(csig.email).decode('utf-8'),
cast(str, maybe_string(csig.name)),
cast(str, maybe_string(csig.email)),
csig.when.time,
csig.when.offset,
'utf-8',
)


class BlameHunk:
if TYPE_CHECKING:
_blame: Blame
_hunk: _CHunk

@classmethod
def _from_c(cls, blame, ptr):
def _from_c(cls, blame: Blame, ptr: _CHunk):
hunk = cls.__new__(cls)
hunk._blame = blame
hunk._hunk = ptr
Expand Down Expand Up @@ -73,9 +87,7 @@ def final_committer(self):

@property
def final_commit_id(self):
return Oid(
raw=bytes(ffi.buffer(ffi.addressof(self._hunk, 'final_commit_id'))[:])
)
return Oid(raw=buffer_to_bytes(ffi.addressof(self._hunk, 'final_commit_id')))

@property
def orig_start_line_number(self):
Expand All @@ -89,23 +101,17 @@ def orig_committer(self):

@property
def orig_commit_id(self):
return Oid(
raw=bytes(ffi.buffer(ffi.addressof(self._hunk, 'orig_commit_id'))[:])
)
return Oid(raw=buffer_to_bytes(ffi.addressof(self._hunk, 'orig_commit_id')))

@property
def orig_path(self):
"""Original path"""
path = self._hunk.orig_path
if not path:
return None

return ffi.string(path).decode('utf-8')
return maybe_string(self._hunk.orig_path)


class Blame:
@classmethod
def _from_c(cls, repo, ptr):
def _from_c(cls, repo: BaseRepository, ptr: CData):
blame = cls.__new__(cls)
blame._repo = repo
blame._blame = ptr
Expand All @@ -117,14 +123,14 @@ def __del__(self):
def __len__(self):
return C.git_blame_get_hunk_count(self._blame)

def __getitem__(self, index):
def __getitem__(self, index: int):
chunk = C.git_blame_get_hunk_byindex(self._blame, index)
if not chunk:
raise IndexError

return BlameHunk._from_c(self, chunk)

def for_line(self, line_no):
def for_line(self, line_no: int) -> BlameHunk:
"""
Returns the <BlameHunk> object for a given line given its number in the
current Blame.
Expand Down

0 comments on commit 0e55fb3

Please sign in to comment.