Skip to content

Commit e8050c3

Browse files
author
Pietro Albini
committed
Add ability to compare API objects
This commit adds correct equality checks for most of the API objects. This allows, for example, to check if two `User` instances points to the same user by simply comparing them (`user1 == user2`).
1 parent 02a98fe commit e8050c3

File tree

6 files changed

+47
-0
lines changed

6 files changed

+47
-0
lines changed

botogram/objects/base.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class BaseObject:
1818
required = {}
1919
optional = {}
2020
replace_keys = {}
21+
_check_equality_ = None
2122

2223
def __init__(self, data, api=None):
2324
# Prevent receiving strange types
@@ -53,6 +54,17 @@ def __init__(self, data, api=None):
5354
if api is not None:
5455
self.set_api(api)
5556

57+
def __eq__(self, other):
58+
to_check = self._check_equality_
59+
60+
if to_check is None:
61+
return id(self) == id(other)
62+
63+
if not isinstance(other, self.__class__):
64+
return False
65+
66+
return getattr(self, to_check) == getattr(other, to_check)
67+
5668
def set_api(self, api):
5769
"""Change the API instance"""
5870
self._api = api

botogram/objects/chats.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class User(BaseObject, mixins.ChatMixin):
2727
"last_name": str,
2828
"username": str,
2929
}
30+
_check_equality_ = "id"
3031

3132
@property
3233
def name(self):
@@ -90,6 +91,7 @@ class Chat(BaseObject, mixins.ChatMixin):
9091
"first_name": str,
9192
"last_name": str,
9293
}
94+
_check_equality_ = "id"
9395

9496
@property
9597
def name(self):

botogram/objects/media.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class PhotoSize(BaseObject, mixins.FileMixin):
2424
optional = {
2525
"file_size": int,
2626
}
27+
_check_equality_ = "file_id"
2728

2829

2930
class Photo(mixins.FileMixin):
@@ -61,6 +62,9 @@ def __init__(self, data, api=None):
6162
for attr in attrs:
6263
setattr(self, attr, getattr(self.biggest, attr))
6364

65+
def __eq__(self, other):
66+
return isinstance(other, Photo) and self.sizes == other.sizes
67+
6468
def set_api(self, api):
6569
"""Change the API instance"""
6670
self._api = api
@@ -94,6 +98,7 @@ class Audio(BaseObject, mixins.FileMixin):
9498
"mime_type": str,
9599
"file_size": int,
96100
}
101+
_check_equality_ = "file_id"
97102

98103

99104
class Voice(BaseObject, mixins.FileMixin):
@@ -110,6 +115,7 @@ class Voice(BaseObject, mixins.FileMixin):
110115
"mime_type": str,
111116
"file_size": int,
112117
}
118+
_check_equality_ = "file_id"
113119

114120

115121
class Document(BaseObject, mixins.FileMixin):
@@ -127,6 +133,7 @@ class Document(BaseObject, mixins.FileMixin):
127133
"mime_type": str,
128134
"file_size": int,
129135
}
136+
_check_equality_ = "file_id"
130137

131138

132139
class Sticker(BaseObject, mixins.FileMixin):
@@ -145,6 +152,7 @@ class Sticker(BaseObject, mixins.FileMixin):
145152
"emoji": str,
146153
"file_size": int,
147154
}
155+
_check_equality_ = "file_id"
148156

149157

150158
class Video(BaseObject, mixins.FileMixin):
@@ -164,6 +172,7 @@ class Video(BaseObject, mixins.FileMixin):
164172
"mime_type": str,
165173
"file_size": int,
166174
}
175+
_check_equality_ = "file_id"
167176

168177

169178
class Contact(BaseObject):
@@ -180,6 +189,7 @@ class Contact(BaseObject):
180189
"last_name": str,
181190
"user_id": int,
182191
}
192+
_check_equality_ = "phone_number"
183193

184194

185195
class Location(BaseObject):
@@ -192,3 +202,8 @@ class Location(BaseObject):
192202
"longitude": float,
193203
"latitude": float,
194204
}
205+
206+
def __eq__(self, other):
207+
return isinstance(other, Location) and \
208+
self.longitude == other.longitude and \
209+
self.latitude == other.latitude

botogram/objects/messages.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ def __init__(self, data, api=None, message=None):
6666

6767
self._message = message
6868

69+
def __eq__(self, other):
70+
if not isinstance(other, ParsedTextEntity):
71+
return False
72+
73+
# Don't do custom equality if no message object is attached
74+
if self._message is None or other._message is None:
75+
return id(self) == id(other)
76+
77+
return self._message.message_id == other._message.message_id and \
78+
self._offset == other._offset and self._length == other._length
79+
6980
def __str__(self):
7081
return self.text
7182

@@ -174,6 +185,10 @@ def __init__(self, data, api=None, message=None):
174185

175186
self.set_message(message)
176187

188+
def __eq__(self, other):
189+
return isinstance(other, ParsedText) and \
190+
self._entities == other._entities
191+
177192
def __repr__(self):
178193
return '<ParsedText %s>' % repr(self._calculate_entities())
179194

@@ -313,6 +328,7 @@ def from_(self):
313328
"forward_from": "_forward_from",
314329
"forward_from_chat": "_forward_from_chat",
315330
}
331+
_check_equality_ = "message_id"
316332

317333
def __init__(self, data, api=None):
318334
super().__init__(data, api)

botogram/objects/updates.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Update(BaseObject):
2323
optional = {
2424
"message": Message
2525
}
26+
_check_equality_ = "update_id"
2627

2728

2829
# Shortcut for the Updates type

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ New features
5151
* Every method which sends something to a chat now returns the sent
5252
:py:class:`~botogram.Message`
5353
* Multiple instances of the same bot are now properly handled (as errors)
54+
* It's now possible to correctly compare API objects
5455

5556
Changes
5657
-------

0 commit comments

Comments
 (0)