diff --git a/client/pyproject.toml b/client/pyproject.toml index a418124d..dd9a292e 100644 --- a/client/pyproject.toml +++ b/client/pyproject.toml @@ -31,6 +31,7 @@ dev = [ "isort~=5.12", "black~=23.3.0", "mypy~=1.3", + "ruff~=0.0.292", "pytest~=7.3", "pytest-asyncio~=0.21", ] @@ -51,3 +52,8 @@ build-backend = "setuptools.build_meta" [tool.setuptools.dynamic] version = {attr = "telethon.version.__version__"} + +[tool.ruff] +ignore = [ + "E501", # formatter takes care of lines that are too long besides documentation +] diff --git a/client/src/telethon/__init__.py b/client/src/telethon/__init__.py index 2ad99319..2c444947 100644 --- a/client/src/telethon/__init__.py +++ b/client/src/telethon/__init__.py @@ -5,6 +5,5 @@ from ._impl import tl as _tl from ._impl.client import Client from ._impl.client.errors import errors from ._impl.mtproto import RpcError -from .version import __version__ __all__ = ["_tl", "Client", "errors", "RpcError"] diff --git a/client/src/telethon/_impl/client/client/__init__.py b/client/src/telethon/_impl/client/client/__init__.py index 13bf806f..21b01780 100644 --- a/client/src/telethon/_impl/client/client/__init__.py +++ b/client/src/telethon/_impl/client/client/__init__.py @@ -1,10 +1,8 @@ -from .bots import InlineResult, InlineResults from .client import Client from .net import Config __all__ = [ "InlineResult", - "InlineResults", "Client", "Config", ] diff --git a/client/src/telethon/_impl/client/client/bots.py b/client/src/telethon/_impl/client/client/bots.py index 8b47ab30..3a17db9e 100644 --- a/client/src/telethon/_impl/client/client/bots.py +++ b/client/src/telethon/_impl/client/client/bots.py @@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, AsyncIterator, List, Optional, Self from ...tl import abcs, functions, types from ..types import ChatLike, InlineResult, NoPublicConstructor -from ..utils import generate_random_id if TYPE_CHECKING: from .client import Client diff --git a/client/src/telethon/_impl/client/client/client.py b/client/src/telethon/_impl/client/client/client.py index 54a4c111..f890798b 100644 --- a/client/src/telethon/_impl/client/client/client.py +++ b/client/src/telethon/_impl/client/client/client.py @@ -42,6 +42,7 @@ from ..types import ( Draft, File, InFileLike, + InlineResult, LoginToken, Message, OutFileLike, @@ -59,7 +60,7 @@ from .auth import ( sign_in, sign_out, ) -from .bots import InlineResult, inline_query +from .bots import inline_query from .chats import ( get_admin_log, get_participants, @@ -92,7 +93,6 @@ from .messages import ( unpin_message, ) from .net import ( - DEFAULT_DC, Config, connect, connected, diff --git a/client/src/telethon/_impl/client/client/files.py b/client/src/telethon/_impl/client/client/files.py index da2eafc0..8482a4e9 100644 --- a/client/src/telethon/_impl/client/client/files.py +++ b/client/src/telethon/_impl/client/client/files.py @@ -1,7 +1,6 @@ from __future__ import annotations import hashlib -import math import mimetypes import urllib.parse from inspect import isawaitable diff --git a/client/src/telethon/_impl/client/client/messages.py b/client/src/telethon/_impl/client/client/messages.py index 3b8bb0b5..ba9d40a4 100644 --- a/client/src/telethon/_impl/client/client/messages.py +++ b/client/src/telethon/_impl/client/client/messages.py @@ -2,7 +2,7 @@ from __future__ import annotations import datetime import sys -from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Tuple, TypeVar, Union +from typing import TYPE_CHECKING, Dict, List, Literal, Optional, Tuple, Union from ...session import PackedChat from ...tl import abcs, functions, types diff --git a/client/src/telethon/_impl/client/client/net.py b/client/src/telethon/_impl/client/client/net.py index b22a9aee..a5e67137 100644 --- a/client/src/telethon/_impl/client/client/net.py +++ b/client/src/telethon/_impl/client/client/net.py @@ -12,7 +12,7 @@ from ...mtproto import Full, RpcError from ...mtsender import Sender from ...mtsender import connect as connect_without_auth from ...mtsender import connect_with_auth -from ...session import DataCenter, Session +from ...session import DataCenter from ...session import User as SessionUser from ...tl import LAYER, Request, functions, types from ..errors import adapt_rpc @@ -154,7 +154,7 @@ async def connect(self: Client) -> None: except RpcError as e: if e.code == 401: self._session.user = None - except Exception as e: + except Exception: pass else: if not self._session.user: diff --git a/client/src/telethon/_impl/client/client/updates.py b/client/src/telethon/_impl/client/client/updates.py index 0a506374..06ecf43c 100644 --- a/client/src/telethon/_impl/client/client/updates.py +++ b/client/src/telethon/_impl/client/client/updates.py @@ -130,7 +130,7 @@ async def dispatcher(client: Client) -> None: except asyncio.CancelledError: return except Exception as e: - if isinstance(e, RuntimeError) and loop.is_closed: + if isinstance(e, RuntimeError) and loop.is_closed(): # User probably forgot to call disconnect. logging.warning( "client was not closed cleanly, make sure to call client.disconnect()! %s", diff --git a/client/src/telethon/_impl/client/client/users.py b/client/src/telethon/_impl/client/client/users.py index 33c64733..9105dced 100644 --- a/client/src/telethon/_impl/client/client/users.py +++ b/client/src/telethon/_impl/client/client/users.py @@ -50,7 +50,7 @@ def resolved_peer_to_chat(resolved: abcs.contacts.ResolvedPeer) -> Chat: if chat := map.get(peer_id(resolved.peer)): return chat else: - raise ValueError(f"no matching chat found in response") + raise ValueError("no matching chat found in response") async def resolve_phone(client: Client, phone: str) -> Chat: diff --git a/client/src/telethon/_impl/client/types/__init__.py b/client/src/telethon/_impl/client/types/__init__.py index b1f7452d..4f781d18 100644 --- a/client/src/telethon/_impl/client/types/__init__.py +++ b/client/src/telethon/_impl/client/types/__init__.py @@ -3,12 +3,12 @@ from .chat import Channel, Chat, ChatLike, Group, RestrictionReason, User from .dialog import Dialog from .draft import Draft from .file import File, InFileLike, OutFileLike, OutWrapper +from .inline_result import InlineResult from .login_token import LoginToken from .message import Message from .meta import NoPublicConstructor from .participant import Participant from .password_token import PasswordToken -from .inline_result import InlineResult from .recent_action import RecentAction __all__ = [ diff --git a/client/src/telethon/_impl/client/types/dialog.py b/client/src/telethon/_impl/client/types/dialog.py index aff46fe0..e0d12b64 100644 --- a/client/src/telethon/_impl/client/types/dialog.py +++ b/client/src/telethon/_impl/client/types/dialog.py @@ -1,7 +1,6 @@ -from typing import Dict, List, Optional, Self +from typing import Dict, Self -from ...session import PackedChat, PackedType -from ...tl import abcs, types +from ...tl import abcs from .chat import Chat from .meta import NoPublicConstructor diff --git a/client/src/telethon/_impl/client/types/draft.py b/client/src/telethon/_impl/client/types/draft.py index 8cb80509..04f4c9ce 100644 --- a/client/src/telethon/_impl/client/types/draft.py +++ b/client/src/telethon/_impl/client/types/draft.py @@ -1,7 +1,6 @@ -from typing import Dict, List, Optional, Self +from typing import Dict, Self -from ...session import PackedChat, PackedType -from ...tl import abcs, types +from ...tl import types from .chat import Chat from .meta import NoPublicConstructor diff --git a/client/src/telethon/_impl/client/types/file.py b/client/src/telethon/_impl/client/types/file.py index 95baa911..6aa3d37e 100644 --- a/client/src/telethon/_impl/client/types/file.py +++ b/client/src/telethon/_impl/client/types/file.py @@ -1,10 +1,8 @@ from __future__ import annotations import mimetypes -import os from inspect import isawaitable -from io import BufferedReader, BufferedWriter -from mimetypes import guess_type +from io import BufferedWriter from pathlib import Path from typing import TYPE_CHECKING, Any, Coroutine, List, Optional, Protocol, Self, Union diff --git a/client/src/telethon/_impl/client/types/inline_result.py b/client/src/telethon/_impl/client/types/inline_result.py index e5d908e0..86471a6f 100644 --- a/client/src/telethon/_impl/client/types/inline_result.py +++ b/client/src/telethon/_impl/client/types/inline_result.py @@ -2,11 +2,11 @@ from __future__ import annotations from typing import TYPE_CHECKING, Optional, Union +from ...tl import abcs, functions, types from ..utils import generate_random_id -from ...tl import abcs, types, functions from .chat import ChatLike -from .meta import NoPublicConstructor from .message import Message +from .meta import NoPublicConstructor if TYPE_CHECKING: from ..client import Client diff --git a/client/src/telethon/_impl/client/types/participant.py b/client/src/telethon/_impl/client/types/participant.py index fd41910e..912eadd1 100644 --- a/client/src/telethon/_impl/client/types/participant.py +++ b/client/src/telethon/_impl/client/types/participant.py @@ -1,6 +1,5 @@ -from typing import Dict, List, Optional, Self, Union +from typing import Dict, Self, Union -from ...session import PackedChat, PackedType from ...tl import abcs, types from .chat import Chat from .meta import NoPublicConstructor diff --git a/client/src/telethon/_impl/client/types/recent_action.py b/client/src/telethon/_impl/client/types/recent_action.py index ffb1acc0..f93a011d 100644 --- a/client/src/telethon/_impl/client/types/recent_action.py +++ b/client/src/telethon/_impl/client/types/recent_action.py @@ -1,6 +1,5 @@ -from typing import Dict, List, Optional, Self, Union +from typing import Dict -from ...session import PackedChat, PackedType from ...tl import abcs, types from .chat import Chat from .meta import NoPublicConstructor diff --git a/client/src/telethon/_impl/client/utils.py b/client/src/telethon/_impl/client/utils.py index 1fba9fa2..b1ffda26 100644 --- a/client/src/telethon/_impl/client/utils.py +++ b/client/src/telethon/_impl/client/utils.py @@ -2,17 +2,7 @@ import itertools import sys import time from collections import defaultdict -from typing import ( - Any, - Callable, - DefaultDict, - Dict, - Iterator, - List, - Optional, - Union, - cast, -) +from typing import DefaultDict, Dict, List, Optional, Union from ..tl import abcs, types from .types import Channel, Chat, Group, User diff --git a/client/src/telethon/_impl/crypto/aes.py b/client/src/telethon/_impl/crypto/aes.py index a7cb70d9..ada0ece2 100644 --- a/client/src/telethon/_impl/crypto/aes.py +++ b/client/src/telethon/_impl/crypto/aes.py @@ -56,11 +56,17 @@ def ige_decrypt(ciphertext: bytes, key: bytes, iv: bytes) -> bytes: try: import cryptg - ige_encrypt = lambda t, k, i: cryptg.encrypt_ige( - bytes(t) if not isinstance(t, bytes) else t, k, i - ) - ige_decrypt = lambda t, k, i: cryptg.decrypt_ige( - bytes(t) if not isinstance(t, bytes) else t, k, i - ) + def ige_encrypt(plaintext: bytes, key: bytes, iv: bytes) -> bytes: # noqa: F811 + return cryptg.encrypt_ige( + bytes(plaintext) if not isinstance(plaintext, bytes) else plaintext, key, iv + ) + + def ige_decrypt(ciphertext: bytes, key: bytes, iv: bytes) -> bytes: # noqa: F811 + return cryptg.decrypt_ige( + bytes(ciphertext) if not isinstance(ciphertext, bytes) else ciphertext, + key, + iv, + ) + except ImportError: pass diff --git a/client/src/telethon/_impl/session/session.py b/client/src/telethon/_impl/session/session.py index d97599f3..9a008e60 100644 --- a/client/src/telethon/_impl/session/session.py +++ b/client/src/telethon/_impl/session/session.py @@ -1,5 +1,4 @@ -import base64 -from typing import Any, Dict, List, Optional, Self +from typing import List, Optional class DataCenter: diff --git a/client/src/telethon/_impl/session/storage/__init__.py b/client/src/telethon/_impl/session/storage/__init__.py index 285e8822..3a8e4b11 100644 --- a/client/src/telethon/_impl/session/storage/__init__.py +++ b/client/src/telethon/_impl/session/storage/__init__.py @@ -6,10 +6,11 @@ from .storage import Storage try: from .sqlite import SqliteSession except ImportError as e: + import_err = e class SqliteSession(Storage): # type: ignore [no-redef] def __init__(self, *args: Any, **kwargs: Any) -> None: - raise e from None + raise import_err from None __all__ = ["MemorySession", "Storage", "SqliteSession"] diff --git a/client/src/telethon/_impl/tl/mtproto/core.py b/client/src/telethon/_impl/tl/mtproto/core.py index 4fcabbf3..b61995e4 100644 --- a/client/src/telethon/_impl/tl/mtproto/core.py +++ b/client/src/telethon/_impl/tl/mtproto/core.py @@ -1 +1 @@ -from ..core import * +from ..core import * # noqa: F403 diff --git a/client/src/telethon/types.py b/client/src/telethon/types.py index 1fea0edc..482fb856 100644 --- a/client/src/telethon/types.py +++ b/client/src/telethon/types.py @@ -1,7 +1,7 @@ """ Classes for the various objects the library returns. """ -from ._impl.client.client import Config, InlineResult +from ._impl.client.client import Config from ._impl.client.types import ( AsyncList, Channel, @@ -11,6 +11,7 @@ from ._impl.client.types import ( File, Group, InFileLike, + InlineResult, LoginToken, Message, OutFileLike, diff --git a/client/tests/mtsender_test.py b/client/tests/mtsender_test.py index 49f5599a..bc86ef87 100644 --- a/client/tests/mtsender_test.py +++ b/client/tests/mtsender_test.py @@ -4,7 +4,6 @@ import logging from pytest import LogCaptureFixture, mark from telethon._impl.mtproto import Full from telethon._impl.mtsender import connect -from telethon._impl.session import DataCenter from telethon._impl.tl import LAYER, abcs, functions, types TELEGRAM_TEST_DC = 2, "149.154.167.40:443" diff --git a/generator/pyproject.toml b/generator/pyproject.toml index 9a8f4ec7..483277db 100644 --- a/generator/pyproject.toml +++ b/generator/pyproject.toml @@ -36,3 +36,8 @@ build-backend = "setuptools.build_meta" [tool.setuptools.dynamic] version = {attr = "telethon_generator.__version__"} + +[tool.ruff] +ignore = [ + "E501", # formatter takes care of lines that are too long besides documentation +] diff --git a/generator/src/telethon_generator/__init__.py b/generator/src/telethon_generator/__init__.py index f393a924..c144af21 100644 --- a/generator/src/telethon_generator/__init__.py +++ b/generator/src/telethon_generator/__init__.py @@ -1,4 +1,3 @@ from . import codegen, tl_parser -from .version import __version__ __all__ = ["codegen", "tl_parser"] diff --git a/generator/src/telethon_generator/_impl/codegen/generator.py b/generator/src/telethon_generator/_impl/codegen/generator.py index 2acb9193..938fc43e 100644 --- a/generator/src/telethon_generator/_impl/codegen/generator.py +++ b/generator/src/telethon_generator/_impl/codegen/generator.py @@ -94,10 +94,10 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None: writer = fs.open(type_path) if type_path not in fs: - writer.write(f"import struct") - writer.write(f"from typing import List, Optional, Self") - writer.write(f"from .. import abcs") - writer.write(f"from ..core import Reader, Serializable, serialize_bytes_to") + writer.write("import struct") + writer.write("from typing import List, Optional, Self") + writer.write("from .. import abcs") + writer.write("from ..core import Reader, Serializable, serialize_bytes_to") ns = f"{typedef.namespace[0]}." if typedef.namespace else "" generated_type_names.add(f"{ns}{to_class_name(typedef.name)}") @@ -112,8 +112,8 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None: writer.write(f" __slots__ = ({slots})") # def constructor_id() - writer.write(f" @classmethod") - writer.write(f" def constructor_id(_) -> int:") + writer.write(" @classmethod") + writer.write(" def constructor_id(_) -> int:") writer.write(f" return {hex(typedef.id)}") # def __init__() @@ -126,8 +126,8 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None: writer.write(f" _s.{p.name} = {p.name}") # def _read_from() - writer.write(f" @classmethod") - writer.write(f" def _read_from(cls, reader: Reader) -> Self:") + writer.write(" @classmethod") + writer.write(" def _read_from(cls, reader: Reader) -> Self:") writer.indent(2) generate_read(writer, typedef) params = ", ".join(f"{p.name}={param_value_fmt(p)}" for p in property_params) @@ -135,13 +135,13 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None: writer.dedent(2) # def _write_to() - writer.write(f" def _write_to(self, buffer: bytearray) -> None:") + writer.write(" def _write_to(self, buffer: bytearray) -> None:") if typedef.params: writer.indent(2) generate_write(writer, typedef) writer.dedent(2) else: - writer.write(f" pass") + writer.write(" pass") for functiondef in tl.functiondefs: if len(functiondef.namespace) >= 2: @@ -158,10 +158,10 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None: writer = fs.open(function_path) if function_path not in fs: - writer.write(f"import struct") - writer.write(f"from typing import List, Optional, Self") - writer.write(f"from .. import abcs") - writer.write(f"from ..core import Request, serialize_bytes_to") + writer.write("import struct") + writer.write("from typing import List, Optional, Self") + writer.write("from .. import abcs") + writer.write("from ..core import Request, serialize_bytes_to") # def name(params, ...) required_params = [p for p in functiondef.params if not is_computed(p.ty)] @@ -182,11 +182,11 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None: ) writer = fs.open(Path("layer.py")) - writer.write(f"from . import abcs, types") + writer.write("from . import abcs, types") writer.write( - f"from .core import Serializable, Reader, deserialize_bool, deserialize_i32_list, deserialize_i64_list, deserialize_identity, single_deserializer, list_deserializer" + "from .core import Serializable, Reader, deserialize_bool, deserialize_i32_list, deserialize_i64_list, deserialize_identity, single_deserializer, list_deserializer" ) - writer.write(f"from typing import cast, Tuple, Type") + writer.write("from typing import cast, Tuple, Type") writer.write(f"LAYER = {tl.layer!r}") writer.write( "TYPE_MAPPING = {t.constructor_id(): t for t in cast(Tuple[Type[Serializable]], (" @@ -200,4 +200,4 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None: f" {hex(functiondef.id)}: {function_deserializer_fmt(functiondef)}," ) writer.write("}") - writer.write(f"__all__ = ['LAYER', 'TYPE_MAPPING', 'RESPONSE_MAPPING']") + writer.write("__all__ = ['LAYER', 'TYPE_MAPPING', 'RESPONSE_MAPPING']") diff --git a/generator/src/telethon_generator/_impl/codegen/serde/deserialization.py b/generator/src/telethon_generator/_impl/codegen/serde/deserialization.py index 66c58442..d417a82b 100644 --- a/generator/src/telethon_generator/_impl/codegen/serde/deserialization.py +++ b/generator/src/telethon_generator/_impl/codegen/serde/deserialization.py @@ -20,13 +20,13 @@ def reader_read_fmt(ty: Type, constructor_id: int) -> Tuple[str, Optional[str]]: size = struct.calcsize(f"<{fmt}") return f"reader.read_fmt(f'<{fmt}', {size})[0]", None elif ty.name == "string": - return f"str(reader.read_bytes(), 'utf-8', 'replace')", None + return "str(reader.read_bytes(), 'utf-8', 'replace')", None elif ty.name == "bytes": - return f"b'' + reader.read_bytes()", None + return "b'' + reader.read_bytes()", None elif ty.name == "int128": - return f"int.from_bytes(reader.read(16))", None + return "int.from_bytes(reader.read(16))", None elif ty.name == "int256": - return f"int.from_bytes(reader.read(32))", None + return "int.from_bytes(reader.read(32))", None elif ty.bare: return f"{to_class_name(ty.name)}._read_from(reader)", None elif ty.name == "Object": @@ -60,11 +60,11 @@ def generate_normal_param_read( ) if param.ty.bare: - writer.write(f"__len = reader.read_fmt('= 0") + writer.write("__len = reader.read_fmt('= 0") else: - writer.write(f"__vid, __len = reader.read_fmt('= 0") + writer.write("__vid, __len = reader.read_fmt('= 0") generic = NormalParameter(ty=param.ty.generic_arg, flag=None) if is_trivial(generic): @@ -91,7 +91,7 @@ def generate_normal_param_read( if flag_check: writer.dedent() - writer.write(f"else:") + writer.write("else:") writer.write(f" _{name} = None") diff --git a/tools/check.py b/tools/check.py index 4fce513b..3fdf3174 100644 --- a/tools/check.py +++ b/tools/check.py @@ -18,6 +18,7 @@ def main() -> None: run("isort", ".", "-c", "--profile", "black", "--gitignore") or run("black", ".", "--check", "--extend-exclude", BLACK_IGNORE) or run("mypy", "--strict", ".") + or run("ruff", "check", ".") or run("sphinx", "-M", "dummy", "client/doc", tmp_dir, "-n", "-W") or run("pytest", ".", "-m", "not net") )