Make ConversationHandler attributes immutable (#1756)

* Make ConversationHandler attributes immutable

* Add forgotten name property to test_immutable
This commit is contained in:
Bibo-Joshi 2020-03-30 17:37:37 +02:00 committed by GitHub
parent d55d981e22
commit 982f6707e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 123 additions and 10 deletions

View file

@ -165,23 +165,23 @@ class ConversationHandler(Handler):
persistent=False, persistent=False,
map_to_parent=None): map_to_parent=None):
self.entry_points = entry_points self._entry_points = entry_points
self.states = states self._states = states
self.fallbacks = fallbacks self._fallbacks = fallbacks
self.allow_reentry = allow_reentry self._allow_reentry = allow_reentry
self.per_user = per_user self._per_user = per_user
self.per_chat = per_chat self._per_chat = per_chat
self.per_message = per_message self._per_message = per_message
self.conversation_timeout = conversation_timeout self._conversation_timeout = conversation_timeout
self.name = name self._name = name
if persistent and not self.name: if persistent and not self.name:
raise ValueError("Conversations can't be persistent when handler is unnamed.") raise ValueError("Conversations can't be persistent when handler is unnamed.")
self.persistent = persistent self.persistent = persistent
self._persistence = None self._persistence = None
""":obj:`telegram.ext.BasePersistance`: The persistence used to store conversations. """:obj:`telegram.ext.BasePersistance`: The persistence used to store conversations.
Set by dispatcher""" Set by dispatcher"""
self.map_to_parent = map_to_parent self._map_to_parent = map_to_parent
self.timeout_jobs = dict() self.timeout_jobs = dict()
self._timeout_jobs_lock = Lock() self._timeout_jobs_lock = Lock()
@ -225,6 +225,87 @@ class ConversationHandler(Handler):
"since inline queries have no chat context.") "since inline queries have no chat context.")
break break
@property
def entry_points(self):
return self._entry_points
@entry_points.setter
def entry_points(self, value):
raise ValueError('You can not assign a new value to entry_points after initialization.')
@property
def states(self):
return self._states
@states.setter
def states(self, value):
raise ValueError('You can not assign a new value to states after initialization.')
@property
def fallbacks(self):
return self._fallbacks
@fallbacks.setter
def fallbacks(self, value):
raise ValueError('You can not assign a new value to fallbacks after initialization.')
@property
def allow_reentry(self):
return self._allow_reentry
@allow_reentry.setter
def allow_reentry(self, value):
raise ValueError('You can not assign a new value to allow_reentry after initialization.')
@property
def per_user(self):
return self._per_user
@per_user.setter
def per_user(self, value):
raise ValueError('You can not assign a new value to per_user after initialization.')
@property
def per_chat(self):
return self._per_chat
@per_chat.setter
def per_chat(self, value):
raise ValueError('You can not assign a new value to per_chat after initialization.')
@property
def per_message(self):
return self._per_message
@per_message.setter
def per_message(self, value):
raise ValueError('You can not assign a new value to per_message after initialization.')
@property
def conversation_timeout(self):
return self._conversation_timeout
@conversation_timeout.setter
def conversation_timeout(self, value):
raise ValueError('You can not assign a new value to conversation_timeout after '
'initialization.')
@property
def name(self):
return self._name
@name.setter
def name(self, value):
raise ValueError('You can not assign a new value to name after initialization.')
@property
def map_to_parent(self):
return self._map_to_parent
@map_to_parent.setter
def map_to_parent(self, value):
raise ValueError('You can not assign a new value to map_to_parent after initialization.')
@property @property
def persistence(self): def persistence(self):
return self._persistence return self._persistence

View file

@ -179,6 +179,38 @@ class TestConversationHandler(object):
return self._set_state(update, self.STOPPING) return self._set_state(update, self.STOPPING)
# Tests # Tests
@pytest.mark.parametrize('attr', ['entry_points', 'states', 'fallbacks', 'per_chat', 'name',
'per_user', 'allow_reentry', 'conversation_timeout', 'map_to_parent'],
indirect=False)
def test_immutable(self, attr):
ch = ConversationHandler('entry_points', {'states': ['states']}, 'fallbacks',
per_chat='per_chat',
per_user='per_user', per_message=False,
allow_reentry='allow_reentry',
conversation_timeout='conversation_timeout',
name='name', map_to_parent='map_to_parent')
value = getattr(ch, attr)
if isinstance(value, list):
assert value[0] == attr
elif isinstance(value, dict):
assert list(value.keys())[0] == attr
else:
assert getattr(ch, attr) == attr
with pytest.raises(ValueError, match='You can not assign a new value to {}'.format(attr)):
setattr(ch, attr, True)
def test_immutable_per_message(self):
ch = ConversationHandler('entry_points', {'states': ['states']}, 'fallbacks',
per_chat='per_chat',
per_user='per_user', per_message=False,
allow_reentry='allow_reentry',
conversation_timeout='conversation_timeout',
name='name', map_to_parent='map_to_parent')
assert ch.per_message is False
with pytest.raises(ValueError, match='You can not assign a new value to per_message'):
ch.per_message = True
def test_per_all_false(self): def test_per_all_false(self):
with pytest.raises(ValueError, match="can't all be 'False'"): with pytest.raises(ValueError, match="can't all be 'False'"):
ConversationHandler(self.entry_points, self.states, self.fallbacks, ConversationHandler(self.entry_points, self.states, self.fallbacks,