11from __future__ import annotations
22
33import dataclasses
4+ import json
45from typing import Any , TYPE_CHECKING
56
7+ from gitlab import exceptions
8+
69
710@dataclasses .dataclass (frozen = True )
811class RequiredOptional :
@@ -36,6 +39,13 @@ def validate_attrs(
3639
3740
3841class GitlabAttribute :
42+ # Used in utils._transform_types() to decide if we should call get_for_api()
43+ # on the attribute when transform_data is False (e.g. for POST/PUT/PATCH).
44+ #
45+ # This allows us to force transformation of data even when sending JSON bodies,
46+ # which is useful for types like CommaSeparatedStringAttribute.
47+ transform_in_body = False
48+
3949 def __init__ (self , value : Any = None ) -> None :
4050 self ._value = value
4151
@@ -49,6 +59,16 @@ def get_for_api(self, *, key: str) -> tuple[str, Any]:
4959 return (key , self ._value )
5060
5161
62+ class JsonAttribute (GitlabAttribute ):
63+ def set_from_cli (self , cli_value : str ) -> None :
64+ try :
65+ self ._value = json .loads (cli_value )
66+ except (ValueError , TypeError ) as e :
67+ raise exceptions .GitlabParsingError (
68+ f"Could not parse JSON data: { e } "
69+ ) from e
70+
71+
5272class _ListArrayAttribute (GitlabAttribute ):
5373 """Helper class to support `list` / `array` types."""
5474
@@ -82,9 +102,23 @@ def get_for_api(self, *, key: str) -> tuple[str, Any]:
82102
83103
84104class CommaSeparatedListAttribute (_ListArrayAttribute ):
85- """For values which are sent to the server as a Comma Separated Values
86- (CSV) string. We allow them to be specified as a list and we convert it
87- into a CSV"""
105+ """
106+ For values which are sent to the server as a Comma Separated Values (CSV) string
107+ in query parameters (GET), but as a list/array in JSON bodies (POST/PUT).
108+ """
109+
110+
111+ class CommaSeparatedStringAttribute (_ListArrayAttribute ):
112+ """
113+ For values which are sent to the server as a Comma Separated Values (CSV) string.
114+ Unlike CommaSeparatedListAttribute, this type ensures the value is converted
115+ to a string even in JSON bodies (POST/PUT requests).
116+ """
117+
118+ # Used in utils._transform_types() to ensure the value is converted to a string
119+ # via get_for_api() even when transform_data is False (e.g. for POST/PUT/PATCH).
120+ # This is needed because some APIs require a CSV string instead of a JSON array.
121+ transform_in_body = True
88122
89123
90124class LowercaseStringAttribute (GitlabAttribute ):
0 commit comments