23
23
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
24
24
# Boston, MA 02110-1301, USA.
25
25
26
+ from __future__ import annotations
27
+
26
28
import contextlib
27
29
import os
30
+ from types import TracebackType
31
+ from typing import TYPE_CHECKING , Any , Generic , TypeVar , cast
28
32
29
33
# Import from pygit2
30
34
from .ffi import C , ffi
31
35
36
+ if TYPE_CHECKING :
37
+ from _typeshed import SupportsLenAndGetItem
38
+
39
+ _T = TypeVar ('_T' )
40
+
32
41
33
- def maybe_string (ptr ) :
42
+ def maybe_string (ptr : Any ) -> str | None :
34
43
if not ptr :
35
44
return None
36
45
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
38
50
39
51
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 :
41
53
if s == ffi .NULL or s is None :
42
54
return ffi .NULL
43
55
@@ -50,27 +62,27 @@ def to_bytes(s, encoding='utf-8', errors='strict'):
50
62
return s .encode (encoding , errors )
51
63
52
64
53
- def to_str (s ) :
65
+ def to_str (s : Any ) -> str :
54
66
if hasattr (s , '__fspath__' ):
55
67
s = os .fspath (s )
56
68
57
- if type ( s ) is str :
69
+ if isinstance ( s , str ) :
58
70
return s
59
71
60
- if type ( s ) is bytes :
72
+ if isinstance ( s , bytes ) :
61
73
return s .decode ()
62
74
63
75
raise TypeError (f'unexpected type "{ repr (s )} "' )
64
76
65
77
66
- def ptr_to_bytes (ptr_cdata ) :
78
+ def ptr_to_bytes (ptr_cdata : Any ) -> bytes :
67
79
"""
68
80
Convert a pointer coming from C code (<cdata 'some_type *'>)
69
81
to a byte buffer containing the address that the pointer refers to.
70
82
"""
71
83
72
84
pp = ffi .new ('void **' , ptr_cdata )
73
- return bytes (ffi .buffer (pp )[:])
85
+ return bytes (ffi .buffer (pp )[:]) # type: ignore
74
86
75
87
76
88
@contextlib .contextmanager
@@ -80,15 +92,15 @@ def new_git_strarray():
80
92
C .git_strarray_dispose (strarray )
81
93
82
94
83
- def strarray_to_strings (arr ) :
95
+ def strarray_to_strings (arr : Any ) -> list [ str ] :
84
96
"""
85
97
Return a list of strings from a git_strarray pointer.
86
98
87
99
Free the strings contained in the git_strarry, this means it won't be usable after
88
100
calling this function.
89
101
"""
90
102
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
92
104
finally :
93
105
C .git_strarray_dispose (arr )
94
106
@@ -113,18 +125,20 @@ class StrArray:
113
125
contents of 'struct' only remain valid within the StrArray context.
114
126
"""
115
127
116
- def __init__ (self , l ):
128
+ def __init__ (self , listarg : Any ):
117
129
# Allow passing in None as lg2 typically considers them the same as empty
118
- if l is None :
130
+ if listarg is None :
119
131
self .__array = ffi .NULL
120
132
return
121
133
122
- if not isinstance (l , (list , tuple )):
134
+ if not isinstance (listarg , (list , tuple )):
123
135
raise TypeError ('Value must be a list' )
124
136
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 ]
128
142
if not isinstance (li , str ) and not hasattr (li , '__fspath__' ):
129
143
raise TypeError ('Value must be a string or PathLike object' )
130
144
@@ -137,14 +151,16 @@ def __init__(self, l):
137
151
def __enter__ (self ):
138
152
return self
139
153
140
- def __exit__ (self , type , value , traceback ):
154
+ def __exit__ (
155
+ self , type : type [BaseException ], value : BaseException , traceback : TracebackType
156
+ ) -> None :
141
157
pass
142
158
143
159
@property
144
160
def ptr (self ):
145
161
return self .__array
146
162
147
- def assign_to (self , git_strarray ):
163
+ def assign_to (self , git_strarray : Any ):
148
164
if self .__array == ffi .NULL :
149
165
git_strarray .strings = ffi .NULL
150
166
git_strarray .count = 0
@@ -153,22 +169,22 @@ def assign_to(self, git_strarray):
153
169
git_strarray .count = len (self .__strings )
154
170
155
171
156
- class GenericIterator :
172
+ class GenericIterator ( Generic [ _T ]) :
157
173
"""Helper to easily implement an iterator.
158
174
159
175
The constructor gets a container which must implement __len__ and
160
176
__getitem__
161
177
"""
162
178
163
- def __init__ (self , container ):
179
+ def __init__ (self , container : SupportsLenAndGetItem [ _T ] ):
164
180
self .container = container
165
181
self .length = len (container )
166
182
self .idx = 0
167
183
168
- def next (self ):
184
+ def next (self ) -> _T :
169
185
return self .__next__ ()
170
186
171
- def __next__ (self ):
187
+ def __next__ (self ) -> _T :
172
188
idx = self .idx
173
189
if idx >= self .length :
174
190
raise StopIteration
0 commit comments