-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add equality rich comparision operators to telegram objects #604
Changes from 13 commits
2b28f12
63763c6
83e3de1
c2ac3a8
6693054
cd0b996
34ac663
65b108c
67e8291
bfe808c
faa1e98
ce25412
1419561
e596fce
90a0a59
590f6f5
2bb3ab0
98974a1
dc79f40
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,3 +80,25 @@ def to_dict(self): | |
data[key] = value | ||
|
||
return data | ||
|
||
def _get_id(self): | ||
for x in ['id', 'file_id', 'message_id', 'result_id', 'update_id']: | ||
if hasattr(self, x): | ||
return self.__getattribute__(x) | ||
raise NotImplementedError | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I return NotImplementedError as a way of saying "this object doesn't implement an id", which many objects do not (pretty much all objects not mentioned in the OP). This is why I'm catching it inside of |
||
|
||
def __eq__(self, other): | ||
if isinstance(other, self.__class__): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is one of the few places where I prefer comparing the class, instead of using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I see it, if I subclass |
||
try: | ||
return self._get_id() == other._get_id() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: you're accessing a private method There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd say it's okay since I'm checking the type of the class first, so I know with almost 100% certainty how There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's a big issue then I can make the _get_id() works either as a static method or just move it out of the class entirely and then have it accept the object to extract id from. |
||
except NotImplementedError: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't happen if you properly perform the class comparison above. |
||
pass # return NotImplemented | ||
return NotImplemented | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I return NotImplemented as a way of telling the interpreter to try the comparison the other way around. This allows the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can go with your take on
|
||
|
||
def __hash__(self): | ||
try: | ||
return hash(( | ||
self.__class__, | ||
self._get_id(),)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style nitpick: the entire There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not according to my yapf There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is what I meant. Cleaner and works with yapf ;-)
|
||
except NotImplementedError: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think catching |
||
return super().__hash__() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,3 +64,11 @@ def de_json(data, bot): | |
data['user'] = User.de_json(data.get('user'), bot) | ||
|
||
return ChatMember(**data) | ||
|
||
def __eq__(self, other): | ||
if isinstance(other, self.__class__): | ||
return self.user == other.user and self.status == other.status | ||
return NotImplemented | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this will be more appropriate: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mmm... following the comments above. |
||
|
||
def __hash__(self): | ||
return hash((self.__class__, self.user, self.status)) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#!/usr/bin/env python | ||
# | ||
# A library that provides a Python interface to the Telegram Bot API | ||
# Copyright (C) 2015-2016 | ||
# Leandro Toledo de Souza <devs@python-telegram-bot.org> | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see [http://www.gnu.org/licenses/]. | ||
"""This module contains an object that represents Tests for Telegram Animation""" | ||
|
||
import unittest | ||
import sys | ||
|
||
sys.path.append('.') | ||
|
||
import telegram | ||
from tests.base import BaseTest | ||
|
||
|
||
class AnimationTest(BaseTest, unittest.TestCase): | ||
"""This object represents Tests for Telegram Animation.""" | ||
|
||
def setUp(self): | ||
self.animation_file_id = 'CgADBAADFQEAAny4rAUgukhiTv2TWwI' | ||
self.thumb = telegram.PhotoSize.de_json({ | ||
'height': 50, | ||
'file_size': 1613, | ||
'file_id': 'AAQEABPQUWQZAAT7gZuQAAH0bd93VwACAg', | ||
'width': 90 | ||
}, self._bot) | ||
self.file_name = "game.gif.mp4" | ||
self.mime_type = "video/mp4" | ||
self.file_size = 4008 | ||
|
||
self.json_dict = { | ||
'file_id': self.animation_file_id, | ||
'thumb': self.thumb.to_dict(), | ||
'file_name': self.file_name, | ||
'mime_type': self.mime_type, | ||
'file_size': self.file_size | ||
} | ||
|
||
def test_animation_de_json(self): | ||
animation = telegram.Animation.de_json(self.json_dict, self._bot) | ||
|
||
self.assertEqual(animation.file_id, self.animation_file_id) | ||
self.assertEqual(animation.thumb, self.thumb) | ||
self.assertEqual(animation.file_name, self.file_name) | ||
self.assertEqual(animation.mime_type, self.mime_type) | ||
self.assertEqual(animation.file_size, self.file_size) | ||
|
||
def test_animation_to_json(self): | ||
animation = telegram.Animation.de_json(self.json_dict, self._bot) | ||
|
||
self.assertTrue(self.is_json(animation.to_json())) | ||
|
||
def test_animation_to_dict(self): | ||
animation = telegram.Animation.de_json(self.json_dict, self._bot) | ||
|
||
self.assertTrue(self.is_dict(animation.to_dict())) | ||
self.assertEqual(animation['file_id'], self.animation_file_id) | ||
self.assertEqual(animation['thumb'], self.thumb) | ||
self.assertEqual(animation['file_name'], self.file_name) | ||
self.assertEqual(animation['mime_type'], self.mime_type) | ||
self.assertEqual(animation['file_size'], self.file_size) | ||
|
||
def test_equality(self): | ||
a = telegram.Animation(self.animation_file_id) | ||
b = telegram.Animation(self.animation_file_id) | ||
d = telegram.Animation("") | ||
e = telegram.Voice(self.animation_file_id, 0) | ||
|
||
self.assertEqual(a, b) | ||
self.assertEqual(hash(a), hash(b)) | ||
self.assertIsNot(a, b) | ||
|
||
self.assertNotEqual(a, d) | ||
self.assertNotEqual(hash(a), hash(d)) | ||
|
||
self.assertNotEqual(a, e) | ||
self.assertNotEqual(hash(a), hash(e)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually prefer using
getattr(self, x)
. Any reason you chose to use__getattribute__
here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd forgotten it existed... I'll change it :D