From 1e17ef1c985eda8569c867c829f0a8f17c823336 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Fri, 3 May 2019 13:59:17 +0200 Subject: [PATCH] Apply several lints --- .github/ISSUE_TEMPLATE.md | 2 +- readthedocs/custom_roles.py | 3 +-- setup.py | 10 +++++----- telethon/client/buttons.py | 3 ++- telethon/client/downloads.py | 11 ++++++++--- telethon/default.py | 5 ----- telethon/errors/__init__.py | 12 +++++------- telethon/network/connection/connection.py | 2 +- telethon/network/connection/http.py | 6 +----- telethon/network/connection/tcpfull.py | 3 ++- telethon/network/connection/tcpmtproxy.py | 18 ++++++++++-------- telethon/network/connection/tcpobfuscated.py | 3 ++- telethon/network/mtprotostate.py | 2 ++ telethon/sessions/memory.py | 3 ++- telethon/sessions/string.py | 17 +++++++++++------ telethon/tl/custom/chatgetter.py | 4 ++++ telethon/tl/custom/inlinebuilder.py | 4 ++++ telethon/tl/custom/message.py | 4 ++-- telethon/tl/custom/sendergetter.py | 10 ++++++++++ telethon/utils.py | 2 -- telethon_generator/generators/errors.py | 4 ++-- telethon_generator/generators/tlobject.py | 3 +++ 22 files changed, 78 insertions(+), 53 deletions(-) delete mode 100644 telethon/default.py diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 858874a7..63896f02 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -9,7 +9,7 @@ If you have a question, ask in https://stackoverflow.com or find the link for th If you paste code, please put it between three backticks (`): ```python -code here +# python code here ``` Once you have read and understood this, delete all this text and detail whatever issue you are posting. diff --git a/readthedocs/custom_roles.py b/readthedocs/custom_roles.py index a9bb9608..bf025fb8 100644 --- a/readthedocs/custom_roles.py +++ b/readthedocs/custom_roles.py @@ -28,6 +28,7 @@ def make_link_node(rawtext, app, name, options): return node +# noinspection PyUnusedLocal def tl_role(name, rawtext, text, lineno, inliner, options=None, content=None): """ Link to the TL reference. @@ -45,8 +46,6 @@ def tl_role(name, rawtext, text, lineno, inliner, options=None, content=None): """ if options is None: options = {} - if content is None: - content = [] # TODO Report error on type not found? # Usage: diff --git a/setup.py b/setup.py index 1456cbcb..7efec8c4 100755 --- a/setup.py +++ b/setup.py @@ -119,19 +119,19 @@ def generate(which): file.unlink() else: def gen_json(fin, fout): - methods = [] + meths = [] constructors = [] for tl in parse_tl(fin, layer): if tl.is_function: - methods.append(tl.to_dict()) + meths.append(tl.to_dict()) else: constructors.append(tl.to_dict()) - what = {'constructors': constructors, 'methods': methods} + what = {'constructors': constructors, 'methods': meths} with open(fout, 'w') as f: json.dump(what, f, indent=2) - for fin, fout in zip(TLOBJECT_IN_TLS, json_files): - gen_json(fin, fout) + for fs in zip(TLOBJECT_IN_TLS, json_files): + gen_json(*fs) if which: print('The following items were not understood:', which) diff --git a/telethon/client/buttons.py b/telethon/client/buttons.py index 9459b014..b6bf6614 100644 --- a/telethon/client/buttons.py +++ b/telethon/client/buttons.py @@ -4,7 +4,8 @@ from .. import utils, events class ButtonMethods(UpdateMethods): - def build_reply_markup(self, buttons, inline_only=False): + @staticmethod + def build_reply_markup(buttons, inline_only=False): """ Builds a :tl`ReplyInlineMarkup` or :tl:`ReplyKeyboardMarkup` for the given buttons, or does nothing if either no buttons are diff --git a/telethon/client/downloads.py b/telethon/client/downloads.py index 77229641..dbd2fe74 100644 --- a/telethon/client/downloads.py +++ b/telethon/client/downloads.py @@ -57,6 +57,8 @@ class DownloadMethods(UserMethods): if not isinstance(entity, TLObject) or entity.SUBCLASS_OF_ID in INPUTS: entity = await self.get_entity(entity) + thumb = -1 if download_big else 0 + possible_names = [] if entity.SUBCLASS_OF_ID not in ENTITIES: photo = entity @@ -68,7 +70,9 @@ class DownloadMethods(UserMethods): return None return await self._download_photo( - entity.chat_photo, file, date=None, progress_callback=None) + entity.chat_photo, file, date=None, + thumb=thumb, progress_callback=None + ) for attr in ('username', 'first_name', 'title'): possible_names.append(getattr(entity, attr, None)) @@ -108,7 +112,7 @@ class DownloadMethods(UserMethods): return await self._download_photo( full.full_chat.chat_photo, file, date=None, progress_callback=None, - thumb=-1 if download_big else 0 + thumb=thumb ) else: # Until there's a report for chats, no need to. @@ -333,7 +337,8 @@ class DownloadMethods(UserMethods): else: return None - def _download_cached_photo_size(self, size, file): + @staticmethod + def _download_cached_photo_size(size, file): # No need to download anything, simply write the bytes if file is bytes: return size.bytes diff --git a/telethon/default.py b/telethon/default.py deleted file mode 100644 index 6ba4ad80..00000000 --- a/telethon/default.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -Sentinel module to signify that a parameter should use its default value. - -Useful when the default value or ``None`` are both valid options. -""" diff --git a/telethon/errors/__init__.py b/telethon/errors/__init__.py index af1e089c..d74b4687 100644 --- a/telethon/errors/__init__.py +++ b/telethon/errors/__init__.py @@ -26,13 +26,13 @@ def rpc_message_to_error(rpc_error, request): # Try to get the error by direct look-up, otherwise regex cls = rpc_errors_dict.get(rpc_error.error_message, None) if cls: - return cls(request) + return cls(request=request) for msg_regex, cls in rpc_errors_re: m = re.match(msg_regex, rpc_error.error_message) if m: capture = int(m.group(1)) if m.groups() else None - return cls(request, capture=capture) + return cls(request=request, capture=capture) # Some errors are negative: # * -500 for "No workers running", @@ -40,8 +40,6 @@ def rpc_message_to_error(rpc_error, request): # # We treat them as if they were positive, so -500 will be treated # as a `ServerError`, etc. - cls = base_errors.get(abs(rpc_error.error_code)) - if cls: - return cls(request, rpc_error.error_message) - - return RPCError(request, rpc_error.error_message, rpc_error.error_code) + cls = base_errors.get(abs(rpc_error.error_code), RPCError) + return cls(request=request, message=rpc_error.error_message, + code=rpc_error.error_code) diff --git a/telethon/network/connection/connection.py b/telethon/network/connection/connection.py index 3ec973b6..5fffaeb2 100644 --- a/telethon/network/connection/connection.py +++ b/telethon/network/connection/connection.py @@ -248,7 +248,7 @@ class PacketCodec(abc.ABC): """ Codec is created when connection is just made. """ - pass + self._conn = connection @abc.abstractmethod def encode_packet(self, data): diff --git a/telethon/network/connection/http.py b/telethon/network/connection/http.py index 253a60b0..e2d976f7 100644 --- a/telethon/network/connection/http.py +++ b/telethon/network/connection/http.py @@ -10,10 +10,6 @@ class HttpPacketCodec(PacketCodec): tag = None obfuscate_tag = None - def __init__(self, connection): - self._ip = connection._ip - self._port = connection._port - def encode_packet(self, data): return ('POST /api HTTP/1.1\r\n' 'Host: {}:{}\r\n' @@ -21,7 +17,7 @@ class HttpPacketCodec(PacketCodec): 'Connection: keep-alive\r\n' 'Keep-Alive: timeout=100000, max=10000000\r\n' 'Content-Length: {}\r\n\r\n' - .format(self._ip, self._port, len(data)) + .format(self._conn._ip, self._conn._port, len(data)) .encode('ascii') + data) async def read_packet(self, reader): diff --git a/telethon/network/connection/tcpfull.py b/telethon/network/connection/tcpfull.py index b9ff7f37..7ebbbe6f 100644 --- a/telethon/network/connection/tcpfull.py +++ b/telethon/network/connection/tcpfull.py @@ -8,7 +8,8 @@ from ...errors import InvalidChecksumError class FullPacketCodec(PacketCodec): tag = None - def __init__(self, _conn): + def __init__(self, connection): + super().__init__(connection) self._send_counter = 0 # Important or Telegram won't reply def encode_packet(self, data): diff --git a/telethon/network/connection/tcpmtproxy.py b/telethon/network/connection/tcpmtproxy.py index 15de79a8..2a9438ab 100644 --- a/telethon/network/connection/tcpmtproxy.py +++ b/telethon/network/connection/tcpmtproxy.py @@ -28,7 +28,8 @@ class MTProxyIO: self._decrypt) = self.init_header( connection._secret, connection._dc_id, connection.packet_codec) - def init_header(self, secret, dc_id, packet_codec): + @staticmethod + def init_header(secret, dc_id, packet_codec): # Validate is_dd = (len(secret) == 17) and (secret[0] == 0xDD) is_rand_codec = issubclass( @@ -93,6 +94,14 @@ class TcpMTProxy(ObfuscatedConnection): packet_codec = None obfuscated_io = MTProxyIO + # noinspection PyUnusedLocal + def __init__(self, ip, port, dc_id, *, loop, loggers, proxy=None): + # connect to proxy's host and port instead of telegram's ones + proxy_host, proxy_port = self.address_info(proxy) + self._secret = bytes.fromhex(proxy[2]) + super().__init__( + proxy_host, proxy_port, dc_id, loop=loop, loggers=loggers) + async def _connect(self, timeout=None, ssl=None): await super()._connect(timeout=timeout, ssl=ssl) @@ -121,13 +130,6 @@ class TcpMTProxy(ObfuscatedConnection): raise ValueError("No proxy info specified for MTProxy connection") return proxy_info[:2] - def __init__(self, ip, port, dc_id, *, loop, loggers, proxy=None): - # connect to proxy's host and port instead of telegram's ones - proxy_host, proxy_port = self.address_info(proxy) - self._secret = bytes.fromhex(proxy[2]) - super().__init__( - proxy_host, proxy_port, dc_id, loop=loop, loggers=loggers) - class ConnectionTcpMTProxyAbridged(TcpMTProxy): """ diff --git a/telethon/network/connection/tcpobfuscated.py b/telethon/network/connection/tcpobfuscated.py index b9c3fc96..6cc10094 100644 --- a/telethon/network/connection/tcpobfuscated.py +++ b/telethon/network/connection/tcpobfuscated.py @@ -17,7 +17,8 @@ class ObfuscatedIO: self._encrypt, self._decrypt) = self.init_header(connection.packet_codec) - def init_header(self, packet_codec): + @staticmethod + def init_header(packet_codec): # Obfuscated messages secrets cannot start with any of these keywords = (b'PVrG', b'GET ', b'POST', b'\xee\xee\xee\xee') while True: diff --git a/telethon/network/mtprotostate.py b/telethon/network/mtprotostate.py index 59341124..05090260 100644 --- a/telethon/network/mtprotostate.py +++ b/telethon/network/mtprotostate.py @@ -39,6 +39,8 @@ class MTProtoState: self._log = loggers[__name__] self.time_offset = 0 self.salt = 0 + + self.id = self._sequence = self._last_msg_id = None self.reset() def reset(self): diff --git a/telethon/sessions/memory.py b/telethon/sessions/memory.py index 1e5db226..02f07cff 100644 --- a/telethon/sessions/memory.py +++ b/telethon/sessions/memory.py @@ -86,7 +86,8 @@ class MemorySession(Session): def delete(self): pass - def _entity_values_to_row(self, id, hash, username, phone, name): + @staticmethod + def _entity_values_to_row(id, hash, username, phone, name): # While this is a simple implementation it might be overrode by, # other classes so they don't need to implement the plural form # of the method. Don't remove. diff --git a/telethon/sessions/string.py b/telethon/sessions/string.py index 666e177b..1b19a2c0 100644 --- a/telethon/sessions/string.py +++ b/telethon/sessions/string.py @@ -25,10 +25,7 @@ class StringSession(MemorySession): * `encode` definition must be ``def encode(value: bytes) -> str:``. * `decode` definition must be ``def decode(value: str) -> bytes:``. """ - encode = lambda x: base64.urlsafe_b64encode(x).decode('ascii') - decode = base64.urlsafe_b64decode - - def __init__(self, string=None): + def __init__(self, string: str = None): super().__init__() if string: if string[0] != CURRENT_VERSION: @@ -37,18 +34,26 @@ class StringSession(MemorySession): string = string[1:] ip_len = 4 if len(string) == 352 else 16 self._dc_id, ip, self._port, key = struct.unpack( - _STRUCT_PREFORMAT.format(ip_len), StringSession.decode(string)) + _STRUCT_PREFORMAT.format(ip_len), self.decode(string)) self._server_address = ipaddress.ip_address(ip).compressed if any(key): self._auth_key = AuthKey(key) + @staticmethod + def encode(x: bytes) -> str: + return base64.urlsafe_b64encode(x).decode('ascii') + + @staticmethod + def decode(x: str) -> bytes: + return base64.urlsafe_b64decode(x) + def save(self): if not self._auth_key: return '' ip = ipaddress.ip_address(self._server_address).packed - return CURRENT_VERSION + StringSession.encode(struct.pack( + return CURRENT_VERSION + self.encode(struct.pack( _STRUCT_PREFORMAT.format(len(ip)), self._dc_id, ip, diff --git a/telethon/tl/custom/chatgetter.py b/telethon/tl/custom/chatgetter.py index 9db7a03d..791c156c 100644 --- a/telethon/tl/custom/chatgetter.py +++ b/telethon/tl/custom/chatgetter.py @@ -14,6 +14,10 @@ class ChatGetter(abc.ABC): `_input_chat`, `_chat_peer`, `_broadcast` and `_client`. As an end user, you should not worry about this. """ + def __init__(self): + self._chat = self._input_chat = self._chat_peer = \ + self._client = self._broadcast = None + @property def chat(self): """ diff --git a/telethon/tl/custom/inlinebuilder.py b/telethon/tl/custom/inlinebuilder.py index 0ee5a702..5edb1438 100644 --- a/telethon/tl/custom/inlinebuilder.py +++ b/telethon/tl/custom/inlinebuilder.py @@ -56,6 +56,7 @@ class InlineBuilder: def __init__(self, client): self._client = client + # noinspection PyIncorrectDocstring async def article( self, title, description=None, *, url=None, thumb=None, content=None, @@ -107,6 +108,7 @@ class InlineBuilder: return result + # noinspection PyIncorrectDocstring async def photo( self, file, *, id=None, text=None, parse_mode=(), link_preview=True, @@ -154,6 +156,7 @@ class InlineBuilder: return result + # noinspection PyIncorrectDocstring async def document( self, file, title=None, *, description=None, type=None, mime_type=None, attributes=None, force_document=False, @@ -236,6 +239,7 @@ class InlineBuilder: return result + # noinspection PyIncorrectDocstring async def game( self, short_name, *, id=None, text=None, parse_mode=(), link_preview=True, diff --git a/telethon/tl/custom/message.py b/telethon/tl/custom/message.py index c1304bc2..509a1462 100644 --- a/telethon/tl/custom/message.py +++ b/telethon/tl/custom/message.py @@ -519,12 +519,12 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC): @property def action_entities(self): """ - Returns a list of entities that can took part in this action. + Returns a list of entities that took part in this action. Possible cases for this are :tl:`MessageActionChatAddUser`, :tl:`types.MessageActionChatCreate`, :tl:`MessageActionChatDeleteUser`, :tl:`MessageActionChatJoinedByLink` :tl:`MessageActionChatMigrateTo` - and :tl:`MessageActionChannelMigrateFrom). + and :tl:`MessageActionChannelMigrateFrom`. If the action is neither of those, the result will be ``None``. If some entities could not be retrieved, the list may contain diff --git a/telethon/tl/custom/sendergetter.py b/telethon/tl/custom/sendergetter.py index 9c9724fc..c81073a9 100644 --- a/telethon/tl/custom/sendergetter.py +++ b/telethon/tl/custom/sendergetter.py @@ -11,6 +11,10 @@ class SenderGetter(abc.ABC): `_input_sender`, `_sender_id` and `_client`. As an end user, you should not worry about this. """ + def __init__(self): + self._sender = self._input_sender = self._sender_id = \ + self._client = None + @property def sender(self): """ @@ -79,3 +83,9 @@ class SenderGetter(abc.ABC): """ Re-fetches sender information through other means. """ + + @abc.abstractmethod + async def _reload_message(self): + """ + Subclasses should implement message reloading. + """ diff --git a/telethon/utils.py b/telethon/utils.py index d45ad39b..e6bfe7b2 100644 --- a/telethon/utils.py +++ b/telethon/utils.py @@ -1139,8 +1139,6 @@ class AsyncClassWrapper: if callable(w): return wrapper - elif isinstance(w, property): - return w.fget(self.wrapped) else: return w diff --git a/telethon_generator/generators/errors.py b/telethon_generator/generators/errors.py index f373a5a1..6f5a6021 100644 --- a/telethon_generator/generators/errors.py +++ b/telethon_generator/generators/errors.py @@ -27,7 +27,7 @@ def generate_errors(errors, f): # Error classes generation for error in errors: f.write('\n\nclass {}({}):\n' - ' def __init__(self, request, **kwargs):\n' + ' def __init__(self, **kwargs):\n' ' '.format(error.name, error.subclass)) if error.has_captures: @@ -40,7 +40,7 @@ def generate_errors(errors, f): if error.has_captures: f.write('.format({0}=self.{0})'.format(error.capture_name)) - f.write(' + self._fmt_request(request))\n') + f.write(" + self._fmt_request(kwargs['request']))\n") # Create the actual {CODE: ErrorClassName} dict once classes are defined f.write('\n\nrpc_errors_dict = {\n') diff --git a/telethon_generator/generators/tlobject.py b/telethon_generator/generators/tlobject.py index 1636a944..5e7f066d 100644 --- a/telethon_generator/generators/tlobject.py +++ b/telethon_generator/generators/tlobject.py @@ -206,6 +206,9 @@ def _write_class_init(tlobject, kind, type_constructors, builder): if not tlobject.real_args: return + if any(a.name in __builtins__ for a in tlobject.real_args): + builder.writeln('# noinspection PyShadowingBuiltins') + builder.writeln("def __init__({}):", ', '.join(['self'] + args)) builder.writeln('"""') if tlobject.is_function: