Remove mark from peer_id

This commit is contained in:
Lonami Exo 2021-09-18 16:29:45 +02:00
parent 9f3bb52e4e
commit 431a9309e3
9 changed files with 45 additions and 89 deletions

View File

@ -31,6 +31,29 @@ will need to migrate that to support the new size requirement of 8 bytes.
For the full list of types changed, please review the above link.
Peer IDs, including chat_id and sender_id, no longer follow bot API conventions
-------------------------------------------------------------------------------
Both the ``utils.get_peer_id`` and ``client.get_peer_id`` methods no longer have an ``add_mark``
parameter. Both will always return the original ID as given by Telegram. This should lead to less
confusion. However, it also means that an integer ID on its own no longer embeds the information
about the type (did it belong to a user, chat, or channel?), so ``utils.get_peer`` can no longer
guess the type from just a number.
Because it's not possible to know what other changes Telegram will do with identifiers, it's
probably best to get used to transparently storing whatever value they send along with the type
separatedly.
As far as I can tell, user, chat and channel identifiers are globally unique, meaning a channel
and a user cannot share the same identifier. The library currently makes this assumption. However,
this is merely an observation (I have never heard of such a collision exist), and Telegram could
change at any time. If you want to be on the safe side, you're encouraged to save a pair of type
and identifier, rather than just the number.
// TODO we DEFINITELY need to provide a way to "upgrade" old ids
// TODO and storing type+number by hand is a pain, provide better alternative
Synchronous compatibility mode has been removed
-----------------------------------------------
@ -244,6 +267,9 @@ The following ``utils`` methods no longer exist or have been made private:
* ``utils.pack_bot_file_id``. It was half-broken.
* ``utils.resolve_invite_link``. It has been broken for a while, so this just makes its removal
official (see `issue #1723 <https://github.com/LonamiWebs/Telethon/issues/1723>`__).
* ``utils.resolve_id``. Marked IDs are no longer used thorough the library. The removal of this
method also means ``utils.get_peer`` can no longer get a ``Peer`` from just a number, as the
type is no longer embedded inside the ID.
// TODO provide the new clean utils

View File

@ -3541,17 +3541,13 @@ class TelegramClient:
async def get_peer_id(
self: 'TelegramClient',
peer: 'hints.EntityLike',
add_mark: bool = True) -> int:
peer: 'hints.EntityLike') -> int:
"""
Gets the ID for the given entity.
This method needs to be ``async`` because `peer` supports usernames,
invite-links, phone numbers (from people in your contact list), etc.
If ``add_mark is False``, then a positive ID will be returned
instead. By default, bot-API style IDs (signed) are returned.
Example
.. code-block:: python

View File

@ -317,10 +317,9 @@ async def _get_peer(self: 'TelegramClient', peer: 'hints.EntityLike'):
async def get_peer_id(
self: 'TelegramClient',
peer: 'hints.EntityLike',
add_mark: bool = True) -> int:
peer: 'hints.EntityLike') -> int:
if isinstance(peer, int):
return utils.get_peer_id(peer, add_mark=add_mark)
return utils.get_peer_id(peer)
try:
if peer.SUBCLASS_OF_ID not in (0x2d45687, 0xc91c90b6):
@ -332,7 +331,7 @@ async def get_peer_id(
if isinstance(peer, _tl.InputPeerSelf):
peer = await self.get_me(input_peer=True)
return utils.get_peer_id(peer, add_mark=add_mark)
return utils.get_peer_id(peer)
async def _get_entity_from_string(self: 'TelegramClient', string):
@ -381,7 +380,7 @@ async def _get_entity_from_string(self: 'TelegramClient', string):
.format(username)) from e
try:
pid = utils.get_peer_id(result.peer, add_mark=False)
pid = utils.get_peer_id(result.peer)
if isinstance(result.peer, _tl.PeerUser):
return next(x for x in result.users if x.id == pid)
else:

View File

@ -119,12 +119,10 @@ class EntityCache:
update.user_id not in dct:
return False
if cid in has_chat_id and \
utils.get_peer_id(_tl.PeerChat(update.chat_id)) not in dct:
if cid in has_chat_id and update.chat_id not in dct:
return False
if cid in has_channel_id and \
utils.get_peer_id(_tl.PeerChannel(update.channel_id)) not in dct:
if cid in has_channel_id and update.channel_id not in dct:
return False
if cid in has_peer and \

View File

@ -961,10 +961,7 @@ def get_inner_text(text, entities):
def get_peer(peer):
try:
if isinstance(peer, int):
pid, cls = resolve_id(peer)
return cls(pid)
elif peer.SUBCLASS_OF_ID == 0x2d45687:
if peer.SUBCLASS_OF_ID == 0x2d45687:
return peer
elif isinstance(peer, (
_tl.contacts.ResolvedPeer, _tl.InputNotifyPeer,
@ -993,24 +990,13 @@ def get_peer(peer):
_raise_cast_fail(peer, 'Peer')
def get_peer_id(peer, add_mark=True):
def get_peer_id(peer):
"""
Convert the given peer into its marked ID by default.
This "mark" comes from the "bot api" format, and with it the peer type
can be identified back. User ID is left unmodified, chat ID is negated,
and channel ID is "prefixed" with -100:
* ``user_id``
* ``-chat_id``
* ``-100channel_id``
The original ID and the peer type class can be returned with
a call to :meth:`resolve_id(marked_id)`.
Extract the integer ID from the given peer.
"""
# First we assert it's a Peer TLObject, or early return for integers
if isinstance(peer, int):
return peer if add_mark else resolve_id(peer)[0]
return peer
# Tell the user to use their client to resolve InputPeerSelf if we got one
if isinstance(peer, _tl.InputPeerSelf):
@ -1024,34 +1010,9 @@ def get_peer_id(peer, add_mark=True):
if isinstance(peer, _tl.PeerUser):
return peer.user_id
elif isinstance(peer, _tl.PeerChat):
# Check in case the user mixed things up to avoid blowing up
if not (0 < peer.chat_id <= 0x7fffffff):
peer.chat_id = resolve_id(peer.chat_id)[0]
return -peer.chat_id if add_mark else peer.chat_id
return peer.chat_id
else: # if isinstance(peer, _tl.PeerChannel):
# Check in case the user mixed things up to avoid blowing up
if not (0 < peer.channel_id <= 0x7fffffff):
peer.channel_id = resolve_id(peer.channel_id)[0]
if not add_mark:
return peer.channel_id
# Growing backwards from -100_0000_000_000 indicates it's a channel
return -(1000000000000 + peer.channel_id)
def resolve_id(marked_id):
"""Given a marked ID, returns the original ID and its :tl:`Peer` type."""
if marked_id >= 0:
return marked_id, _tl.PeerUser
marked_id = -marked_id
if marked_id > 1000000000000:
marked_id -= 1000000000000
return marked_id, _tl.PeerChannel
else:
return marked_id, _tl.PeerChat
return peer.channel_id
def _rle_decode(data):

View File

@ -18,14 +18,7 @@ async def _into_id_set(client, chats):
result = set()
for chat in chats:
if isinstance(chat, int):
if chat < 0:
result.add(chat) # Explicitly marked IDs are negative
else:
result.update({ # Support all valid types of peers
utils.get_peer_id(_tl.PeerUser(chat)),
utils.get_peer_id(_tl.PeerChat(chat)),
utils.get_peer_id(_tl.PeerChannel(chat)),
})
result.add(chat)
elif isinstance(chat, tlobject.TLObject) and chat.SUBCLASS_OF_ID == 0x2d45687:
# 0x2d45687 == crc32(b'Peer')
result.add(utils.get_peer_id(chat))

View File

@ -165,17 +165,8 @@ class MemorySession(Session):
def get_entity_rows_by_id(self, id, exact=True):
try:
if exact:
return next((id, hash) for found_id, hash, _, _, _
in self._entities if found_id == id)
else:
ids = (
utils.get_peer_id(_tl.PeerUser(id)),
utils.get_peer_id(_tl.PeerChat(id)),
utils.get_peer_id(_tl.PeerChannel(id))
)
return next((id, hash) for found_id, hash, _, _, _
in self._entities if found_id in ids)
return next((id, hash) for found_id, hash, _, _, _
in self._entities if found_id == id)
except StopIteration:
pass

View File

@ -316,16 +316,8 @@ class SQLiteSession(MemorySession):
'select id, hash from entities where name = ?', name)
def get_entity_rows_by_id(self, id, exact=True):
if exact:
return self._execute(
'select id, hash from entities where id = ?', id)
else:
return self._execute(
'select id, hash from entities where id in (?,?,?)',
utils.get_peer_id(_tl.PeerUser(id)),
utils.get_peer_id(_tl.PeerChat(id)),
utils.get_peer_id(_tl.PeerChannel(id))
)
return self._execute(
'select id, hash from entities where id = ?', id)
# File processing

View File

@ -32,7 +32,7 @@ AUTO_CASTS = {
}
NAMED_AUTO_CASTS = {
('chat_id', 'int'): 'await client.get_peer_id({}, add_mark=False)'
('chat_id', 'int'): 'await client.get_peer_id({})'
}
# Secret chats have a chat_id which may be negative.