1
1
import base64
2
+ from typing import Any ,Callable ,cast ,Dict ,List ,Optional ,TYPE_CHECKING
3
+
4
+ import requests
2
5
3
6
from gitlab import cli
4
7
from gitlab import exceptions as exc
22
25
class ProjectFile (SaveMixin ,ObjectDeleteMixin ,RESTObject ):
23
26
_id_attr = "file_path"
24
27
_short_print_attr = "file_path"
28
+ file_path :str
29
+ manager :"ProjectFileManager"
25
30
26
31
def decode (self )-> bytes :
27
32
"""Returns the decoded content of the file.
@@ -31,7 +36,11 @@ def decode(self) -> bytes:
31
36
"""
32
37
return base64 .b64decode (self .content )
33
38
34
- def save (self ,branch ,commit_message ,** kwargs ):
39
+ # NOTE(jlvillal): Signature doesn't match SaveMixin.save() so ignore
40
+ # type error
41
+ def save (# type: ignore
42
+ self ,branch :str ,commit_message :str ,** kwargs :Any
43
+ )-> None :
35
44
"""Save the changes made to the file to the server.
36
45
37
46
The object is updated to match what the server returns.
@@ -50,7 +59,12 @@ def save(self, branch, commit_message, **kwargs):
50
59
self .file_path = self .file_path .replace ("/" ,"%2F" )
51
60
super (ProjectFile ,self ).save (** kwargs )
52
61
53
- def delete (self ,branch ,commit_message ,** kwargs ):
62
+ @exc .on_http_error (exc .GitlabDeleteError )
63
+ # NOTE(jlvillal): Signature doesn't match DeleteMixin.delete() so ignore
64
+ # type error
65
+ def delete (# type: ignore
66
+ self ,branch :str ,commit_message :str ,** kwargs :Any
67
+ )-> None :
54
68
"""Delete the file from the server.
55
69
56
70
Args:
@@ -80,7 +94,11 @@ class ProjectFileManager(GetMixin, CreateMixin, UpdateMixin, DeleteMixin, RESTMa
80
94
)
81
95
82
96
@cli .register_custom_action ("ProjectFileManager" , ("file_path" ,"ref" ))
83
- def get (self ,file_path ,ref ,** kwargs ):
97
+ # NOTE(jlvillal): Signature doesn't match UpdateMixin.update() so ignore
98
+ # type error
99
+ def get (# type: ignore
100
+ self ,file_path :str ,ref :str ,** kwargs :Any
101
+ )-> ProjectFile :
84
102
"""Retrieve a single file.
85
103
86
104
Args:
@@ -95,15 +113,17 @@ def get(self, file_path, ref, **kwargs):
95
113
Returns:
96
114
object: The generated RESTObject
97
115
"""
98
- return GetMixin .get (self ,file_path ,ref = ref ,** kwargs )
116
+ return cast ( ProjectFile , GetMixin .get (self ,file_path ,ref = ref ,** kwargs ) )
99
117
100
118
@cli .register_custom_action (
101
119
"ProjectFileManager" ,
102
120
("file_path" ,"branch" ,"content" ,"commit_message" ),
103
121
("encoding" ,"author_email" ,"author_name" ),
104
122
)
105
123
@exc .on_http_error (exc .GitlabCreateError )
106
- def create (self ,data ,** kwargs ):
124
+ def create (
125
+ self ,data :Optional [Dict [str ,Any ]]= None ,** kwargs :Any
126
+ )-> ProjectFile :
107
127
"""Create a new object.
108
128
109
129
Args:
@@ -120,15 +140,23 @@ def create(self, data, **kwargs):
120
140
GitlabCreateError: If the server cannot perform the request
121
141
"""
122
142
143
+ if TYPE_CHECKING :
144
+ assert data is not None
123
145
self ._check_missing_create_attrs (data )
124
146
new_data = data .copy ()
125
147
file_path = new_data .pop ("file_path" ).replace ("/" ,"%2F" )
126
148
path = f"{ self .path } /{ file_path } "
127
149
server_data = self .gitlab .http_post (path ,post_data = new_data ,** kwargs )
150
+ if TYPE_CHECKING :
151
+ assert isinstance (server_data ,dict )
128
152
return self ._obj_cls (self ,server_data )
129
153
130
154
@exc .on_http_error (exc .GitlabUpdateError )
131
- def update (self ,file_path ,new_data = None ,** kwargs ):
155
+ # NOTE(jlvillal): Signature doesn't match UpdateMixin.update() so ignore
156
+ # type error
157
+ def update (# type: ignore
158
+ self ,file_path :str ,new_data :Optional [Dict [str ,Any ]]= None ,** kwargs :Any
159
+ )-> Dict [str ,Any ]:
132
160
"""Update an object on the server.
133
161
134
162
Args:
@@ -149,13 +177,20 @@ def update(self, file_path, new_data=None, **kwargs):
149
177
data ["file_path" ]= file_path
150
178
path = f"{ self .path } /{ file_path } "
151
179
self ._check_missing_update_attrs (data )
152
- return self .gitlab .http_put (path ,post_data = data ,** kwargs )
180
+ result = self .gitlab .http_put (path ,post_data = data ,** kwargs )
181
+ if TYPE_CHECKING :
182
+ assert isinstance (result ,dict )
183
+ return result
153
184
154
185
@cli .register_custom_action (
155
186
"ProjectFileManager" , ("file_path" ,"branch" ,"commit_message" )
156
187
)
157
188
@exc .on_http_error (exc .GitlabDeleteError )
158
- def delete (self ,file_path ,branch ,commit_message ,** kwargs ):
189
+ # NOTE(jlvillal): Signature doesn't match DeleteMixin.delete() so ignore
190
+ # type error
191
+ def delete (# type: ignore
192
+ self ,file_path :str ,branch :str ,commit_message :str ,** kwargs :Any
193
+ )-> None :
159
194
"""Delete a file on the server.
160
195
161
196
Args:
@@ -175,8 +210,14 @@ def delete(self, file_path, branch, commit_message, **kwargs):
175
210
@cli .register_custom_action ("ProjectFileManager" , ("file_path" ,"ref" ))
176
211
@exc .on_http_error (exc .GitlabGetError )
177
212
def raw (
178
- self ,file_path ,ref ,streamed = False ,action = None ,chunk_size = 1024 ,** kwargs
179
- ):
213
+ self ,
214
+ file_path :str ,
215
+ ref :str ,
216
+ streamed :bool = False ,
217
+ action :Optional [Callable [...,Any ]]= None ,
218
+ chunk_size :int = 1024 ,
219
+ ** kwargs :Any ,
220
+ )-> Optional [bytes ]:
180
221
"""Return the content of a file for a commit.
181
222
182
223
Args:
@@ -203,11 +244,13 @@ def raw(
203
244
result = self .gitlab .http_get (
204
245
path ,query_data = query_data ,streamed = streamed ,raw = True ,** kwargs
205
246
)
247
+ if TYPE_CHECKING :
248
+ assert isinstance (result ,requests .Response )
206
249
return utils .response_content (result ,streamed ,action ,chunk_size )
207
250
208
251
@cli .register_custom_action ("ProjectFileManager" , ("file_path" ,"ref" ))
209
252
@exc .on_http_error (exc .GitlabListError )
210
- def blame (self ,file_path ,ref ,** kwargs ) :
253
+ def blame (self ,file_path : str ,ref : str ,** kwargs : Any ) -> List [ Dict [ str , Any ]] :
211
254
"""Return the content of a file for a commit.
212
255
213
256
Args:
@@ -225,4 +268,7 @@ def blame(self, file_path, ref, **kwargs):
225
268
file_path = file_path .replace ("/" ,"%2F" ).replace ("." ,"%2E" )
226
269
path = f"{ self .path } /{ file_path } /blame"
227
270
query_data = {"ref" :ref }
228
- return self .gitlab .http_list (path ,query_data ,** kwargs )
271
+ result = self .gitlab .http_list (path ,query_data ,** kwargs )
272
+ if TYPE_CHECKING :
273
+ assert isinstance (result ,list )
274
+ return result