Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3fa330c

Browse files
authored
feat: support mutually exclusive attributes and consolidate validation to fix board lists (#2037)
add exclusive tuple to RequiredOptional data class to support formutually exclusive attributesconsolidate _check_missing_create_attrs and _check_missing_update_attrsfrom mixins.py into _validate_attrs in utils.pychange _create_attrs in board list manager classes fromrequired=('label_ld',) toexclusive=('label_id','asignee_id','milestone_id')closes#1897
1 parent37eb8e0 commit3fa330c

File tree

8 files changed

+53
-40
lines changed

8 files changed

+53
-40
lines changed

‎gitlab/mixins.py

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -256,15 +256,6 @@ class CreateMixin(_RestManagerBase):
256256
_path:Optional[str]
257257
gitlab:gitlab.Gitlab
258258

259-
def_check_missing_create_attrs(self,data:Dict[str,Any])->None:
260-
missing= []
261-
forattrinself._create_attrs.required:
262-
ifattrnotindata:
263-
missing.append(attr)
264-
continue
265-
ifmissing:
266-
raiseAttributeError(f"Missing attributes:{', '.join(missing)}")
267-
268259
@exc.on_http_error(exc.GitlabCreateError)
269260
defcreate(
270261
self,data:Optional[Dict[str,Any]]=None,**kwargs:Any
@@ -287,7 +278,7 @@ def create(
287278
ifdataisNone:
288279
data= {}
289280

290-
self._check_missing_create_attrs(data)
281+
utils._validate_attrs(data=data,attributes=self._create_attrs)
291282
data,files=utils._transform_types(data,self._types)
292283

293284
# Handle specific URL for creation
@@ -309,22 +300,6 @@ class UpdateMixin(_RestManagerBase):
309300
_update_uses_post:bool=False
310301
gitlab:gitlab.Gitlab
311302

312-
def_check_missing_update_attrs(self,data:Dict[str,Any])->None:
313-
ifTYPE_CHECKING:
314-
assertself._obj_clsisnotNone
315-
# Remove the id field from the required list as it was previously moved
316-
# to the http path.
317-
required=tuple(
318-
[kforkinself._update_attrs.requiredifk!=self._obj_cls._id_attr]
319-
)
320-
missing= []
321-
forattrinrequired:
322-
ifattrnotindata:
323-
missing.append(attr)
324-
continue
325-
ifmissing:
326-
raiseAttributeError(f"Missing attributes:{', '.join(missing)}")
327-
328303
def_get_update_method(
329304
self,
330305
)->Callable[...,Union[Dict[str,Any],requests.Response]]:
@@ -367,7 +342,12 @@ def update(
367342
else:
368343
path=f"{self.path}/{utils.EncodedId(id)}"
369344

370-
self._check_missing_update_attrs(new_data)
345+
excludes= []
346+
ifself._obj_clsisnotNoneandself._obj_cls._id_attrisnotNone:
347+
excludes= [self._obj_cls._id_attr]
348+
utils._validate_attrs(
349+
data=new_data,attributes=self._update_attrs,excludes=excludes
350+
)
371351
new_data,files=utils._transform_types(new_data,self._types)
372352

373353
http_method=self._get_update_method()

‎gitlab/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
classRequiredOptional:
2424
required:Tuple[str, ...]= ()
2525
optional:Tuple[str, ...]= ()
26+
exclusive:Tuple[str, ...]= ()
2627

2728

2829
classGitlabAttribute:

‎gitlab/utils.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
importtraceback
2020
importurllib.parse
2121
importwarnings
22-
fromtypingimportAny,Callable,Dict,Optional,Tuple,Type,Union
22+
fromtypingimportAny,Callable,Dict,List,Optional,Tuple,Type,Union
2323

2424
importrequests
2525

@@ -161,3 +161,30 @@ def warn(
161161
stacklevel=stacklevel,
162162
source=source,
163163
)
164+
165+
166+
def_validate_attrs(
167+
data:Dict[str,Any],
168+
attributes:types.RequiredOptional,
169+
excludes:Optional[List[str]]=None,
170+
)->None:
171+
ifexcludesisNone:
172+
excludes= []
173+
174+
ifattributes.required:
175+
required= [kforkinattributes.requiredifknotinexcludes]
176+
missing= [attrforattrinrequiredifattrnotindata]
177+
ifmissing:
178+
raiseAttributeError(f"Missing attributes:{', '.join(missing)}")
179+
180+
ifattributes.exclusive:
181+
exclusives= [attrforattrindataifattrinattributes.exclusive]
182+
iflen(exclusives)>1:
183+
raiseAttributeError(
184+
f"Provide only one of these attributes:{', '.join(exclusives)}"
185+
)
186+
ifnotexclusives:
187+
raiseAttributeError(
188+
"Must provide one of these attributes: %(attrs)s"
189+
% {"attrs":", ".join(attributes.exclusive)}
190+
)

‎gitlab/v4/objects/boards.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ class GroupBoardListManager(CRUDMixin, RESTManager):
2424
_path="/groups/{group_id}/boards/{board_id}/lists"
2525
_obj_cls=GroupBoardList
2626
_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+
)
2830
_update_attrs=RequiredOptional(required=("position",))
2931

3032
defget(
@@ -55,7 +57,9 @@ class ProjectBoardListManager(CRUDMixin, RESTManager):
5557
_path="/projects/{project_id}/boards/{board_id}/lists"
5658
_obj_cls=ProjectBoardList
5759
_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+
)
5963
_update_attrs=RequiredOptional(required=("position",))
6064

6165
defget(

‎gitlab/v4/objects/epics.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
fromtypingimportAny,cast,Dict,Optional,TYPE_CHECKING,Union
22

33
fromgitlabimportexceptionsasexc
4-
fromgitlabimporttypes
4+
fromgitlabimporttypes,utils
55
fromgitlab.baseimportRESTManager,RESTObject
66
fromgitlab.mixinsimport (
77
CreateMixin,
@@ -107,7 +107,7 @@ def create(
107107
"""
108108
ifTYPE_CHECKING:
109109
assertdataisnotNone
110-
CreateMixin._check_missing_create_attrs(self,data)
110+
utils._validate_attrs(data=data,attributes=self._create_attrs)
111111
path=f"{self.path}/{data.pop('issue_id')}"
112112
server_data=self.gitlab.http_post(path,**kwargs)
113113
ifTYPE_CHECKING:

‎gitlab/v4/objects/files.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def create(
145145

146146
ifTYPE_CHECKING:
147147
assertdataisnotNone
148-
self._check_missing_create_attrs(data)
148+
utils._validate_attrs(data=data,attributes=self._create_attrs)
149149
new_data=data.copy()
150150
file_path=utils.EncodedId(new_data.pop("file_path"))
151151
path=f"{self.path}/{file_path}"
@@ -179,7 +179,7 @@ def update( # type: ignore
179179
file_path=utils.EncodedId(file_path)
180180
data["file_path"]=file_path
181181
path=f"{self.path}/{file_path}"
182-
self._check_missing_update_attrs(data)
182+
utils._validate_attrs(data=data,attributes=self._update_attrs)
183183
result=self.gitlab.http_put(path,post_data=data,**kwargs)
184184
ifTYPE_CHECKING:
185185
assertisinstance(result,dict)

‎gitlab/v4/objects/issues.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
fromgitlabimportcli
44
fromgitlabimportexceptionsasexc
5-
fromgitlabimporttypes
5+
fromgitlabimporttypes,utils
66
fromgitlab.baseimportRESTManager,RESTObject
77
fromgitlab.mixinsimport (
88
CreateMixin,
@@ -272,7 +272,7 @@ def create( # type: ignore
272272
GitlabAuthenticationError: If authentication is not correct
273273
GitlabCreateError: If the server cannot perform the request
274274
"""
275-
self._check_missing_create_attrs(data)
275+
utils._validate_attrs(data=data,attributes=self._create_attrs)
276276
ifTYPE_CHECKING:
277277
assertself.pathisnotNone
278278
server_data=self.gitlab.http_post(self.path,post_data=data,**kwargs)

‎tests/unit/mixins/test_mixin_methods.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
fromgitlabimportbase
55
fromgitlabimporttypesasgl_types
6+
fromgitlabimportutils
67
fromgitlab.mixinsimport (
78
CreateMixin,
89
DeleteMixin,
@@ -173,11 +174,11 @@ class M(CreateMixin, FakeManager):
173174

174175
mgr=M(gl)
175176
data= {"foo":"bar","baz":"blah"}
176-
mgr._check_missing_create_attrs(data)
177+
utils._validate_attrs(data=data,attributes=mgr._create_attrs)
177178

178179
data= {"baz":"blah"}
179180
withpytest.raises(AttributeError)aserror:
180-
mgr._check_missing_create_attrs(data)
181+
utils._validate_attrs(data=data,attributes=mgr._create_attrs)
181182
assert"foo"instr(error.value)
182183

183184

@@ -239,11 +240,11 @@ class M(UpdateMixin, FakeManager):
239240

240241
mgr=M(gl)
241242
data= {"foo":"bar","baz":"blah"}
242-
mgr._check_missing_update_attrs(data)
243+
utils._validate_attrs(data=data,attributes=mgr._update_attrs)
243244

244245
data= {"baz":"blah"}
245246
withpytest.raises(AttributeError)aserror:
246-
mgr._check_missing_update_attrs(data)
247+
utils._validate_attrs(data=data,attributes=mgr._update_attrs)
247248
assert"foo"instr(error.value)
248249

249250

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp