summaryrefslogtreecommitdiff
path: root/gitlab/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'gitlab/utils.py')
-rw-r--r--gitlab/utils.py37
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],