diff options
Diffstat (limited to 'gitlab/utils.py')
-rw-r--r-- | gitlab/utils.py | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/gitlab/utils.py b/gitlab/utils.py index 1979355..a05cb22 100644 --- a/gitlab/utils.py +++ b/gitlab/utils.py @@ -19,10 +19,12 @@ import pathlib import traceback import urllib.parse import warnings -from typing import Any, Callable, Dict, Optional, Type, Union +from typing import Any, Callable, Dict, Optional, Tuple, Type, Union import requests +from gitlab import types + class _StdoutStream: def __call__(self, chunk: Any) -> None: @@ -47,6 +49,39 @@ def response_content( return None +def _transform_types( + data: Dict[str, Any], custom_types: dict, *, transform_files: Optional[bool] = True +) -> Tuple[dict, dict]: + """Copy the data dict with attributes that have custom types and transform them + before being sent to the server. + + If ``transform_files`` is ``True`` (default), also populates the ``files`` dict for + FileAttribute types with tuples to prepare fields for requests' MultipartEncoder: + https://toolbelt.readthedocs.io/en/latest/user.html#multipart-form-data-encoder + + Returns: + A tuple of the transformed data dict and files dict""" + + # Duplicate data to avoid messing with what the user sent us + data = data.copy() + files = {} + + for attr_name, type_cls in custom_types.items(): + if attr_name not in data: + continue + + type_obj = type_cls(data[attr_name]) + + # if the type if FileAttribute we need to pass the data as file + if transform_files and isinstance(type_obj, types.FileAttribute): + key = type_obj.get_file_name(attr_name) + files[attr_name] = (key, data.pop(attr_name)) + else: + data[attr_name] = type_obj.get_for_api() + + return data, files + + def copy_dict( *, src: Dict[str, Any], |