summaryrefslogtreecommitdiff
path: root/gitlab/base.py
diff options
context:
space:
mode:
authorJohn L. Villalovos <john@sodarock.com>2021-11-30 08:35:58 -0800
committerJohn L. Villalovos <john@sodarock.com>2021-11-30 08:35:58 -0800
commit1839c9e7989163a5cc9a201241942b7faca6e214 (patch)
treef6fcb4f19fb62e6db8234a6f96d367ec093cab27 /gitlab/base.py
parent09a973ee379d82af05a5080decfaec16d2f4eab3 (diff)
downloadgitlab-jlvillal/attribute_help.tar.gz
chore: attempt to be more informative for missing attributesjlvillal/attribute_help
A commonly reported issue from users on Gitter is that they get an AttributeError for an attribute that should be present. This is often caused due to the fact that they used the `list()` method to retrieve the object and objects retrieved this way often only have a subset of the full data. Add more details in the AttributeError message that explains the situation to users. This will hopefully allow them to resolve the issue. Update the FAQ in the docs to add a section discussing the issue. Closes #1138
Diffstat (limited to 'gitlab/base.py')
-rw-r--r--gitlab/base.py38
1 files changed, 34 insertions, 4 deletions
diff --git a/gitlab/base.py b/gitlab/base.py
index 5e5f57b..f7b52fa 100644
--- a/gitlab/base.py
+++ b/gitlab/base.py
@@ -16,9 +16,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import importlib
+import textwrap
from types import ModuleType
from typing import Any, Dict, Iterable, NamedTuple, Optional, Tuple, Type
+import gitlab
from gitlab import types as g_types
from gitlab.exceptions import GitlabParsingError
@@ -32,6 +34,12 @@ __all__ = [
]
+_URL_ATTRIBUTE_ERROR = (
+ f"https://python-gitlab.readthedocs.io/en/{gitlab.__version__}/"
+ f"faq.html#attribute-error-list"
+)
+
+
class RESTObject(object):
"""Represents an object built from server data.
@@ -45,13 +53,20 @@ class RESTObject(object):
_id_attr: Optional[str] = "id"
_attrs: Dict[str, Any]
+ _created_from_list: bool # Indicates if object was created from a list() action
_module: ModuleType
_parent_attrs: Dict[str, Any]
_short_print_attr: Optional[str] = None
_updated_attrs: Dict[str, Any]
manager: "RESTManager"
- def __init__(self, manager: "RESTManager", attrs: Dict[str, Any]) -> None:
+ def __init__(
+ self,
+ manager: "RESTManager",
+ attrs: Dict[str, Any],
+ *,
+ created_from_list: bool = False,
+ ) -> None:
if not isinstance(attrs, dict):
raise GitlabParsingError(
"Attempted to initialize RESTObject with a non-dictionary value: "
@@ -64,6 +79,7 @@ class RESTObject(object):
"_attrs": attrs,
"_updated_attrs": {},
"_module": importlib.import_module(self.__module__),
+ "_created_from_list": created_from_list,
}
)
self.__dict__["_parent_attrs"] = self.manager.parent_attrs
@@ -106,8 +122,22 @@ class RESTObject(object):
except KeyError:
try:
return self.__dict__["_parent_attrs"][name]
- except KeyError:
- raise AttributeError(name)
+ except KeyError as exc:
+ message = (
+ f"{type(self).__name__!r} object has no attribute {name!r}"
+ )
+ if self._created_from_list:
+ message = (
+ f"{message}\n\n"
+ + textwrap.fill(
+ f"{self.__class__!r} was created via a list() call and "
+ f"only a subset of the data may be present. To ensure "
+ f"all data is present get the object using a "
+ f"get(object.id) call. For more details, see:"
+ )
+ + f"\n\n{_URL_ATTRIBUTE_ERROR}"
+ )
+ raise AttributeError(message) from exc
def __setattr__(self, name: str, value: Any) -> None:
self.__dict__["_updated_attrs"][name] = value
@@ -229,7 +259,7 @@ class RESTObjectList(object):
def next(self) -> RESTObject:
data = self._list.next()
- return self._obj_cls(self.manager, data)
+ return self._obj_cls(self.manager, data, created_from_list=True)
@property
def current_page(self) -> int: