From 29a90fc3856c3582a5b876e784c1ab4e5df90476 Mon Sep 17 00:00:00 2001 From: profitroll Date: Sun, 5 Jan 2025 22:46:40 +0100 Subject: [PATCH] WIP: Convert docstrings to Google's format --- src/libbot/errors/config.py | 10 +-- src/libbot/i18n/_functions.py | 94 +++++++++++++-------------- src/libbot/i18n/classes/bot_locale.py | 43 ++++++------ src/libbot/pycord/classes/bot.py | 40 ++++++++++-- src/libbot/pycord/utils/color.py | 20 +++--- src/libbot/pyrogram/classes/client.py | 88 +++++++++++++++---------- 6 files changed, 173 insertions(+), 122 deletions(-) diff --git a/src/libbot/errors/config.py b/src/libbot/errors/config.py index ef544f2..b512086 100644 --- a/src/libbot/errors/config.py +++ b/src/libbot/errors/config.py @@ -4,8 +4,8 @@ from typing import Any, List, Optional class ConfigKeyError(Exception): """Raised when config key is not found. - ### Attributes: - * key (`str | List[str]`): Missing config key. + Args: + key (str | List[str]): Missing config key """ def __init__(self, key: str | List[str]) -> None: @@ -21,9 +21,9 @@ class ConfigKeyError(Exception): class ConfigValueError(Exception): """Raised when config key's value is invalid. - ### Attributes: - * key (`str | List[str]`): Invalid config key. - * value (`Optional[Any]`): Key's correct value. + Args: + key (str | List[str]): Invalid config key + value (Optional[Any]): Key's correct value """ def __init__(self, key: str | List[str], value: Optional[Any] = None) -> None: diff --git a/src/libbot/i18n/_functions.py b/src/libbot/i18n/_functions.py index 05944ed..f122db7 100644 --- a/src/libbot/i18n/_functions.py +++ b/src/libbot/i18n/_functions.py @@ -18,16 +18,16 @@ def _( locale: str | None = "en", locales_root: str | Path = Path("locale"), ) -> Any: - """Get value of locale string + """Get value of the locale string. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. - * locale (`str | None`): Locale to looked up in. Defaults to `"en"`. - * locales_root (`str | Path`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` + locale (str | None): Locale to be looked up in. Defaults to `"en"` + locales_root (str | Path, optional):Folder where locales are located. Defaults to `Path("locale")` - ### Returns: - * `Any`: Value of provided locale key. Is usually `str`, `Dict[str, Any]` or `List[Any]` + Returns: + Any: Value of provided locale key. Is usually `str`, `Dict[str, Any]` or `List[Any]` """ if locale is None: locale: str = config_get("locale") @@ -58,16 +58,16 @@ async def _( locale: str | None = "en", locales_root: str | Path = Path("locale"), ) -> Any: - """Get value of locale string + """Get value of the locale string. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. - * locale (`str | None`): Locale to looked up in. Defaults to `"en"`. - * locales_root (`str | Path`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` + locale (str | None): Locale to be looked up in. Defaults to `"en"` + locales_root (str | Path, optional):Folder where locales are located. Defaults to `Path("locale")` - ### Returns: - * `Any`: Value of provided locale key. Is usually `str`, `Dict[str, Any]` or `List[Any]` + Returns: + Any: Value of provided locale key. Is usually `str`, `Dict[str, Any]` or `List[Any]` """ locale: str = config_get("locale") if locale is None else locale @@ -94,17 +94,16 @@ async def _( @asyncable def in_all_locales(key: str, *args: str, locales_root: str | Path = Path("locale")) -> List[Any]: - """Get value of the provided key and path in all available locales + """Get value of the provided key and path in all available locales. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. - * locales_root (`str | Path`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` + locales_root (str | Path, optional): Folder where locales are located. Defaults to `Path("locale")` - ### Returns: - * `List[Any]`: List of values in all locales + Returns: + List[Any]: List of values in all locales """ - output: List[Any] = [] for locale in _get_valid_locales(locales_root): @@ -128,15 +127,15 @@ def in_all_locales(key: str, *args: str, locales_root: str | Path = Path("locale @in_all_locales.asynchronous async def in_all_locales(key: str, *args: str, locales_root: str | Path = Path("locale")) -> List[Any]: - """Get value of the provided key and path in all available locales + """Get value of the provided key and path in all available locales. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. - * locales_root (`str | Path`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` + locales_root (str | Path, optional): Folder where locales are located. Defaults to `Path("locale")` - ### Returns: - * `List[Any]`: List of values in all locales + Returns: + List[Any]: List of values in all locales """ output: List[Any] = [] @@ -161,20 +160,17 @@ async def in_all_locales(key: str, *args: str, locales_root: str | Path = Path(" @asyncable -def in_every_locale( - key: str, *args: str, locales_root: str | Path = Path("locale") -) -> Dict[str, Any]: - """Get value of the provided key and path in every available locale with locale tag +def in_every_locale(key: str, *args: str, locales_root: str | Path = Path("locale")) -> Dict[str, Any]: + """Get value of the provided key and path in every available locale with locale tag. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. - * locales_root (`str | Path`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` + locales_root (str | Path, optional): Folder where locales are located. Defaults to `Path("locale")` - ### Returns: - * `Dict[str, Any]`: Locale is a key, and it's value from locale file is a value + Returns: + Dict[str, Any]: Locale is a key, and it's value from locale file is a value """ - output: Dict[str, Any] = {} for locale in _get_valid_locales(locales_root): @@ -200,15 +196,15 @@ def in_every_locale( async def in_every_locale( key: str, *args: str, locales_root: str | Path = Path("locale") ) -> Dict[str, Any]: - """Get value of the provided key and path in every available locale with locale tag + """Get value of the provided key and path in every available locale with locale tag. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. - * locales_root (`str | Path`, *optional*): Folder where locales are located. Defaults to `Path("locale")`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` + locales_root (str | Path, optional): Folder where locales are located. Defaults to `Path("locale")` - ### Returns: - * `Dict[str, Any]`: Locale is a key, and it's value from locale file is a value + Returns: + Dict[str, Any]: Locale is a key, and it's value from locale file is a value """ output: Dict[str, Any] = {} diff --git a/src/libbot/i18n/classes/bot_locale.py b/src/libbot/i18n/classes/bot_locale.py index c1970dc..25e296b 100644 --- a/src/libbot/i18n/classes/bot_locale.py +++ b/src/libbot/i18n/classes/bot_locale.py @@ -14,6 +14,11 @@ class BotLocale: default_locale: str | None = "en", locales_root: str | Path = Path("locale"), ) -> None: + """ + Args: + default_locale (str | None): Default bot's locale. Defaults to `"en"` + locales_root (str | Path): Folder where locales are located. Defaults to `Path("locale")` + """ if isinstance(locales_root, str): locales_root = Path(locales_root) elif not isinstance(locales_root, Path): @@ -30,15 +35,15 @@ class BotLocale: self.locales[locale] = json_read(Path(f"{locales_root}/{locale}.json")) def _(self, key: str, *args: str, locale: str | None = None) -> Any: - """Get value of locale string + """Get value of locale string. - ### Args: - * key (`str`): The last key of the locale's keys path - * *args (`str`): Path to key like: `dict[args][key]` - * locale (`str | None`, *optional*): Locale to looked up in. Defaults to config's `"locale"` value + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` + locale (str | None, optional): Locale to be looked up in. Defaults to config's `"locale"` value - ### Returns: - * `Any`: Value of provided locale key. Is usually `str`, `Dict[str, Any]` or `List[Any]` + Returns: + Any: Value of provided locale key. Is usually `str`, `Dict[str, Any]` or `List[Any]` """ if locale is None: locale: str = self.default @@ -64,14 +69,14 @@ class BotLocale: return f'⚠️ Locale in config is invalid: could not get "{key}" in {args} from locale "{locale}"' def in_all_locales(self, key: str, *args: str) -> List[Any]: - """Get value of the provided key and path in all available locales + """Get value of the provided key and path in all available locales. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` - ### Returns: - * `List[Any]`: List of values in all locales + Returns: + List[Any]: List of values in all locales """ output: List[Any] = [] @@ -94,14 +99,14 @@ class BotLocale: return output def in_every_locale(self, key: str, *args: str) -> Dict[str, Any]: - """Get value of the provided key and path in every available locale with locale tag + """Get value of the provided key and path in every available locale with locale tag. - ### Args: - * key (`str`): The last key of the locale's keys path. - * *args (`str`): Path to key like: `dict[args][key]`. + Args: + key (str): The last key of the locale's keys path + *args (str): Path to key like: `dict[args][key]` - ### Returns: - * `Dict[str, Any]`: Locale is a key, and it's value from locale file is a value + Returns: + Dict[str, Any]: Locale is a key, and it's value from locale file is a value """ output: Dict[str, Any] = {} diff --git a/src/libbot/pycord/classes/bot.py b/src/libbot/pycord/classes/bot.py index 6390813..66cbbef 100644 --- a/src/libbot/pycord/classes/bot.py +++ b/src/libbot/pycord/classes/bot.py @@ -19,16 +19,27 @@ logger: Logger = logging.getLogger(__name__) class PycordBot(Bot): + # TODO Write a docstring @override def __init__( - self, - *args, - config: Dict[str, Any] | None = None, - config_path: str | Path = Path("config.json"), - locales_root: str | Path | None = None, - scheduler: AsyncIOScheduler | BackgroundScheduler | None = None, - **kwargs, + self, + *args, + config: Dict[str, Any] | None = None, + config_path: str | Path = Path("config.json"), + locales_root: str | Path | None = None, + scheduler: AsyncIOScheduler | BackgroundScheduler | None = None, + **kwargs, ): + """ + + Args: + *args: + config: + config_path: + locales_root: + scheduler: + **kwargs: + """ self.config: Dict[str, Any] = config if config is not None else json_read(config_path) super().__init__( @@ -51,15 +62,30 @@ class PycordBot(Bot): self.scheduler: AsyncIOScheduler | BackgroundScheduler | None = scheduler + # TODO Write a docstring @override async def start(self, token: str, reconnect: bool = True, scheduler_start: bool = True) -> None: + """ + + Args: + token: + reconnect: + scheduler_start: + """ if self.scheduler is not None and scheduler_start: self.scheduler.start() await super().start(token, reconnect=reconnect) + # TODO Write a docstring @override async def close(self, scheduler_shutdown: bool = True, scheduler_wait: bool = True) -> None: + """ + + Args: + scheduler_shutdown: + scheduler_wait: + """ if self.scheduler is not None and scheduler_shutdown: self.scheduler.shutdown(scheduler_wait) diff --git a/src/libbot/pycord/utils/color.py b/src/libbot/pycord/utils/color.py index 9b61282..93c4e3a 100644 --- a/src/libbot/pycord/utils/color.py +++ b/src/libbot/pycord/utils/color.py @@ -16,20 +16,24 @@ def _hex_from_int(color_int: int) -> str: def color_from_hex(hex_string: str) -> Colour: - """Convert valid hexadecimal string to discord.Colour. + """Convert valid hexadecimal string to :class:`discord.Colour`. - :param hex_string: Hexadecimal string to convert into Colour object - :type hex_string: str - :return: Colour object + Args: + hex_string (str): Hexadecimal string to convert into :class:`discord.Colour` object + + Returns: + Colour: :class:`discord.Colour` object """ return Colour(_int_from_hex(hex_string)) def hex_from_color(color: Colour) -> str: - """Convert discord.Colour to hexadecimal string. + """Convert :class:`discord.Colour` to hexadecimal string. - :param color: Colour object to convert into the string - :type color: Colour - :return: Hexadecimal string in #XXXXXX format + Args: + color (Colour): :class:`discord.Colour` object to convert into the string + + Returns: + str: Hexadecimal string in #XXXXXX format """ return _hex_from_int(color.value) diff --git a/src/libbot/pyrogram/classes/client.py b/src/libbot/pyrogram/classes/client.py index 2b01db7..9189cee 100644 --- a/src/libbot/pyrogram/classes/client.py +++ b/src/libbot/pyrogram/classes/client.py @@ -6,7 +6,7 @@ from logging import Logger from os import cpu_count, getpid from pathlib import Path from time import time -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from typing_extensions import override @@ -46,27 +46,28 @@ logger: Logger = logging.getLogger(__name__) class PyroClient(Client): + # TODO Write a docstring @override def __init__( - self, - name: str = "bot_client", - owner: int | None = None, - config: Dict[str, Any] | None = None, - config_path: str | Path = Path("config.json"), - api_id: int | None = None, - api_hash: str | None = None, - bot_token: str | None = None, - workers: int = min(32, cpu_count() + 4), - locales_root: str | Path | None = None, - plugins_root: str = "plugins", - plugins_exclude: List[str] | None = None, - sleep_threshold: int = 120, - max_concurrent_transmissions: int = 1, - commands_source: Dict[str, dict] | None = None, - scoped_commands: bool | None = None, - i18n_bot_info: bool = False, - scheduler: AsyncIOScheduler | BackgroundScheduler | None = None, - **kwargs, + self, + name: str = "bot_client", + owner: int | None = None, + config: Dict[str, Any] | None = None, + config_path: str | Path = Path("config.json"), + api_id: int | None = None, + api_hash: str | None = None, + bot_token: str | None = None, + workers: int = min(32, cpu_count() + 4), + locales_root: str | Path | None = None, + plugins_root: str = "plugins", + plugins_exclude: List[str] | None = None, + sleep_threshold: int = 120, + max_concurrent_transmissions: int = 1, + commands_source: Dict[str, dict] | None = None, + scoped_commands: bool | None = None, + i18n_bot_info: bool = False, + scheduler: AsyncIOScheduler | BackgroundScheduler | None = None, + **kwargs, ): self.config: Dict[str, Any] = config if config is not None else json_read(config_path) @@ -119,6 +120,12 @@ class PyroClient(Client): @override async def start(self, register_commands: bool = True, scheduler_start: bool = True) -> None: + """Start the bot and it's services. + + Args: + register_commands (bool, optional): Register commands on start. Defaults to `True` + scheduler_start (bool, optional): Start the scheduler on start. Defaults to `True` + """ await super().start() self.start_time = time() @@ -209,8 +216,15 @@ class PyroClient(Client): @override async def stop( - self, exit_completely: bool = True, scheduler_shutdown: bool = True, scheduler_wait: bool = True + self, exit_completely: bool = True, scheduler_shutdown: bool = True, scheduler_wait: bool = True ) -> None: + """Stop the bot and it's services. + + Args: + exit_completely (bool, optional): Exit the program. Defaults to `True` + scheduler_shutdown (bool): Shutdown the scheduler. Defaults to `True` + scheduler_wait (bool): Wait for tasks to finish. Defaults to `True` + """ try: await self.send_message( chat_id=( @@ -237,10 +251,10 @@ class PyroClient(Client): raise SystemExit("Bot has been shut down, this is not an application error!") from exc async def collect_commands(self) -> List[CommandSet] | None: - """Gather list of the bot's commands + """Gather list of the bot's commands. - ### Returns: - * `List[CommandSet]`: List of the commands' sets. + Returns: + List[CommandSet]: List of the commands' sets """ command_sets = None @@ -308,7 +322,7 @@ class PyroClient(Client): # in it, if there are any. Then adds them to self.commands for handler in self.dispatcher.groups[0]: if isinstance(handler, MessageHandler) and ( - hasattr(handler.filters, "base") or hasattr(handler.filters, "other") + hasattr(handler.filters, "base") or hasattr(handler.filters, "other") ): for entry in [handler.filters.base, handler.filters.other]: if hasattr(entry, "commands"): @@ -319,13 +333,13 @@ class PyroClient(Client): return command_sets def add_command( - self, - command: str, + self, + command: str, ) -> None: - """Add command to the bot's internal commands list + """Add command to the bot's internal commands list. - ### Args: - * command (`str`) + Args: + command (str): Command's name """ self.commands.append( PyroCommand( @@ -338,9 +352,12 @@ class PyroClient(Client): command, ) - async def register_commands(self, command_sets: List[CommandSet] | None = None) -> None: - """Register commands stored in bot's 'commands' attribute""" + async def register_commands(self, command_sets: Optional[List[CommandSet]] = None) -> None: + """Register commands stored in bot's 'commands' attribute. + Args: + command_sets (List[CommandSet], optional): List of command sets. Commands will be parsed from bot's 'commands' attribute if not provided + """ if command_sets is None: commands = [ BotCommand(command=command.command, description=command.description) @@ -365,9 +382,12 @@ class PyroClient(Client): language_code=command_set.language_code, ) - async def remove_commands(self, command_sets: List[CommandSet] | None = None) -> None: - """Remove commands stored in bot's 'commands' attribute""" + async def remove_commands(self, command_sets: Optional[List[CommandSet]] = None) -> None: + """Remove commands stored in bot's 'commands' attribute. + Args: + command_sets (List[CommandSet], optional): List of command sets. Commands with scope :class:`pyrogram.types.BotCommandScopeDefault` will be removed if not provided + """ if command_sets is None: logger.info("Removing commands with a default scope 'BotCommandScopeDefault'") await self.delete_bot_commands(BotCommandScopeDefault())