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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy