Stop relying on __doc__ in EntityCache

This breaks when running with python -OO (optimized) which
removes the documentation but is crucial. Instead and thanks
to fce5cfea, we can now rely on the type hints instead.
This commit is contained in:
Lonami Exo 2019-05-02 10:19:39 +02:00
parent fce5cfea0e
commit b58c0d3071
2 changed files with 23 additions and 28 deletions

View File

@ -1,15 +1,18 @@
import inspect
import itertools import itertools
from . import utils from . import utils
from .tl import types from .tl import types
# Which updates have the following fields? # Which updates have the following fields?
_has_user_id = [] _has_field = {
_has_chat_id = [] ('user_id', int): [],
_has_channel_id = [] ('chat_id', int): [],
_has_peer = [] ('channel_id', int): [],
_has_dialog_peer = [] ('peer', 'TypePeer'): [],
_has_message = [] ('peer', 'TypeDialogPeer'): [],
('message', 'TypeMessage'): [],
}
# Note: We don't bother checking for some rare: # Note: We don't bother checking for some rare:
# * `UpdateChatParticipantAdd.inviter_id` integer. # * `UpdateChatParticipantAdd.inviter_id` integer.
@ -26,27 +29,18 @@ def _fill():
update = getattr(types, name) update = getattr(types, name)
if getattr(update, 'SUBCLASS_OF_ID', None) == 0x9f89304e: if getattr(update, 'SUBCLASS_OF_ID', None) == 0x9f89304e:
cid = update.CONSTRUCTOR_ID cid = update.CONSTRUCTOR_ID
doc = update.__init__.__doc__ or '' sig = inspect.signature(update.__init__)
if ':param int user_id:' in doc: for param in sig.parameters.values():
_has_user_id.append(cid) vec = _has_field.get((param.name, param.annotation))
if ':param int chat_id:' in doc: if vec is not None:
_has_chat_id.append(cid) vec.append(cid)
if ':param int channel_id:' in doc:
_has_channel_id.append(cid)
if ':param TypePeer peer:' in doc:
_has_peer.append(cid)
if ':param TypeDialogPeer peer:' in doc:
_has_dialog_peer.append(cid)
if ':param TypeMessage message:' in doc:
_has_message.append(cid)
# Future-proof check: if the documentation format ever changes # Future-proof check: if the documentation format ever changes
# then we won't be able to pick the update types we are interested # then we won't be able to pick the update types we are interested
# in, so we must make sure we have at least an update for each field # in, so we must make sure we have at least an update for each field
# which likely means we are doing it right. # which likely means we are doing it right.
if not all((_has_user_id, _has_chat_id, _has_channel_id, if not all(_has_field.values()):
_has_peer, _has_dialog_peer)): raise RuntimeError('FIXME: Did the init signature or updates change?')
raise RuntimeError('FIXME: Did the generated docs or updates change?')
# We use a function to avoid cluttering the globals (with name/update/cid/doc) # We use a function to avoid cluttering the globals (with name/update/cid/doc)
@ -100,10 +94,11 @@ class EntityCache:
def ensure_cached( def ensure_cached(
self, self,
update, update,
has_user_id=frozenset(_has_user_id), has_user_id=frozenset(_has_field[('user_id', int)]),
has_channel_id=frozenset(_has_channel_id), has_chat_id=frozenset(_has_field[('chat_id', int)]),
has_peer=frozenset(_has_peer + _has_dialog_peer), has_channel_id=frozenset(_has_field[('channel_id', int)]),
has_message=frozenset(_has_message) has_peer=frozenset(_has_field[('peer', 'TypePeer')] + _has_field[('peer', 'TypeDialogPeer')]),
has_message=frozenset(_has_field[('message', 'TypeMessage')])
): ):
""" """
Ensures that all the relevant entities in the given update are cached. Ensures that all the relevant entities in the given update are cached.
@ -118,7 +113,7 @@ class EntityCache:
update.user_id not in dct: update.user_id not in dct:
return False return False
if cid in _has_chat_id and \ if cid in has_chat_id and \
utils.get_peer_id(types.PeerChat(update.chat_id)) not in dct: utils.get_peer_id(types.PeerChat(update.chat_id)) not in dct:
return False return False

View File

@ -1,3 +1,3 @@
# Versions should comply with PEP440. # Versions should comply with PEP440.
# This line is parsed in setup.py: # This line is parsed in setup.py:
__version__ = '1.7.3' __version__ = '1.7.4'