Skip to content

Commit 44fd9dc

Browse files
igorp-collaboraJohnVillalovos
authored andcommitted
feat(api): Narrow down return type of download methods using typing.overload
Currently the download methods such as `ProjectJob.artifacts` have return type set to `Optional[Union[bytes, Iterator[Any]]]` which means they return either `None` or `bytes` or `Iterator[Any]`. However, the actual return type is determined by the passed `streamed` and `iterator` arguments. Using `@typing.overload` decorator it is possible to return a single type based on the passed arguments. Add overloads in the following order to all download methods: 1. If `streamed=False` and `iterator=False` return `bytes`. This is the default argument values therefore it should be first as it will be used to lookup default arguments. 2. If `iterator=True` return `Iterator[Any]`. This can be combined with both `streamed=True` and `streamed=False`. 3. If `streamed=True` and `iterator=False` return `None`. In this case `action` argument can be set to a callable that accepts `bytes`. Signed-off-by: Igor Ponomarev <igor.ponomarev@collabora.com>
1 parent e4c5c74 commit 44fd9dc

File tree

9 files changed

+529
-6
lines changed

9 files changed

+529
-6
lines changed

gitlab/mixins.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
Dict,
77
Iterator,
88
List,
9+
Literal,
910
Optional,
11+
overload,
1012
Tuple,
1113
Type,
1214
TYPE_CHECKING,
@@ -612,6 +614,39 @@ class DownloadMixin(_RestObjectBase):
612614
_updated_attrs: Dict[str, Any]
613615
manager: base.RESTManager
614616

