Skip to content

Commit 537e1fb

Browse files
refactor: add and improve type annotations across utils and database
1 parent d29a007 commit 537e1fb

4 files changed

Lines changed: 50 additions & 23 deletions

File tree

eduu/database/localization.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# SPDX-License-Identifier: MIT
22
# Copyright (c) 2018-2026 Amano LLC
33

4+
from __future__ import annotations
5+
46
from hydrogram.enums import ChatType
57

68
from eduu.utils.consts import GROUP_TYPES
@@ -10,7 +12,7 @@
1012
conn = database.get_conn()
1113

1214

13-
async def set_db_lang(chat_id: int, chat_type: ChatType, lang_code: str):
15+
async def set_db_lang(chat_id: int, chat_type: ChatType, lang_code: str) -> None:
1416
if chat_type in {ChatType.PRIVATE, ChatType.BOT}:
1517
await conn.execute(
1618
"UPDATE users SET chat_lang = ? WHERE user_id = ?", (lang_code, chat_id)
@@ -30,7 +32,7 @@ async def set_db_lang(chat_id: int, chat_type: ChatType, lang_code: str):
3032
raise TypeError(f"Unknown chat type '{chat_type}'.")
3133

3234

33-
async def get_db_lang(chat_id: int, chat_type: ChatType) -> str:
35+
async def get_db_lang(chat_id: int, chat_type: ChatType) -> str | None:
3436
if chat_type == ChatType.PRIVATE:
3537
cursor = await conn.execute("SELECT chat_lang FROM users WHERE user_id = ?", (chat_id,))
3638
ul = await cursor.fetchone()

eduu/utils/decorators.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
from eduu.utils.utils import check_perms
1919

2020
if TYPE_CHECKING:
21-
from collections.abc import Callable
21+
from collections.abc import Callable, Coroutine
2222

2323

24-
def aiowrap(func: Callable) -> Callable:
24+
def aiowrap[T, **P](func: Callable[P, T]) -> Callable[..., Coroutine[None, None, T]]:
2525
@wraps(func)
26-
async def run(*args, loop=None, executor=None, **kwargs):
26+
async def run(*args: P.args, loop=None, executor=None, **kwargs: P.kwargs) -> T:
2727
if loop is None:
2828
loop = asyncio.get_event_loop()
2929
pfunc = partial(func, *args, **kwargs)
@@ -92,10 +92,12 @@ async def wrapper(client: Client, message: CallbackQuery | Message, *args, **kwa
9292
return decorator
9393

9494

95-
def stop_here(func: Callable) -> Callable:
96-
async def wrapper(*args, **kwargs):
95+
def stop_here[T, **P](
96+
func: Callable[P, Coroutine[None, None, T]],
97+
) -> Callable[P, Coroutine[None, None, T]]:
98+
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
9799
try:
98-
await func(*args, **kwargs)
100+
return await func(*args, **kwargs)
99101
finally:
100102
raise StopPropagation
101103

eduu/utils/localization.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@
88
from collections.abc import Callable
99
from functools import partial
1010
from pathlib import Path
11+
from typing import TYPE_CHECKING
1112

1213
from hydrogram.enums import ChatType
1314
from hydrogram.types import CallbackQuery, InlineQuery, Message
1415

1516
from eduu.database.localization import get_db_lang
1617

18+
if TYPE_CHECKING:
19+
from collections.abc import Coroutine
20+
21+
from hydrogram import Client
22+
1723
enabled_locales: list[str] = [
1824
"en-GB", # English (United Kingdom)
1925
"en-US", # English (United States)
@@ -66,7 +72,8 @@ def cache_locales(locales: list[str]) -> dict[str, dict[str, str]]:
6672

6773
if "_meta_language_name" not in locale_keys or "_meta_language_flag" not in locale_keys:
6874
logging.warning(
69-
"Locale has required keys _meta_language_name or _meta_language_flag missing. This locale will not be loaded."
75+
"Locale has required keys _meta_language_name or _meta_language_flag missing."
76+
" This locale will not be loaded."
7077
)
7178
continue
7279

@@ -127,10 +134,17 @@ async def get_lang(message: CallbackQuery | Message | InlineQuery) -> str:
127134
return lang if lang in enabled_locales else default_language
128135

129136

130-
def use_chat_lang(func: Callable):
137+
def use_chat_lang[T](
138+
func: Callable[..., Coroutine[None, None, T]],
139+
) -> Callable[..., Coroutine[None, None, T]]:
131140
"""Decorator to get the chat language and pass it to the function."""
132141

133-
async def wrapper(client, message, *args, **kwargs):
142+
async def wrapper(
143+
client: Client,
144+
message: CallbackQuery | Message | InlineQuery,
145+
*args,
146+
**kwargs,
147+
) -> T:
134148
lang = await get_lang(message)
135149

136150
lfunc = partial(get_locale_string, lang)

eduu/utils/utils.py

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from datetime import datetime, timedelta
1111
from functools import partial
1212
from string import Formatter
13+
from typing import TYPE_CHECKING
1314

1415
from curl_cffi.requests import AsyncSession
1516
from hydrogram import Client, filters
@@ -24,6 +25,12 @@
2425

2526
from config import SUDOERS
2627

28+
if TYPE_CHECKING:
29+
from collections.abc import Callable, Coroutine
30+
from typing import Any
31+
32+
from eduu.utils.localization import Strings
33+
2734
BTN_URL_REGEX = re.compile(r"(\[([^\[]+?)\]\(buttonurl:(?:/{0,2})(.+?)(:same)?\))")
2835

2936
SMART_OPEN = "“"
@@ -34,12 +41,14 @@
3441
http = AsyncSession(timeout=40)
3542

3643

37-
def run_async(func, *args, **kwargs):
44+
def run_async[T, **P](
45+
func: Callable[P, Coroutine[Any, Any, T]], *args: P.args, **kwargs: P.kwargs
46+
) -> T:
3847
loop = asyncio.get_event_loop()
39-
loop.run_until_complete(func(*args, **kwargs))
48+
return loop.run_until_complete(func(*args, **kwargs))
4049

4150

42-
def pretty_size(size_bytes):
51+
def pretty_size(size_bytes: int) -> str:
4352
if size_bytes == 0:
4453
return "0B"
4554
size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
@@ -53,7 +62,7 @@ async def check_perms(
5362
message: CallbackQuery | Message,
5463
permissions: ChatPrivileges | None = None,
5564
complain_missing_perms: bool = True,
56-
s=None,
65+
s: Strings | None = None,
5766
) -> bool:
5867
if isinstance(message, CallbackQuery):
5968
sender = partial(message.answer, show_alert=True)
@@ -125,7 +134,7 @@ def remove_escapes(text: str) -> str:
125134
return res
126135

127136

128-
def split_quotes(text: str) -> list:
137+
def split_quotes(text: str) -> list[str]:
129138
if not any(text.startswith(char) for char in START_CHAR):
130139
return text.split(None, 1)
131140
counter = 1 # ignore first char -> is some kind of quote
@@ -198,8 +207,8 @@ def add_command(
198207
self,
199208
command: str,
200209
category: str,
201-
aliases: list | None = None,
202-
):
210+
aliases: list[str] | None = None,
211+
) -> None:
203212
description_key = f"cmd_{command}_description"
204213

205214
if self.commands.get(category) is None:
@@ -210,7 +219,7 @@ def add_command(
210219
"aliases": aliases or [],
211220
})
212221

213-
def get_commands_message(self, s, category: str | None = None):
222+
def get_commands_message(self, s: Strings, category: str | None = None) -> str:
214223
# TODO: Add pagination support.
215224
if category is None:
216225
cmds_list = []
@@ -238,8 +247,8 @@ def __init__(self):
238247
def add_command(
239248
self,
240249
command: str,
241-
aliases: list | None = None,
242-
):
250+
aliases: list[str] | None = None,
251+
) -> None:
243252
description_key = f"inline_cmd_{command.split(maxsplit=1)[0]}_description"
244253

245254
self.commands.append({
@@ -248,7 +257,7 @@ def add_command(
248257
"aliases": aliases or [],
249258
})
250259

251-
def search_commands(self, query: str | None = None):
260+
def search_commands(self, query: str | None = None) -> list[dict[str, str | list[str]]]:
252261
return [
253262
cmd
254263
for cmd in sorted(self.commands, key=operator.itemgetter("command"))
@@ -277,7 +286,7 @@ async def get_target_user(c: Client, m: Message) -> User:
277286
)
278287

279288

280-
def get_reason_text(c: Client, m: Message) -> Message:
289+
def get_reason_text(c: Client, m: Message) -> str | None:
281290
reply = m.reply_to_message
282291
spilt_text = m.text.split
283292

0 commit comments

Comments
 (0)