From 55789ca3276cf88c228eaa6caaa8f6b2c8737fe1 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Fri, 6 Jul 2018 13:11:32 +0200 Subject: [PATCH] Work around a bug where queue.Queue returns never-inserted lists --- telethon/network/mtprotosender.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/telethon/network/mtprotosender.py b/telethon/network/mtprotosender.py index bb723481..fa86d2ea 100644 --- a/telethon/network/mtprotosender.py +++ b/telethon/network/mtprotosender.py @@ -755,12 +755,29 @@ class _ContainerQueue(queue.Queue): result = [result] while not self.empty(): - item = self.get_nowait() - if item == _reconnect_sentinel or\ - isinstance(item.obj, MessageContainer): - self.put_nowait(item) - break - else: - result.append(item) + # TODO Is this a bug in Python? For some reason get_nowait() + # sometimes returns a *list* even when one was *never* put. + # + # This can be seen by overriding `_put` to track if a list + # is ever inserted. The issue occurs when getting invoking + # many requests at once (thus a lot of messages are put + # really fast). With `_put` override it can be seen that + # no `list` is ever inserted but `get_nowait` may return it. + # + # If we use `self.queue.popleft()` it doesn't seem to occur + # which is the method that gets ultimately used. + # + # To work around that issue, always convert the result to + # a list, so if it's a list, we don't need to do anything. + items = self.get_nowait() + if not isinstance(items, list): + items = [items] + for item in items: + if item == _reconnect_sentinel or\ + isinstance(item.obj, MessageContainer): + self.put_nowait(item) + break + else: + result.append(item) return result