Skip to content

Commit 95b003f

Browse files
committed
add typing to utils.py
1 parent 5fc3b70 commit 95b003f

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

pygit2/utils.py

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,33 @@
2323
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
2424
# Boston, MA 02110-1301, USA.
2525

26+
from __future__ import annotations
27+
2628
import contextlib
2729
import os
30+
from types import TracebackType
31+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast
2832

2933
# Import from pygit2
3034
from .ffi import C, ffi
3135

36+
if TYPE_CHECKING:
37+
from _typeshed import SupportsLenAndGetItem
38+
39+
_T = TypeVar('_T')
40+
3241

33-
def maybe_string(ptr):
42+
def maybe_string(ptr: Any) -> str | None:
3443
if not ptr:
3544
return None
3645

37-
return ffi.string(ptr).decode('utf8')
46+
out = ffi.string(ptr)
47+
if isinstance(out, bytes):
48+
out = out.decode('utf8')
49+
return out
3850

3951

40-
def to_bytes(s, encoding='utf-8', errors='strict'):
52+
def to_bytes(s: Any, encoding: str = 'utf-8', errors: str = 'strict') -> bytes | Any:
4153
if s == ffi.NULL or s is None:
4254
return ffi.NULL
4355

@@ -50,27 +62,27 @@ def to_bytes(s, encoding='utf-8', errors='strict'):
5062
return s.encode(encoding, errors)
5163

5264

53-
def to_str(s):
65+
def to_str(s: Any) -> str:
5466
if hasattr(s, '__fspath__'):
5567
s = os.fspath(s)
5668

57-
if type(s) is str:
69+
if isinstance(s, str):
5870
return s
5971

60-
if type(s) is bytes:
72+
if isinstance(s, bytes):
6173
return s.decode()
6274

6375
raise TypeError(f'unexpected type "{repr(s)}"')
6476

6577

66-
def ptr_to_bytes(ptr_cdata):
78+
def ptr_to_bytes(ptr_cdata: Any) -> bytes:
6779
"""
6880
Convert a pointer coming from C code (<cdata 'some_type *'>)
6981
to a byte buffer containing the address that the pointer refers to.
7082
"""
7183

7284
pp = ffi.new('void **', ptr_cdata)
73-
return bytes(ffi.buffer(pp)[:])
85+
return bytes(ffi.buffer(pp)[:]) # type: ignore
7486

7587

7688
@contextlib.contextmanager
@@ -80,15 +92,15 @@ def new_git_strarray():
8092
C.git_strarray_dispose(strarray)
8193

8294

83-
def strarray_to_strings(arr):
95+
def strarray_to_strings(arr: Any) -> list[str]:
8496
"""
8597
Return a list of strings from a git_strarray pointer.
8698
8799
Free the strings contained in the git_strarry, this means it won't be usable after
88100
calling this function.
89101
"""
90102
try:
91-
return [ffi.string(arr.strings[i]).decode('utf-8') for i in range(arr.count)]
103+
return [ffi.string(arr.strings[i]).decode('utf-8') for i in range(arr.count)] # type: ignore
92104
finally:
93105
C.git_strarray_dispose(arr)
94106

@@ -113,18 +125,20 @@ class StrArray:
113125
contents of 'struct' only remain valid within the StrArray context.
114126
"""
115127

116-
def __init__(self, l):
128+
def __init__(self, listarg: Any):
117129
# Allow passing in None as lg2 typically considers them the same as empty
118-
if l is None:
130+
if listarg is None:
119131
self.__array = ffi.NULL
120132
return
121133

122-
if not isinstance(l, (list, tuple)):
134+
if not isinstance(listarg, (list, tuple)):
123135
raise TypeError('Value must be a list')
124136

125-
strings = [None] * len(l)
126-
for i in range(len(l)):
127-
li = l[i]
137+
listarg = cast(list[Any], listarg)
138+
139+
strings: list[Any] = [None] * len(listarg)
140+
for i in range(len(listarg)):
141+
li = listarg[i]
128142
if not isinstance(li, str) and not hasattr(li, '__fspath__'):
129143
raise TypeError('Value must be a string or PathLike object')
130144

@@ -137,14 +151,16 @@ def __init__(self, l):
137151
def __enter__(self):
138152
return self
139153

140-
def __exit__(self, type, value, traceback):
154+
def __exit__(
155+
self, type: type[BaseException], value: BaseException, traceback: TracebackType
156+
) -> None:
141157
pass
142158

143159
@property
144160
def ptr(self):
145161
return self.__array
146162

147-
def assign_to(self, git_strarray):
163+
def assign_to(self, git_strarray: Any):
148164
if self.__array == ffi.NULL:
149165
git_strarray.strings = ffi.NULL
150166
git_strarray.count = 0
@@ -153,22 +169,22 @@ def assign_to(self, git_strarray):
153169
git_strarray.count = len(self.__strings)
154170

155171

156-
class GenericIterator:
172+
class GenericIterator(Generic[_T]):
157173
"""Helper to easily implement an iterator.
158174
159175
The constructor gets a container which must implement __len__ and
160176
__getitem__
161177
"""
162178

163-
def __init__(self, container):
179+
def __init__(self, container: SupportsLenAndGetItem[_T]):
164180
self.container = container
165181
self.length = len(container)
166182
self.idx = 0
167183

168-
def next(self):
184+
def next(self) -> _T:
169185
return self.__next__()
170186

171-
def __next__(self):
187+
def __next__(self) -> _T:
172188
idx = self.idx
173189
if idx >= self.length:
174190
raise StopIteration

0 commit comments

Comments
 (0)