617+
@overload
618+
def download(
619+
self,
620+
streamed: Literal[False] = False,
621+
action: None = None,
622+
chunk_size: int = 1024,
623+
*,
624+
iterator: Literal[False] = False,
625+
**kwargs: Any,
626+
) -> bytes: ...
627+
628+
@overload
629+
def download(
630+
self,
631+
streamed: bool = False,
632+
action: None = None,
633+
chunk_size: int = 1024,
634+
*,
635+
iterator: Literal[True] = True,
636+
**kwargs: Any,
637+
) -> Iterator[Any]: ...
638+
639+
@overload
640+
def download(
641+
self,
642+
streamed: Literal[True] = True,
643+
action: Optional[Callable[[bytes], None]] = None,
644+
chunk_size: int = 1024,
645+
*,
646+
iterator: Literal[False] = False,
647+
**kwargs: Any,
648+
) -> None: ...
649+
615650
@cli.register_custom_action(cls_names=("GroupExport", "ProjectExport"))
616651
@exc.on_http_error(exc.GitlabGetError)
617652
def download(

gitlab/v4/objects/artifacts.py

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,16 @@
33
https://docs.gitlab.com/ee/api/job_artifacts.html
44
"""
55

6-
from typing import Any, Callable, Iterator, Optional, TYPE_CHECKING, Union
6+
from typing import (
7+
Any,
8+
Callable,
9+
Iterator,
10+
Literal,
11+
Optional,
12+
overload,
13+
TYPE_CHECKING,
14+
Union,
15+
)
716

817
import requests
918

@@ -43,6 +52,45 @@ def delete(self, **kwargs: Any) -> None:
4352
assert path is not None
4453
self.gitlab.http_delete(path, **kwargs)
4554

55+
@overload
56+
def download(
57+
self,
58+
ref_name: str,
59+
job: str,
60+
streamed: Literal[False] = False,
61+
action: None = None,
62+
chunk_size: int = 1024,
63+
*,
64+
iterator: Literal[False] = False,
65+
**kwargs: Any,
66+
) -> bytes: ...
67+
68+
@overload
69+
def download(
70+
self,
71+
ref_name: str,
72+
job: str,
73+
streamed: bool = False,
74+
action: None = None,
75+
chunk_size: int = 1024,
76+
*,
77+
iterator: Literal[True] = True,
78+
**kwargs: Any,
79+
) -> Iterator[Any]: ...
80+
81+
@overload
82+
def download(
83+
self,
84+
ref_name: str,
85+
job: str,
86+
streamed: Literal[True] = True,
87+
action: Optional[Callable[[bytes], None]] = None,
88+
chunk_size: int = 1024,
89+
*,
90+
iterator: Literal[False] = False,
91+
**kwargs: Any,
92+
) -> None: ...
93+
4694
@cli.register_custom_action(
4795
cls_names="ProjectArtifactManager",
4896
required=("ref_name", "job"),
@@ -94,6 +142,48 @@ def download(
94142
result, streamed, action, chunk_size, iterator=iterator
95143
)
96144

145+
@overload
146+
def raw(
147+
self,
148+
ref_name: str,
149+
artifact_path: str,
150+
job: str,
151+
streamed: Literal[False] = False,
152+
action: None = None,
153+
chunk_size: int = 1024,
154+
*,
155+
iterator: Literal[False] = False,
156+
**kwargs: Any,
157+
) -> bytes: ...
158+
159+
@overload
160+
def raw(
161+
self,
162+
ref_name: str,
163+
artifact_path: str,
164+
job: str,
165+
streamed: bool = False,
166+
action: None = None,
167+
chunk_size: int = 1024,
168+
*,
169+
iterator: Literal[True] = True,
170+
**kwargs: Any,
171+
) -> Iterator[Any]: ...
172+
173+
@overload
174+
def raw(
175+
self,
176+
ref_name: str,
177+
artifact_path: str,
178+
job: str,
179+
streamed: Literal[True] = True,
180+
action: Optional[Callable[[bytes], None]] = None,
181+
chunk_size: int = 1024,
182+
*,
183+
iterator: Literal[False] = False,
184+
**kwargs: Any,
185+
) -> None: ...
186+
97187
@cli.register_custom_action(
98188
cls_names="ProjectArtifactManager",
99189
required=("ref_name", "artifact_path", "job"),

gitlab/v4/objects/jobs.py

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1-
from typing import Any, Callable, cast, Dict, Iterator, Optional, TYPE_CHECKING, Union
1+
from typing import (
2+
Any,
3+
Callable,
4+
cast,
5+
Dict,
6+
Iterator,
7+
Literal,
8+
Optional,
9+
overload,
10+
TYPE_CHECKING,
11+
Union,
12+
)
213

314
import requests
415

@@ -115,6 +126,39 @@ def delete_artifacts(self, **kwargs: Any) -> None:
115126
path = f"{self.manager.path}/{self.encoded_id}/artifacts"
116127
self.manager.gitlab.http_delete(path, **kwargs)
117128

129+
@overload
130+
def artifacts(
131+
self,
132+
streamed: Literal[False] = False,
133+
action: None = None,
134+
chunk_size: int = 1024,
135+
*,
136+
iterator: Literal[False] = False,
137+
**kwargs: Any,
138+
) -> bytes: ...
139+
140+
@overload
141+
def artifacts(
142+
self,
143+
streamed: bool = False,
144+
action: None = None,
145+
chunk_size: int = 1024,
146+
*,
147+
iterator: Literal[True] = True,
148+
**kwargs: Any,
149+
) -> Iterator[Any]: ...
150+
151+
@overload
152+
def artifacts(
153+
self,
154+
streamed: Literal[True] = True,
155+
action: Optional[Callable[[bytes], None]] = None,
156+
chunk_size: int = 1024,
157+
*,
158+
iterator: Literal[False] = False,
159+
**kwargs: Any,
160+
) -> None: ...
161+
118162
@cli.register_custom_action(cls_names="ProjectJob")
119163
@exc.on_http_error(exc.GitlabGetError)
120164
def artifacts(
@@ -156,6 +200,42 @@ def artifacts(
156200
result, streamed, action, chunk_size, iterator=iterator
157201
)
158202

203+
@overload
204+
def artifact(
205+
self,
206+
path: str,
207+
streamed: Literal[False] = False,
208+
action: None = None,
209+
chunk_size: int = 1024,
210+
*,
211+
iterator: Literal[False] = False,
212+
**kwargs: Any,
213+
) -> bytes: ...
214+
215+
@overload
216+
def artifact(
217+
self,
218+
path: str,
219+
streamed: bool = False,
220+
action: None = None,
221+
chunk_size: int = 1024,
222+
*,
223+
iterator: Literal[True] = True,
224+
**kwargs: Any,
225+
) -> Iterator[Any]: ...
226+
227+
@overload
228+
def artifact(
229+
self,
230+
path: str,
231+
streamed: Literal[True] = True,
232+
action: Optional[Callable[[bytes], None]] = None,
233+
chunk_size: int = 1024,
234+
*,
235+
iterator: Literal[False] = False,
236+
**kwargs: Any,
237+
) -> None: ...
238+
159239
@cli.register_custom_action(cls_names="ProjectJob")
160240
@exc.on_http_error(exc.GitlabGetError)
161241
def artifact(
@@ -199,6 +279,39 @@ def artifact(
199279
result, streamed, action, chunk_size, iterator=iterator
200280
)
201281

282+
@overload
283+
def trace(
284+
self,
285+
streamed: Literal[False] = False,
286+
action: None = None,
287+
chunk_size: int = 1024,
288+
*,
289+
iterator: Literal[False] = False,
290+
**kwargs: Any,
291+
) -> bytes: ...
292+
293+
@overload
294+
def trace(
295+
self,
296+
streamed: bool = False,
297+
action: None = None,
298+
chunk_size: int = 1024,
299+
*,
300+
iterator: Literal[True] = True,
301+
**kwargs: Any,
302+
) -> Iterator[Any]: ...
303+
304+
@overload
305+
def trace(
306+
self,
307+
streamed: Literal[True] = True,
308+
action: Optional[Callable[[bytes], None]] = None,
309+
chunk_size: int = 1024,
310+
*,
311+
iterator: Literal[False] = False,
312+
**kwargs: Any,
313+
) -> None: ...
314+
202315
@cli.register_custom_action(cls_names="ProjectJob")
203316
@exc.on_http_error(exc.GitlabGetError)
204317
def trace(

gitlab/v4/objects/packages.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
Callable,
1212
cast,
1313
Iterator,
14+
Literal,
1415
Optional,
16+
overload,
1517
TYPE_CHECKING,
1618
Union,
1719
)
@@ -122,6 +124,48 @@ def upload(
122124
attrs.update(server_data)
123125
return self._obj_cls(self, attrs=attrs)
124126

127+
@overload
128+
def download(
129+
self,
130+
package_name: str,
131+
package_version: str,
132+
file_name: str,
133+
streamed: Literal[False] = False,
134+
action: None = None,
135+
chunk_size: int = 1024,
136+
*,
137+
iterator: Literal[False] = False,
138+
**kwargs: Any,
139+
) -> bytes: ...
140+
141+
@overload
142+
def download(
143+
self,
144+
package_name: str,
145+
package_version: str,
146+
file_name: str,
147+
streamed: bool = False,
148+
action: None = None,
149+
chunk_size: int = 1024,
150+
*,
151+
iterator: Literal[True] = True,
152+
**kwargs: Any,
153+
) -> Iterator[Any]: ...
154+
155+
@overload
156+
def download(
157+
self,
158+
package_name: str,
159+
package_version: str,
160+
file_name: str,
161+
streamed: Literal[True] = True,
162+
action: Optional[Callable[[bytes], None]] = None,
163+
chunk_size: int = 1024,
164+
*,
165+
iterator: Literal[False] = False,
166+
**kwargs: Any,
167+
) -> None: ...
168+
125169
@cli.register_custom_action(
126170
cls_names="GenericPackageManager",
127171
required=("package_name", "package_version", "file_name"),

0 commit comments

Comments
 (0)