| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 387a140 commit 09b3b22
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,7 +33,6 @@ | |||
| 33 | 33 | import gitlab | |
| 34 | 34 | from gitlab import base, cli | |
| 35 | 35 | from gitlab import exceptions as exc | |
| 36 | - from gitlab import types as g_types | ||
| 37 | 36 | from gitlab import utils | |
| 38 | 37 | ||
| 39 | 38 | __all__ = [ | |
@@ -214,8 +213,8 @@ def list(self, **kwargs: Any) -> Union[base.RESTObjectList, List[base.RESTObject | |||
| 214 | 213 | GitlabListError: If the server cannot perform the request | |
| 215 | 214 | """ | |
| 216 | 215 | ||
| 217 | - # Duplicate data to avoid messing with what the user sent us | ||
| 218 | - data = kwargs.copy() | ||
| 216 | + data, _ = utils._transform_types(kwargs, self._types, transform_files=False) | ||
| 217 | + | ||
| 219 | 218 | if self.gitlab.per_page: | |
| 220 | 219 | data.setdefault("per_page", self.gitlab.per_page) | |
| 221 | 220 | ||
@@ -226,13 +225,6 @@ def list(self, **kwargs: Any) -> Union[base.RESTObjectList, List[base.RESTObject | |||
| 226 | 225 | if self.gitlab.order_by: | |
| 227 | 226 | data.setdefault("order_by", self.gitlab.order_by) | |
| 228 | 227 | ||
| 229 | - # We get the attributes that need some special transformation | ||
| 230 | - if self._types: | ||
| 231 | - for attr_name, type_cls in self._types.items(): | ||
| 232 | - if attr_name in data.keys(): | ||
| 233 | - type_obj = type_cls(data[attr_name]) | ||
| 234 | - data[attr_name] = type_obj.get_for_api() | ||
| 235 | - | ||
| 236 | 228 | # Allow to overwrite the path, handy for custom listings | |
| 237 | 229 | path = data.pop("path", self.path) | |
| 238 | 230 | ||
@@ -298,23 +290,7 @@ def create( | |||
| 298 | 290 | data = {} | |
| 299 | 291 | ||
| 300 | 292 | self._check_missing_create_attrs(data) | |
| 301 | - files = {} | ||
| 302 | - | ||
| 303 | - # We get the attributes that need some special transformation | ||
| 304 | - if self._types: | ||
| 305 | - # Duplicate data to avoid messing with what the user sent us | ||
| 306 | - data = data.copy() | ||
| 307 | - for attr_name, type_cls in self._types.items(): | ||
| 308 | - if attr_name in data.keys(): | ||
| 309 | - type_obj = type_cls(data[attr_name]) | ||
| 310 | - | ||
| 311 | - # if the type if FileAttribute we need to pass the data as | ||
| 312 | - # file | ||
| 313 | - if isinstance(type_obj, g_types.FileAttribute): | ||
| 314 | - k = type_obj.get_file_name(attr_name) | ||
| 315 | - files[attr_name] = (k, data.pop(attr_name)) | ||
| 316 | - else: | ||
| 317 | - data[attr_name] = type_obj.get_for_api() | ||
| 293 | + data, files = utils._transform_types(data, self._types) | ||
| 318 | 294 | ||
| 319 | 295 | # Handle specific URL for creation | |
| 320 | 296 | path = kwargs.pop("path", self.path) | |
@@ -394,23 +370,7 @@ def update( | |||
| 394 | 370 | path = f"{self.path}/{utils.EncodedId(id)}" | |
| 395 | 371 | ||
| 396 | 372 | self._check_missing_update_attrs(new_data) | |
| 397 | - files = {} | ||
| 398 | - | ||
| 399 | - # We get the attributes that need some special transformation | ||
| 400 | - if self._types: | ||
| 401 | - # Duplicate data to avoid messing with what the user sent us | ||
| 402 | - new_data = new_data.copy() | ||
| 403 | - for attr_name, type_cls in self._types.items(): | ||
| 404 | - if attr_name in new_data.keys(): | ||
| 405 | - type_obj = type_cls(new_data[attr_name]) | ||
| 406 | - | ||
| 407 | - # if the type if FileAttribute we need to pass the data as | ||
| 408 | - # file | ||
| 409 | - if isinstance(type_obj, g_types.FileAttribute): | ||
| 410 | - k = type_obj.get_file_name(attr_name) | ||
| 411 | - files[attr_name] = (k, new_data.pop(attr_name)) | ||
| 412 | - else: | ||
| 413 | - new_data[attr_name] = type_obj.get_for_api() | ||
| 373 | + new_data, files = utils._transform_types(new_data, self._types) | ||
| 414 | 374 | ||
| 415 | 375 | http_method = self._get_update_method() | |
| 416 | 376 | result = http_method(path, post_data=new_data, files=files, **kwargs) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,10 +19,12 @@ | |||
| 19 | 19 | import traceback | |
| 20 | 20 | import urllib.parse | |
| 21 | 21 | import warnings | |
| 22 | - from typing import Any, Callable, Dict, Optional, Type, Union | ||
| 22 | + from typing import Any, Callable, Dict, Optional, Tuple, Type, Union | ||
| 23 | 23 | ||
| 24 | 24 | import requests | |
| 25 | 25 | ||
| 26 | + from gitlab import types | ||
| 27 | + | ||
| 26 | 28 | ||
| 27 | 29 | class _StdoutStream: | |
| 28 | 30 | def __call__(self, chunk: Any) -> None: | |
@@ -47,6 +49,39 @@ def response_content( | |||
| 47 | 49 | return None | |
| 48 | 50 | ||
| 49 | 51 | ||
| 52 | + def _transform_types( | ||
| 53 | + data: Dict[str, Any], custom_types: dict, *, transform_files: Optional[bool] = True | ||
| 54 | + ) -> Tuple[dict, dict]: | ||
| 55 | + """Copy the data dict with attributes that have custom types and transform them | ||
| 56 | + before being sent to the server. | ||
| 57 | + | ||
| 58 | + If ``transform_files`` is ``True`` (default), also populates the ``files`` dict for | ||
| 59 | + FileAttribute types with tuples to prepare fields for requests' MultipartEncoder: | ||
| 60 | + https://toolbelt.readthedocs.io/en/latest/user.html#multipart-form-data-encoder | ||
| 61 | + | ||
| 62 | + Returns: | ||
| 63 | + A tuple of the transformed data dict and files dict""" | ||
| 64 | + | ||
| 65 | + # Duplicate data to avoid messing with what the user sent us | ||
| 66 | + data = data.copy() | ||
| 67 | + files = {} | ||
| 68 | + | ||
| 69 | + for attr_name, type_cls in custom_types.items(): | ||
| 70 | + if attr_name not in data: | ||
| 71 | + continue | ||
| 72 | + | ||
| 73 | + type_obj = type_cls(data[attr_name]) | ||
| 74 | + | ||
| 75 | + # if the type if FileAttribute we need to pass the data as file | ||
| 76 | + if transform_files and isinstance(type_obj, types.FileAttribute): | ||
| 77 | + key = type_obj.get_file_name(attr_name) | ||
| 78 | + files[attr_name] = (key, data.pop(attr_name)) | ||
| 79 | + else: | ||
| 80 | + data[attr_name] = type_obj.get_for_api() | ||
| 81 | + | ||
| 82 | + return data, files | ||
| 83 | + | ||
| 84 | + | ||
| 50 | 85 | def copy_dict( | |
| 51 | 86 | *, | |
| 52 | 87 | src: Dict[str, Any], | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ | |||
| 18 | 18 | import json | |
| 19 | 19 | import warnings | |
| 20 | 20 | ||
| 21 | - from gitlab import utils | ||
| 21 | + from gitlab import types, utils | ||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | 24 | class TestEncodedId: | |
@@ -95,3 +95,30 @@ def test_warn(self): | |||
| 95 | 95 | assert warn_message in str(warning.message) | |
| 96 | 96 | assert __file__ in str(warning.message) | |
| 97 | 97 | assert warn_source == warning.source | |
| 98 | + | ||
| 99 | + | ||
| 100 | + def test_transform_types_copies_data_with_empty_files(): | ||
| 101 | + data = {"attr": "spam"} | ||
| 102 | + new_data, files = utils._transform_types(data, {}) | ||
| 103 | + | ||
| 104 | + assert new_data is not data | ||
| 105 | + assert new_data == data | ||
| 106 | + assert files == {} | ||
| 107 | + | ||
| 108 | + | ||
| 109 | + def test_transform_types_with_transform_files_populates_files(): | ||
| 110 | + custom_types = {"attr": types.FileAttribute} | ||
| 111 | + data = {"attr": "spam"} | ||
| 112 | + new_data, files = utils._transform_types(data, custom_types) | ||
| 113 | + | ||
| 114 | + assert new_data == {} | ||
| 115 | + assert files["attr"] == ("attr", "spam") | ||
| 116 | + | ||
| 117 | + | ||
| 118 | + def test_transform_types_without_transform_files_populates_data_with_empty_files(): | ||
| 119 | + custom_types = {"attr": types.FileAttribute} | ||
| 120 | + data = {"attr": "spam"} | ||
| 121 | + new_data, files = utils._transform_types(data, custom_types, transform_files=False) | ||
| 122 | + | ||
| 123 | + assert new_data == {"attr": "spam"} | ||
| 124 | + assert files == {} | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments