Enable and use ruff

This commit is contained in:
Lonami Exo 2023-10-12 18:17:41 +02:00
parent 7fabf7da0a
commit 034bf304bb
29 changed files with 75 additions and 79 deletions

View File

@ -31,6 +31,7 @@ dev = [
"isort~=5.12", "isort~=5.12",
"black~=23.3.0", "black~=23.3.0",
"mypy~=1.3", "mypy~=1.3",
"ruff~=0.0.292",
"pytest~=7.3", "pytest~=7.3",
"pytest-asyncio~=0.21", "pytest-asyncio~=0.21",
] ]
@ -51,3 +52,8 @@ build-backend = "setuptools.build_meta"
[tool.setuptools.dynamic] [tool.setuptools.dynamic]
version = {attr = "telethon.version.__version__"} version = {attr = "telethon.version.__version__"}
[tool.ruff]
ignore = [
"E501", # formatter takes care of lines that are too long besides documentation
]

View File

@ -5,6 +5,5 @@ from ._impl import tl as _tl
from ._impl.client import Client from ._impl.client import Client
from ._impl.client.errors import errors from ._impl.client.errors import errors
from ._impl.mtproto import RpcError from ._impl.mtproto import RpcError
from .version import __version__
__all__ = ["_tl", "Client", "errors", "RpcError"] __all__ = ["_tl", "Client", "errors", "RpcError"]

View File

@ -1,10 +1,8 @@
from .bots import InlineResult, InlineResults
from .client import Client from .client import Client
from .net import Config from .net import Config
__all__ = [ __all__ = [
"InlineResult", "InlineResult",
"InlineResults",
"Client", "Client",
"Config", "Config",
] ]

View File

@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, AsyncIterator, List, Optional, Self
from ...tl import abcs, functions, types from ...tl import abcs, functions, types
from ..types import ChatLike, InlineResult, NoPublicConstructor from ..types import ChatLike, InlineResult, NoPublicConstructor
from ..utils import generate_random_id
if TYPE_CHECKING: if TYPE_CHECKING:
from .client import Client from .client import Client

View File

@ -42,6 +42,7 @@ from ..types import (
Draft, Draft,
File, File,
InFileLike, InFileLike,
InlineResult,
LoginToken, LoginToken,
Message, Message,
OutFileLike, OutFileLike,
@ -59,7 +60,7 @@ from .auth import (
sign_in, sign_in,
sign_out, sign_out,
) )
from .bots import InlineResult, inline_query from .bots import inline_query
from .chats import ( from .chats import (
get_admin_log, get_admin_log,
get_participants, get_participants,
@ -92,7 +93,6 @@ from .messages import (
unpin_message, unpin_message,
) )
from .net import ( from .net import (
DEFAULT_DC,
Config, Config,
connect, connect,
connected, connected,

View File

@ -1,7 +1,6 @@
from __future__ import annotations from __future__ import annotations
import hashlib import hashlib
import math
import mimetypes import mimetypes
import urllib.parse import urllib.parse
from inspect import isawaitable from inspect import isawaitable

View File

@ -2,7 +2,7 @@ from __future__ import annotations
import datetime import datetime
import sys 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 ...session import PackedChat
from ...tl import abcs, functions, types from ...tl import abcs, functions, types

View File

@ -12,7 +12,7 @@ from ...mtproto import Full, RpcError
from ...mtsender import Sender from ...mtsender import Sender
from ...mtsender import connect as connect_without_auth from ...mtsender import connect as connect_without_auth
from ...mtsender import connect_with_auth from ...mtsender import connect_with_auth
from ...session import DataCenter, Session from ...session import DataCenter
from ...session import User as SessionUser from ...session import User as SessionUser
from ...tl import LAYER, Request, functions, types from ...tl import LAYER, Request, functions, types
from ..errors import adapt_rpc from ..errors import adapt_rpc
@ -154,7 +154,7 @@ async def connect(self: Client) -> None:
except RpcError as e: except RpcError as e:
if e.code == 401: if e.code == 401:
self._session.user = None self._session.user = None
except Exception as e: except Exception:
pass pass
else: else:
if not self._session.user: if not self._session.user:

View File

@ -130,7 +130,7 @@ async def dispatcher(client: Client) -> None:
except asyncio.CancelledError: except asyncio.CancelledError:
return return
except Exception as e: 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. # User probably forgot to call disconnect.
logging.warning( logging.warning(
"client was not closed cleanly, make sure to call client.disconnect()! %s", "client was not closed cleanly, make sure to call client.disconnect()! %s",

View File

@ -50,7 +50,7 @@ def resolved_peer_to_chat(resolved: abcs.contacts.ResolvedPeer) -> Chat:
if chat := map.get(peer_id(resolved.peer)): if chat := map.get(peer_id(resolved.peer)):
return chat return chat
else: 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: async def resolve_phone(client: Client, phone: str) -> Chat:

View File

@ -3,12 +3,12 @@ from .chat import Channel, Chat, ChatLike, Group, RestrictionReason, User
from .dialog import Dialog from .dialog import Dialog
from .draft import Draft from .draft import Draft
from .file import File, InFileLike, OutFileLike, OutWrapper from .file import File, InFileLike, OutFileLike, OutWrapper
from .inline_result import InlineResult
from .login_token import LoginToken from .login_token import LoginToken
from .message import Message from .message import Message
from .meta import NoPublicConstructor from .meta import NoPublicConstructor
from .participant import Participant from .participant import Participant
from .password_token import PasswordToken from .password_token import PasswordToken
from .inline_result import InlineResult
from .recent_action import RecentAction from .recent_action import RecentAction
__all__ = [ __all__ = [

View File

@ -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
from ...tl import abcs, types
from .chat import Chat from .chat import Chat
from .meta import NoPublicConstructor from .meta import NoPublicConstructor

View File

@ -1,7 +1,6 @@
from typing import Dict, List, Optional, Self from typing import Dict, Self
from ...session import PackedChat, PackedType from ...tl import types
from ...tl import abcs, types
from .chat import Chat from .chat import Chat
from .meta import NoPublicConstructor from .meta import NoPublicConstructor

View File

@ -1,10 +1,8 @@
from __future__ import annotations from __future__ import annotations
import mimetypes import mimetypes
import os
from inspect import isawaitable from inspect import isawaitable
from io import BufferedReader, BufferedWriter from io import BufferedWriter
from mimetypes import guess_type
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Coroutine, List, Optional, Protocol, Self, Union from typing import TYPE_CHECKING, Any, Coroutine, List, Optional, Protocol, Self, Union

View File

@ -2,11 +2,11 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union from typing import TYPE_CHECKING, Optional, Union
from ...tl import abcs, functions, types
from ..utils import generate_random_id from ..utils import generate_random_id
from ...tl import abcs, types, functions
from .chat import ChatLike from .chat import ChatLike
from .meta import NoPublicConstructor
from .message import Message from .message import Message
from .meta import NoPublicConstructor
if TYPE_CHECKING: if TYPE_CHECKING:
from ..client import Client from ..client import Client

View File

@ -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 ...tl import abcs, types
from .chat import Chat from .chat import Chat
from .meta import NoPublicConstructor from .meta import NoPublicConstructor

View File

@ -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 ...tl import abcs, types
from .chat import Chat from .chat import Chat
from .meta import NoPublicConstructor from .meta import NoPublicConstructor

View File

@ -2,17 +2,7 @@ import itertools
import sys import sys
import time import time
from collections import defaultdict from collections import defaultdict
from typing import ( from typing import DefaultDict, Dict, List, Optional, Union
Any,
Callable,
DefaultDict,
Dict,
Iterator,
List,
Optional,
Union,
cast,
)
from ..tl import abcs, types from ..tl import abcs, types
from .types import Channel, Chat, Group, User from .types import Channel, Chat, Group, User

View File

@ -56,11 +56,17 @@ def ige_decrypt(ciphertext: bytes, key: bytes, iv: bytes) -> bytes:
try: try:
import cryptg import cryptg
ige_encrypt = lambda t, k, i: cryptg.encrypt_ige( def ige_encrypt(plaintext: bytes, key: bytes, iv: bytes) -> bytes: # noqa: F811
bytes(t) if not isinstance(t, bytes) else t, k, i return cryptg.encrypt_ige(
bytes(plaintext) if not isinstance(plaintext, bytes) else plaintext, key, iv
) )
ige_decrypt = lambda t, k, i: cryptg.decrypt_ige(
bytes(t) if not isinstance(t, bytes) else t, k, i 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: except ImportError:
pass pass

View File

@ -1,5 +1,4 @@
import base64 from typing import List, Optional
from typing import Any, Dict, List, Optional, Self
class DataCenter: class DataCenter:

View File

@ -6,10 +6,11 @@ from .storage import Storage
try: try:
from .sqlite import SqliteSession from .sqlite import SqliteSession
except ImportError as e: except ImportError as e:
import_err = e
class SqliteSession(Storage): # type: ignore [no-redef] class SqliteSession(Storage): # type: ignore [no-redef]
def __init__(self, *args: Any, **kwargs: Any) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None:
raise e from None raise import_err from None
__all__ = ["MemorySession", "Storage", "SqliteSession"] __all__ = ["MemorySession", "Storage", "SqliteSession"]

View File

@ -1 +1 @@
from ..core import * from ..core import * # noqa: F403

View File

@ -1,7 +1,7 @@
""" """
Classes for the various objects the library returns. 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 ( from ._impl.client.types import (
AsyncList, AsyncList,
Channel, Channel,
@ -11,6 +11,7 @@ from ._impl.client.types import (
File, File,
Group, Group,
InFileLike, InFileLike,
InlineResult,
LoginToken, LoginToken,
Message, Message,
OutFileLike, OutFileLike,

View File

@ -4,7 +4,6 @@ import logging
from pytest import LogCaptureFixture, mark from pytest import LogCaptureFixture, mark
from telethon._impl.mtproto import Full from telethon._impl.mtproto import Full
from telethon._impl.mtsender import connect from telethon._impl.mtsender import connect
from telethon._impl.session import DataCenter
from telethon._impl.tl import LAYER, abcs, functions, types from telethon._impl.tl import LAYER, abcs, functions, types
TELEGRAM_TEST_DC = 2, "149.154.167.40:443" TELEGRAM_TEST_DC = 2, "149.154.167.40:443"

View File

@ -36,3 +36,8 @@ build-backend = "setuptools.build_meta"
[tool.setuptools.dynamic] [tool.setuptools.dynamic]
version = {attr = "telethon_generator.__version__"} version = {attr = "telethon_generator.__version__"}
[tool.ruff]
ignore = [
"E501", # formatter takes care of lines that are too long besides documentation
]

View File

@ -1,4 +1,3 @@
from . import codegen, tl_parser from . import codegen, tl_parser
from .version import __version__
__all__ = ["codegen", "tl_parser"] __all__ = ["codegen", "tl_parser"]

View File

@ -94,10 +94,10 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None:
writer = fs.open(type_path) writer = fs.open(type_path)
if type_path not in fs: if type_path not in fs:
writer.write(f"import struct") writer.write("import struct")
writer.write(f"from typing import List, Optional, Self") writer.write("from typing import List, Optional, Self")
writer.write(f"from .. import abcs") writer.write("from .. import abcs")
writer.write(f"from ..core import Reader, Serializable, serialize_bytes_to") writer.write("from ..core import Reader, Serializable, serialize_bytes_to")
ns = f"{typedef.namespace[0]}." if typedef.namespace else "" ns = f"{typedef.namespace[0]}." if typedef.namespace else ""
generated_type_names.add(f"{ns}{to_class_name(typedef.name)}") 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})") writer.write(f" __slots__ = ({slots})")
# def constructor_id() # def constructor_id()
writer.write(f" @classmethod") writer.write(" @classmethod")
writer.write(f" def constructor_id(_) -> int:") writer.write(" def constructor_id(_) -> int:")
writer.write(f" return {hex(typedef.id)}") writer.write(f" return {hex(typedef.id)}")
# def __init__() # def __init__()
@ -126,8 +126,8 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None:
writer.write(f" _s.{p.name} = {p.name}") writer.write(f" _s.{p.name} = {p.name}")
# def _read_from() # def _read_from()
writer.write(f" @classmethod") writer.write(" @classmethod")
writer.write(f" def _read_from(cls, reader: Reader) -> Self:") writer.write(" def _read_from(cls, reader: Reader) -> Self:")
writer.indent(2) writer.indent(2)
generate_read(writer, typedef) generate_read(writer, typedef)
params = ", ".join(f"{p.name}={param_value_fmt(p)}" for p in property_params) 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) writer.dedent(2)
# def _write_to() # 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: if typedef.params:
writer.indent(2) writer.indent(2)
generate_write(writer, typedef) generate_write(writer, typedef)
writer.dedent(2) writer.dedent(2)
else: else:
writer.write(f" pass") writer.write(" pass")
for functiondef in tl.functiondefs: for functiondef in tl.functiondefs:
if len(functiondef.namespace) >= 2: if len(functiondef.namespace) >= 2:
@ -158,10 +158,10 @@ def generate(fs: FakeFs, tl: ParsedTl) -> None:
writer = fs.open(function_path) writer = fs.open(function_path)
if function_path not in fs: if function_path not in fs:
writer.write(f"import struct") writer.write("import struct")
writer.write(f"from typing import List, Optional, Self") writer.write("from typing import List, Optional, Self")
writer.write(f"from .. import abcs") writer.write("from .. import abcs")
writer.write(f"from ..core import Request, serialize_bytes_to") writer.write("from ..core import Request, serialize_bytes_to")
# def name(params, ...) # def name(params, ...)
required_params = [p for p in functiondef.params if not is_computed(p.ty)] 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 = fs.open(Path("layer.py"))
writer.write(f"from . import abcs, types") writer.write("from . import abcs, types")
writer.write( 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(f"LAYER = {tl.layer!r}")
writer.write( writer.write(
"TYPE_MAPPING = {t.constructor_id(): t for t in cast(Tuple[Type[Serializable]], (" "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)}," f" {hex(functiondef.id)}: {function_deserializer_fmt(functiondef)},"
) )
writer.write("}") writer.write("}")
writer.write(f"__all__ = ['LAYER', 'TYPE_MAPPING', 'RESPONSE_MAPPING']") writer.write("__all__ = ['LAYER', 'TYPE_MAPPING', 'RESPONSE_MAPPING']")

View File

@ -20,13 +20,13 @@ def reader_read_fmt(ty: Type, constructor_id: int) -> Tuple[str, Optional[str]]:
size = struct.calcsize(f"<{fmt}") size = struct.calcsize(f"<{fmt}")
return f"reader.read_fmt(f'<{fmt}', {size})[0]", None return f"reader.read_fmt(f'<{fmt}', {size})[0]", None
elif ty.name == "string": 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": elif ty.name == "bytes":
return f"b'' + reader.read_bytes()", None return "b'' + reader.read_bytes()", None
elif ty.name == "int128": 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": elif ty.name == "int256":
return f"int.from_bytes(reader.read(32))", None return "int.from_bytes(reader.read(32))", None
elif ty.bare: elif ty.bare:
return f"{to_class_name(ty.name)}._read_from(reader)", None return f"{to_class_name(ty.name)}._read_from(reader)", None
elif ty.name == "Object": elif ty.name == "Object":
@ -60,11 +60,11 @@ def generate_normal_param_read(
) )
if param.ty.bare: if param.ty.bare:
writer.write(f"__len = reader.read_fmt('<i', 4)[0]") writer.write("__len = reader.read_fmt('<i', 4)[0]")
writer.write(f"assert __len >= 0") writer.write("assert __len >= 0")
else: else:
writer.write(f"__vid, __len = reader.read_fmt('<ii', 8)") writer.write("__vid, __len = reader.read_fmt('<ii', 8)")
writer.write(f"assert __vid == 0x1cb5c415 and __len >= 0") writer.write("assert __vid == 0x1cb5c415 and __len >= 0")
generic = NormalParameter(ty=param.ty.generic_arg, flag=None) generic = NormalParameter(ty=param.ty.generic_arg, flag=None)
if is_trivial(generic): if is_trivial(generic):
@ -91,7 +91,7 @@ def generate_normal_param_read(
if flag_check: if flag_check:
writer.dedent() writer.dedent()
writer.write(f"else:") writer.write("else:")
writer.write(f" _{name} = None") writer.write(f" _{name} = None")

View File

@ -18,6 +18,7 @@ def main() -> None:
run("isort", ".", "-c", "--profile", "black", "--gitignore") run("isort", ".", "-c", "--profile", "black", "--gitignore")
or run("black", ".", "--check", "--extend-exclude", BLACK_IGNORE) or run("black", ".", "--check", "--extend-exclude", BLACK_IGNORE)
or run("mypy", "--strict", ".") or run("mypy", "--strict", ".")
or run("ruff", "check", ".")
or run("sphinx", "-M", "dummy", "client/doc", tmp_dir, "-n", "-W") or run("sphinx", "-M", "dummy", "client/doc", tmp_dir, "-n", "-W")
or run("pytest", ".", "-m", "not net") or run("pytest", ".", "-m", "not net")
) )