2323# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
2424# Boston, MA 02110-1301, USA.
2525
26+ from __future__ import annotations
27+
2628import contextlib
2729import os
30+ from types import TracebackType
31+ from typing import TYPE_CHECKING , Any , Generic , TypeVar , cast
2832
2933# Import from pygit2
3034from .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