diff --git a/gitlab/base.py b/gitlab/base.py index 7324c31bb..c3da0775a 100644 --- a/gitlab/base.py +++ b/gitlab/base.py @@ -96,6 +96,16 @@ def __repr__(self): else: return '<%s>' % self.__class__.__name__ + def __eq__(self, other): + if self.get_id() and other.get_id(): + return self.get_id() == other.get_id() + return super().__eq__(other) + + def __hash__(self): + if not self.get_id(): + return super().__hash__() + return hash(self.get_id()) + def _create_managers(self): managers = getattr(self, '_managers', None) if managers is None: @@ -112,7 +122,7 @@ def _update_attrs(self, new_attrs): def get_id(self): """Returns the id of the resource.""" - if self._id_attr is None: + if self._id_attr is None or not hasattr(self, self._id_attr): return None return getattr(self, self._id_attr) diff --git a/gitlab/tests/test_base.py b/gitlab/tests/test_base.py index 36cb63b8a..b29d423f4 100644 --- a/gitlab/tests/test_base.py +++ b/gitlab/tests/test_base.py @@ -134,3 +134,26 @@ class ObjectWithManager(FakeObject): self.assertIsInstance(obj.fakes, FakeManager) self.assertEqual(obj.fakes.gitlab, self.gitlab) self.assertEqual(obj.fakes._parent, obj) + + def test_equality(self): + obj1 = FakeObject(self.manager, {'id': 'foo'}) + obj2 = FakeObject(self.manager, {'id': 'foo', 'other_attr': 'bar'}) + self.assertEqual(obj1, obj2) + + def test_equality_custom_id(self): + class OtherFakeObject(FakeObject): + _id_attr = 'foo' + + obj1 = OtherFakeObject(self.manager, {'foo': 'bar'}) + obj2 = OtherFakeObject(self.manager, {'foo': 'bar', 'other_attr': 'baz'}) + self.assertEqual(obj1, obj2) + + def test_inequality(self): + obj1 = FakeObject(self.manager, {'id': 'foo'}) + obj2 = FakeObject(self.manager, {'id': 'bar'}) + self.assertNotEqual(obj1, obj2) + + def test_inequality_no_id(self): + obj1 = FakeObject(self.manager, {'attr1': 'foo'}) + obj2 = FakeObject(self.manager, {'attr1': 'bar'}) + self.assertNotEqual(obj1, obj2)