From e5affc8749797293c1373c6af96334f194875038 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Wed, 20 Jul 2022 08:38:31 -0700 Subject: fix: results returned by `attributes` property to show updates Previously the `attributes` method would show the original values in a Gitlab Object even if they had been updated. Correct this so that the updated value will be returned. Also use copy.deepcopy() to ensure that modifying the dictionary returned can not also modify the object. --- gitlab/base.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'gitlab') diff --git a/gitlab/base.py b/gitlab/base.py index 920617b..7de76e0 100644 --- a/gitlab/base.py +++ b/gitlab/base.py @@ -15,6 +15,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . +import copy import importlib import pprint import textwrap @@ -243,10 +244,11 @@ class RESTObject: @property def attributes(self) -> Dict[str, Any]: - d = self.__dict__["_updated_attrs"].copy() - d.update(self.__dict__["_attrs"]) - d.update(self.__dict__["_parent_attrs"]) - return d + data = {} + data.update(copy.deepcopy(self._parent_attrs)) + data.update(copy.deepcopy(self._attrs)) + data.update(copy.deepcopy(self._updated_attrs)) + return data class RESTObjectList: -- cgit v1.2.1 From 08ac071abcbc28af04c0fa655576e25edbdaa4e2 Mon Sep 17 00:00:00 2001 From: "John L. Villalovos" Date: Wed, 20 Jul 2022 08:38:43 -0700 Subject: feat: add `asdict()` and `to_json()` methods to Gitlab Objects Add an `asdict()` method that returns a dictionary representation copy of the Gitlab Object. This is a copy and changes made to it will have no 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 similar purpose of creating a dictionary represenation of an object. Also add a `to_json()` method that returns a JSON string representation of the object. Closes: #1116 --- gitlab/base.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'gitlab') diff --git a/gitlab/base.py b/gitlab/base.py index 7de76e0..dd69d00 100644 --- a/gitlab/base.py +++ b/gitlab/base.py @@ -17,6 +17,7 @@ import copy import importlib +import json import pprint import textwrap from types import ModuleType @@ -143,15 +144,26 @@ class RESTObject: def __setattr__(self, name: str, value: Any) -> None: self.__dict__["_updated_attrs"][name] = value + def asdict(self, *, with_parent_attrs: bool = False) -> Dict[str, Any]: + data = {} + if with_parent_attrs: + data.update(copy.deepcopy(self._parent_attrs)) + data.update(copy.deepcopy(self._attrs)) + data.update(copy.deepcopy(self._updated_attrs)) + return data + + @property + def attributes(self) -> Dict[str, Any]: + return self.asdict(with_parent_attrs=True) + + def to_json(self, *, with_parent_attrs: bool = False, **kwargs: Any) -> str: + return json.dumps(self.asdict(with_parent_attrs=with_parent_attrs), **kwargs) + def __str__(self) -> str: - data = self._attrs.copy() - data.update(self._updated_attrs) - return f"{type(self)} => {data}" + return f"{type(self)} => {self.asdict()}" def pformat(self) -> str: - data = self._attrs.copy() - data.update(self._updated_attrs) - return f"{type(self)} => \n{pprint.pformat(data)}" + return f"{type(self)} => \n{pprint.pformat(self.asdict())}" def pprint(self) -> None: print(self.pformat()) @@ -242,14 +254,6 @@ class RESTObject: obj_id = gitlab.utils.EncodedId(obj_id) return obj_id - @property - def attributes(self) -> Dict[str, Any]: - data = {} - data.update(copy.deepcopy(self._parent_attrs)) - data.update(copy.deepcopy(self._attrs)) - data.update(copy.deepcopy(self._updated_attrs)) - return data - class RESTObjectList: """Generator object representing a list of RESTObject's. -- cgit v1.2.1