| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 37eb8e0 commit 3fa330c
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -256,15 +256,6 @@ class CreateMixin(_RestManagerBase): | |||
| 256 | 256 | _path: Optional[str] | |
| 257 | 257 | gitlab: gitlab.Gitlab | |
| 258 | 258 | ||
| 259 | - def _check_missing_create_attrs(self, data: Dict[str, Any]) -> None: | ||
| 260 | - missing = [] | ||
| 261 | - for attr in self._create_attrs.required: | ||
| 262 | - if attr not in data: | ||
| 263 | - missing.append(attr) | ||
| 264 | - continue | ||
| 265 | - if missing: | ||
| 266 | - raise AttributeError(f"Missing attributes: {', '.join(missing)}") | ||
| 267 | - | ||
| 268 | 259 | @exc.on_http_error(exc.GitlabCreateError) | |
| 269 | 260 | def create( | |
| 270 | 261 | self, data: Optional[Dict[str, Any]] = None, **kwargs: Any | |
@@ -287,7 +278,7 @@ def create( | |||
| 287 | 278 | if data is None: | |
| 288 | 279 | data = {} | |
| 289 | 280 | ||
| 290 | - self._check_missing_create_attrs(data) | ||
| 281 | + utils._validate_attrs(data=data, attributes=self._create_attrs) | ||
| 291 | 282 | data, files = utils._transform_types(data, self._types) | |
| 292 | 283 | ||
| 293 | 284 | # Handle specific URL for creation | |
@@ -309,22 +300,6 @@ class UpdateMixin(_RestManagerBase): | |||
| 309 | 300 | _update_uses_post: bool = False | |
| 310 | 301 | gitlab: gitlab.Gitlab | |
| 311 | 302 | ||
| 312 | - def _check_missing_update_attrs(self, data: Dict[str, Any]) -> None: | ||
| 313 | - if TYPE_CHECKING: | ||
| 314 | - assert self._obj_cls is not None | ||
| 315 | - # Remove the id field from the required list as it was previously moved | ||
| 316 | - # to the http path. | ||
| 317 | - required = tuple( | ||
| 318 | - [k for k in self._update_attrs.required if k != self._obj_cls._id_attr] | ||
| 319 | - ) | ||
| 320 | - missing = [] | ||
| 321 | - for attr in required: | ||
| 322 | - if attr not in data: | ||
| 323 | - missing.append(attr) | ||
| 324 | - continue | ||
| 325 | - if missing: | ||
| 326 | - raise AttributeError(f"Missing attributes: {', '.join(missing)}") | ||
| 327 | - | ||
| 328 | 303 | def _get_update_method( | |
| 329 | 304 | self, | |
| 330 | 305 | ) -> Callable[..., Union[Dict[str, Any], requests.Response]]: | |
@@ -367,7 +342,12 @@ def update( | |||
| 367 | 342 | else: | |
| 368 | 343 | path = f"{self.path}/{utils.EncodedId(id)}" | |
| 369 | 344 | ||
| 370 | - self._check_missing_update_attrs(new_data) | ||
| 345 | + excludes = [] | ||
| 346 | + if self._obj_cls is not None and self._obj_cls._id_attr is not None: | ||
| 347 | + excludes = [self._obj_cls._id_attr] | ||
| 348 | + utils._validate_attrs( | ||
| 349 | + data=new_data, attributes=self._update_attrs, excludes=excludes | ||
| 350 | + ) | ||
| 371 | 351 | new_data, files = utils._transform_types(new_data, self._types) | |
| 372 | 352 | ||
| 373 | 353 | http_method = self._get_update_method() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,7 @@ | |||
| 23 | 23 | class RequiredOptional: | |
| 24 | 24 | required: Tuple[str, ...] = () | |
| 25 | 25 | optional: Tuple[str, ...] = () | |
| 26 | + exclusive: Tuple[str, ...] = () | ||
| 26 | 27 | ||
| 27 | 28 | ||
| 28 | 29 | class GitlabAttribute: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,7 +19,7 @@ | |||
| 19 | 19 | import traceback | |
| 20 | 20 | import urllib.parse | |
| 21 | 21 | import warnings | |
| 22 | - from typing import Any, Callable, Dict, Optional, Tuple, Type, Union | ||
| 22 | + from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union | ||
| 23 | 23 | ||
| 24 | 24 | import requests | |
| 25 | 25 | ||
@@ -161,3 +161,30 @@ def warn( | |||
| 161 | 161 | stacklevel=stacklevel, | |
| 162 | 162 | source=source, | |
| 163 | 163 | ) | |
| 164 | + | ||
| 165 | + | ||
| 166 | + def _validate_attrs( | ||
| 167 | + data: Dict[str, Any], | ||
| 168 | + attributes: types.RequiredOptional, | ||
| 169 | + excludes: Optional[List[str]] = None, | ||
| 170 | + ) -> None: | ||
| 171 | + if excludes is None: | ||
| 172 | + excludes = [] | ||
| 173 | + | ||
| 174 | + if attributes.required: | ||
| 175 | + required = [k for k in attributes.required if k not in excludes] | ||
| 176 | + missing = [attr for attr in required if attr not in data] | ||
| 177 | + if missing: | ||
| 178 | + raise AttributeError(f"Missing attributes: {', '.join(missing)}") | ||
| 179 | + | ||
| 180 | + if attributes.exclusive: | ||
| 181 | + exclusives = [attr for attr in data if attr in attributes.exclusive] | ||
| 182 | + if len(exclusives) > 1: | ||
| 183 | + raise AttributeError( | ||
| 184 | + f"Provide only one of these attributes: {', '.join(exclusives)}" | ||
| 185 | + ) | ||
| 186 | + if not exclusives: | ||
| 187 | + raise AttributeError( | ||
| 188 | + "Must provide one of these attributes: %(attrs)s" | ||
| 189 | + % {"attrs": ", ".join(attributes.exclusive)} | ||
| 190 | + ) | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,9 @@ class GroupBoardListManager(CRUDMixin, RESTManager): | |||
| 24 | 24 | _path = "/groups/{group_id}/boards/{board_id}/lists" | |
| 25 | 25 | _obj_cls = GroupBoardList | |
| 26 | 26 | _from_parent_attrs = {"group_id": "group_id", "board_id": "id"} | |
| 27 | - _create_attrs = RequiredOptional(required=("label_id",)) | ||
| 27 | + _create_attrs = RequiredOptional( | ||
| 28 | + exclusive=("label_id", "assignee_id", "milestone_id") | ||
| 29 | + ) | ||
| 28 | 30 | _update_attrs = RequiredOptional(required=("position",)) | |
| 29 | 31 | ||
| 30 | 32 | def get( | |
@@ -55,7 +57,9 @@ class ProjectBoardListManager(CRUDMixin, RESTManager): | |||
| 55 | 57 | _path = "/projects/{project_id}/boards/{board_id}/lists" | |
| 56 | 58 | _obj_cls = ProjectBoardList | |
| 57 | 59 | _from_parent_attrs = {"project_id": "project_id", "board_id": "id"} | |
| 58 | - _create_attrs = RequiredOptional(required=("label_id",)) | ||
| 60 | + _create_attrs = RequiredOptional( | ||
| 61 | + exclusive=("label_id", "assignee_id", "milestone_id") | ||
| 62 | + ) | ||
| 59 | 63 | _update_attrs = RequiredOptional(required=("position",)) | |
| 60 | 64 | ||
| 61 | 65 | def get( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,7 @@ | |||
| 1 | 1 | from typing import Any, cast, Dict, Optional, TYPE_CHECKING, Union | |
| 2 | 2 | ||
| 3 | 3 | from gitlab import exceptions as exc | |
| 4 | - from gitlab import types | ||
| 4 | + from gitlab import types, utils | ||
| 5 | 5 | from gitlab.base import RESTManager, RESTObject | |
| 6 | 6 | from gitlab.mixins import ( | |
| 7 | 7 | CreateMixin, | |
@@ -107,7 +107,7 @@ def create( | |||
| 107 | 107 | """ | |
| 108 | 108 | if TYPE_CHECKING: | |
| 109 | 109 | assert data is not None | |
| 110 | - CreateMixin._check_missing_create_attrs(self, data) | ||
| 110 | + utils._validate_attrs(data=data, attributes=self._create_attrs) | ||
| 111 | 111 | path = f"{self.path}/{data.pop('issue_id')}" | |
| 112 | 112 | server_data = self.gitlab.http_post(path, **kwargs) | |
| 113 | 113 | if TYPE_CHECKING: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -145,7 +145,7 @@ def create( | |||
| 145 | 145 | ||
| 146 | 146 | if TYPE_CHECKING: | |
| 147 | 147 | assert data is not None | |
| 148 | - self._check_missing_create_attrs(data) | ||
| 148 | + utils._validate_attrs(data=data, attributes=self._create_attrs) | ||
| 149 | 149 | new_data = data.copy() | |
| 150 | 150 | file_path = utils.EncodedId(new_data.pop("file_path")) | |
| 151 | 151 | path = f"{self.path}/{file_path}" | |
@@ -179,7 +179,7 @@ def update( # type: ignore | |||
| 179 | 179 | file_path = utils.EncodedId(file_path) | |
| 180 | 180 | data["file_path"] = file_path | |
| 181 | 181 | path = f"{self.path}/{file_path}" | |
| 182 | - self._check_missing_update_attrs(data) | ||
| 182 | + utils._validate_attrs(data=data, attributes=self._update_attrs) | ||
| 183 | 183 | result = self.gitlab.http_put(path, post_data=data, **kwargs) | |
| 184 | 184 | if TYPE_CHECKING: | |
| 185 | 185 | assert isinstance(result, dict) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | 3 | from gitlab import cli | |
| 4 | 4 | from gitlab import exceptions as exc | |
| 5 | - from gitlab import types | ||
| 5 | + from gitlab import types, utils | ||
| 6 | 6 | from gitlab.base import RESTManager, RESTObject | |
| 7 | 7 | from gitlab.mixins import ( | |
| 8 | 8 | CreateMixin, | |
@@ -272,7 +272,7 @@ def create( # type: ignore | |||
| 272 | 272 | GitlabAuthenticationError: If authentication is not correct | |
| 273 | 273 | GitlabCreateError: If the server cannot perform the request | |
| 274 | 274 | """ | |
| 275 | - self._check_missing_create_attrs(data) | ||
| 275 | + utils._validate_attrs(data=data, attributes=self._create_attrs) | ||
| 276 | 276 | if TYPE_CHECKING: | |
| 277 | 277 | assert self.path is not None | |
| 278 | 278 | server_data = self.gitlab.http_post(self.path, post_data=data, **kwargs) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | 4 | from gitlab import base | |
| 5 | 5 | from gitlab import types as gl_types | |
| 6 | + from gitlab import utils | ||
| 6 | 7 | from gitlab.mixins import ( | |
| 7 | 8 | CreateMixin, | |
| 8 | 9 | DeleteMixin, | |
@@ -173,11 +174,11 @@ class M(CreateMixin, FakeManager): | |||
| 173 | 174 | ||
| 174 | 175 | mgr = M(gl) | |
| 175 | 176 | data = {"foo": "bar", "baz": "blah"} | |
| 176 | - mgr._check_missing_create_attrs(data) | ||
| 177 | + utils._validate_attrs(data=data, attributes=mgr._create_attrs) | ||
| 177 | 178 | ||
| 178 | 179 | data = {"baz": "blah"} | |
| 179 | 180 | with pytest.raises(AttributeError) as error: | |
| 180 | - mgr._check_missing_create_attrs(data) | ||
| 181 | + utils._validate_attrs(data=data, attributes=mgr._create_attrs) | ||
| 181 | 182 | assert "foo" in str(error.value) | |
| 182 | 183 | ||
| 183 | 184 | ||
@@ -239,11 +240,11 @@ class M(UpdateMixin, FakeManager): | |||
| 239 | 240 | ||
| 240 | 241 | mgr = M(gl) | |
| 241 | 242 | data = {"foo": "bar", "baz": "blah"} | |
| 242 | - mgr._check_missing_update_attrs(data) | ||
| 243 | + utils._validate_attrs(data=data, attributes=mgr._update_attrs) | ||
| 243 | 244 | ||
| 244 | 245 | data = {"baz": "blah"} | |
| 245 | 246 | with pytest.raises(AttributeError) as error: | |
| 246 | - mgr._check_missing_update_attrs(data) | ||
| 247 | + utils._validate_attrs(data=data, attributes=mgr._update_attrs) | ||
| 247 | 248 | assert "foo" in str(error.value) | |
| 248 | 249 | ||
| 249 | 250 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments