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

Commitc188cb0

Browse files
feat: add anasdict() method to the Gitlab Objects
Add an `asdict()` method that returns a dictionary representation copyof the Gitlab Object. This is a copy and changes made to it will haveno impact on the Gitlab Object.The `asdict()` method name was chosen as both the `dataclasses` and`attrs` libraries have an `asdict()` function which has the similarpurpose of creating a dictionary represenation of an object.
1 parentd5de4b1 commitc188cb0

File tree

3 files changed

+105
-6
lines changed

3 files changed

+105
-6
lines changed

‎docs/api-usage.rst‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,35 @@ the value on the object is accepted:
214214
issue.my_super_awesome_feature_flag="random_value"
215215
issue.save()
216216
217+
You can get a dictionary representation copy of the Gitlab Object. Modifications made to
218+
the dictionary will have no impact on the GitLab Object. This can also be used
219+
to create a JSON representation of the object. There are two ways to retrieve a
220+
dictionary representation of the Gitlab Object.
221+
222+
* `asdict()` method. Returns a dictionary with updated attributes having precedence.
223+
* `attributes` property. Returns a dictionary with original attributes having
224+
precedence and then updated attributes. Also returns any relevant parent object
225+
attributes.
226+
227+
..note::
228+
229+
`attributes` returns the parent object attributes that are defined in
230+
`object._from_parent_attrs`. What this can mean is that for example a `ProjectIssue`
231+
object will have a `project_id` key in the dictionary returned from `attributes` but
232+
`asdict()` will not.
233+
234+
235+
..code-block::python
236+
237+
project= gl.projects.get(1)
238+
project_dict= project.asdict()
239+
# Do a JSON dump of the object
240+
print(json.dumps(project.asdict()))
241+
242+
# Or a dictionary representation also containing some of the parent attributes
243+
issue= project.issues.get(1)
244+
attribute_dict= issue.attributes
245+
217246
218247
Base types
219248
==========

‎gitlab/base.py‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# You should have received a copy of the GNU Lesser General Public License
1616
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717

18+
importcopy
1819
importimportlib
1920
importpprint
2021
importtextwrap
@@ -142,15 +143,16 @@ def __getattr__(self, name: str) -> Any:
142143
def__setattr__(self,name:str,value:Any)->None:
143144
self.__dict__["_updated_attrs"][name]=value
144145

146+
defasdict(self)->Dict[str,Any]:
147+
data=copy.deepcopy(self._attrs)
148+
data.update(copy.deepcopy(self._updated_attrs))
149+
returndata
150+
145151
def__str__(self)->str:
146-
data=self._attrs.copy()
147-
data.update(self._updated_attrs)
148-
returnf"{type(self)} =>{data}"
152+
returnf"{type(self)} =>{self.asdict()}"
149153

150154
defpformat(self)->str:
151-
data=self._attrs.copy()
152-
data.update(self._updated_attrs)
153-
returnf"{type(self)} =>\n{pprint.pformat(data)}"
155+
returnf"{type(self)} =>\n{pprint.pformat(self.asdict())}"
154156

155157
defpprint(self)->None:
156158
print(self.pformat())

‎tests/unit/test_base.py‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,71 @@ def test_repr(self, fake_manager):
306306

307307
FakeObject._id_attr=None
308308
assertrepr(obj)=="<FakeObject>"
309+
310+
deftest_asdict(self,fake_manager):
311+
fake_object=FakeObject(fake_manager, {"attr1":"foo","alist": [1,2,3]})
312+
assertfake_object.attr1=="foo"
313+
result=fake_object.asdict()
314+
assertresult== {"attr1":"foo","alist": [1,2,3]}
315+
# Demonstrate modifying the dictionary does not modify the object
316+
result["attr1"]="testing"
317+
result["alist"].append(4)
318+
assertresult== {"attr1":"testing","alist": [1,2,3,4]}
319+
assertfake_object.attr1=="foo"
320+
assertfake_object.alist== [1,2,3]
321+
# asdict() returns the updated value
322+
fake_object.attr1="spam"
323+
assertfake_object.asdict()== {"attr1":"spam","alist": [1,2,3]}
324+
# Modify attribute and then ensure modifying a list in the returned dict won't
325+
# modify the list in the object.
326+
fake_object.attr1= [9,7,8]
327+
assertfake_object.asdict()== {
328+
"attr1": [9,7,8],
329+
"alist": [1,2,3],
330+
}
331+
result=fake_object.asdict()
332+
result["attr1"].append(1)
333+
assertfake_object.asdict()== {
334+
"attr1": [9,7,8],
335+
"alist": [1,2,3],
336+
}
337+
338+
deftest_attributes(self,fake_manager):
339+
fake_object=FakeObject(fake_manager, {"attr1": [1,2,3]})
340+
assertfake_object.attr1== [1,2,3]
341+
result=fake_object.attributes
342+
assertresult== {"attr1": [1,2,3]}
343+
344+
# Updated attribute value is not reflected in `attributes`
345+
fake_object.attr1="hello"
346+
assertfake_object.attributes== {"attr1": [1,2,3]}
347+
assertfake_object.attr1=="hello"
348+
# New attribute is in `attributes`
349+
fake_object.new_attrib="spam"
350+
assertfake_object.attributes== {"attr1": [1,2,3],"new_attrib":"spam"}
351+
352+
# Modifying the dictionary can cause modification to the object :(
353+
result=fake_object.attributes
354+
result["attr1"].append(10)
355+
assertresult== {"attr1": [1,2,3,10],"new_attrib":"spam"}
356+
assertfake_object.attributes== {"attr1": [1,2,3,10],"new_attrib":"spam"}
357+
assertfake_object.attr1=="hello"
358+
359+
360+
deftest_asdict_vs_attributes(self,fake_manager):
361+
fake_object=FakeObject(fake_manager, {"attr1":"foo"})
362+
assertfake_object.attr1=="foo"
363+
result=fake_object.asdict()
364+
assertresult== {"attr1":"foo"}
365+
366+
# New attribute added, return same result
367+
assertfake_object.attributes==fake_object.asdict()
368+
fake_object.attr2="eggs"
369+
assertfake_object.attributes==fake_object.asdict()
370+
# Update attribute, return different result
371+
fake_object.attr1="hello"
372+
assertfake_object.attributes!=fake_object.asdict()
373+
# asdict() returns the updated value
374+
assertfake_object.asdict()== {"attr1":"hello","attr2":"eggs"}
375+
# `attributes` returns original value
376+
assertfake_object.attributes== {"attr1":"foo","attr2":"eggs"}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp