From 94bf3b8195da8c16070c5c376a025044b2d75227 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 17:02:56 +0800 Subject: [PATCH] Fix incorrect type annotations and errors (#3250) * Initial plan * Fix type annotation errors in cmd_conf, cmd_init, and version_comparator Co-authored-by: LIghtJUNction <106986785+LIghtJUNction@users.noreply.github.com> * Changes before error encountered Co-authored-by: LIghtJUNction <106986785+LIghtJUNction@users.noreply.github.com> * Fix more type annotation errors: change `= None` to `| None = None` Co-authored-by: LIghtJUNction <106986785+LIghtJUNction@users.noreply.github.com> * Fix final batch of type annotation errors Co-authored-by: LIghtJUNction <106986785+LIghtJUNction@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: LIghtJUNction <106986785+LIghtJUNction@users.noreply.github.com> Co-authored-by: LIghtJUNction --- astrbot/cli/commands/cmd_conf.py | 2 +- astrbot/cli/commands/cmd_init.py | 3 ++- astrbot/cli/utils/plugin.py | 8 +++---- astrbot/cli/utils/version_comparator.py | 9 ++++--- astrbot/core/config/astrbot_config.py | 4 ++-- astrbot/core/db/migration/sqlite_v3.py | 10 ++++---- astrbot/core/persona_mgr.py | 6 ++--- astrbot/core/platform/astr_message_event.py | 4 ++-- astrbot/core/platform/astrbot_message.py | 12 +++++----- astrbot/core/platform/message_session.py | 2 +- astrbot/core/platform/platform_metadata.py | 8 +++---- astrbot/core/platform/register.py | 6 ++--- .../aiocqhttp/aiocqhttp_message_event.py | 2 +- .../core/platform/sources/discord/client.py | 2 +- .../platform/sources/discord/components.py | 22 ++++++++--------- .../discord/discord_platform_adapter.py | 4 +++- .../qqofficial/qqofficial_message_event.py | 22 ++++++++--------- .../sources/wechatpadpro/xml_data_parser.py | 2 +- astrbot/core/platform_message_history_mgr.py | 4 ++-- astrbot/core/provider/provider.py | 24 +++++++++---------- astrbot/core/provider/register.py | 4 ++-- astrbot/core/utils/io.py | 4 ++-- astrbot/core/utils/pip_installer.py | 8 +++---- astrbot/dashboard/routes/config.py | 4 +++- 24 files changed, 92 insertions(+), 84 deletions(-) diff --git a/astrbot/cli/commands/cmd_conf.py b/astrbot/cli/commands/cmd_conf.py index 86f78cbaa..a9bd40f00 100644 --- a/astrbot/cli/commands/cmd_conf.py +++ b/astrbot/cli/commands/cmd_conf.py @@ -178,7 +178,7 @@ def set_config(key: str, value: str): @conf.command(name="get") @click.argument("key", required=False) -def get_config(key: str = None): +def get_config(key: str | None = None): """获取配置项的值,不提供key则显示所有可配置项""" config = _load_config() diff --git a/astrbot/cli/commands/cmd_init.py b/astrbot/cli/commands/cmd_init.py index 993995a66..6c0c34b99 100644 --- a/astrbot/cli/commands/cmd_init.py +++ b/astrbot/cli/commands/cmd_init.py @@ -1,4 +1,5 @@ import asyncio +from pathlib import Path import click from filelock import FileLock, Timeout @@ -6,7 +7,7 @@ from filelock import FileLock, Timeout from ..utils import check_dashboard, get_astrbot_root -async def initialize_astrbot(astrbot_root) -> None: +async def initialize_astrbot(astrbot_root: Path) -> None: """执行 AstrBot 初始化逻辑""" dot_astrbot = astrbot_root / ".astrbot" diff --git a/astrbot/cli/utils/plugin.py b/astrbot/cli/utils/plugin.py index 55edf4de2..cd76a07c8 100644 --- a/astrbot/cli/utils/plugin.py +++ b/astrbot/cli/utils/plugin.py @@ -221,9 +221,9 @@ def manage_plugin( raise click.ClickException(f"插件 {plugin_name} 未安装,无法更新") # 备份现有插件 - if is_update and backup_path.exists(): + if is_update and backup_path is not None and backup_path.exists(): shutil.rmtree(backup_path) - if is_update: + if is_update and backup_path is not None: shutil.copytree(target_path, backup_path) try: @@ -233,13 +233,13 @@ def manage_plugin( get_git_repo(repo_url, target_path, proxy) # 更新成功,删除备份 - if is_update and backup_path.exists(): + if is_update and backup_path is not None and backup_path.exists(): shutil.rmtree(backup_path) click.echo(f"插件 {plugin_name} {'更新' if is_update else '安装'}成功") except Exception as e: if target_path.exists(): shutil.rmtree(target_path, ignore_errors=True) - if is_update and backup_path.exists(): + if is_update and backup_path is not None and backup_path.exists(): shutil.move(backup_path, target_path) raise click.ClickException( f"{'更新' if is_update else '安装'}插件 {plugin_name} 时出错: {e}", diff --git a/astrbot/cli/utils/version_comparator.py b/astrbot/cli/utils/version_comparator.py index 99d71d34d..0aaf8dcab 100644 --- a/astrbot/cli/utils/version_comparator.py +++ b/astrbot/cli/utils/version_comparator.py @@ -62,9 +62,12 @@ class VersionComparator: return -1 if isinstance(p1, str) and isinstance(p2, int): return 1 - if (isinstance(p1, int) and isinstance(p2, int)) or ( - isinstance(p1, str) and isinstance(p2, str) - ): + if isinstance(p1, int) and isinstance(p2, int): + if p1 > p2: + return 1 + if p1 < p2: + return -1 + elif isinstance(p1, str) and isinstance(p2, str): if p1 > p2: return 1 if p1 < p2: diff --git a/astrbot/core/config/astrbot_config.py b/astrbot/core/config/astrbot_config.py index 68b73cd29..786d29c81 100644 --- a/astrbot/core/config/astrbot_config.py +++ b/astrbot/core/config/astrbot_config.py @@ -28,7 +28,7 @@ class AstrBotConfig(dict): self, config_path: str = ASTRBOT_CONFIG_PATH, default_config: dict = DEFAULT_CONFIG, - schema: dict = None, + schema: dict | None = None, ): super().__init__() @@ -142,7 +142,7 @@ class AstrBotConfig(dict): return has_new - def save_config(self, replace_config: dict = None): + def save_config(self, replace_config: dict | None = None): """将配置写入文件 如果传入 replace_config,则将配置替换为 replace_config diff --git a/astrbot/core/db/migration/sqlite_v3.py b/astrbot/core/db/migration/sqlite_v3.py index 7b341c316..a301028d1 100644 --- a/astrbot/core/db/migration/sqlite_v3.py +++ b/astrbot/core/db/migration/sqlite_v3.py @@ -384,11 +384,11 @@ class SQLiteDatabase: self, page: int = 1, page_size: int = 20, - platforms: list[str] = None, - message_types: list[str] = None, - search_query: str = None, - exclude_ids: list[str] = None, - exclude_platforms: list[str] = None, + platforms: list[str] | None = None, + message_types: list[str] | None = None, + search_query: str | None = None, + exclude_ids: list[str] | None = None, + exclude_platforms: list[str] | None = None, ) -> tuple[list[dict[str, Any]], int]: """获取筛选后的对话列表""" try: diff --git a/astrbot/core/persona_mgr.py b/astrbot/core/persona_mgr.py index 482b5887c..5d1743ab9 100644 --- a/astrbot/core/persona_mgr.py +++ b/astrbot/core/persona_mgr.py @@ -68,9 +68,9 @@ class PersonaManager: async def update_persona( self, persona_id: str, - system_prompt: str = None, - begin_dialogs: list[str] = None, - tools: list[str] = None, + system_prompt: str | None = None, + begin_dialogs: list[str] | None = None, + tools: list[str] | None = None, ): """更新指定 persona 的信息。tools 参数为 None 时表示使用所有工具,空列表表示不使用任何工具""" existing_persona = await self.db.get_persona_by_id(persona_id) diff --git a/astrbot/core/platform/astr_message_event.py b/astrbot/core/platform/astr_message_event.py index 1c37f6a69..6402aeaed 100644 --- a/astrbot/core/platform/astr_message_event.py +++ b/astrbot/core/platform/astr_message_event.py @@ -324,7 +324,7 @@ class AstrMessageEvent(abc.ABC): image_urls: list[str] | None = None, contexts: list | None = None, system_prompt: str = "", - conversation: Conversation = None, + conversation: Conversation | None = None, ) -> ProviderRequest: """创建一个 LLM 请求。 @@ -394,7 +394,7 @@ class AstrMessageEvent(abc.ABC): """ await self.send(MessageChain([Plain(emoji)])) - async def get_group(self, group_id: str = None, **kwargs) -> Group | None: + async def get_group(self, group_id: str | None = None, **kwargs) -> Group | None: """获取一个群聊的数据, 如果不填写 group_id: 如果是私聊消息,返回 None。如果是群聊消息,返回当前群聊的数据。 适配情况: diff --git a/astrbot/core/platform/astrbot_message.py b/astrbot/core/platform/astrbot_message.py index dcc70b0f2..0ada18506 100644 --- a/astrbot/core/platform/astrbot_message.py +++ b/astrbot/core/platform/astrbot_message.py @@ -9,7 +9,7 @@ from .message_type import MessageType @dataclass class MessageMember: user_id: str # 发送者id - nickname: str = None + nickname: str | None = None def __str__(self): # 使用 f-string 来构建返回的字符串表示形式 @@ -23,15 +23,15 @@ class MessageMember: class Group: group_id: str """群号""" - group_name: str = None + group_name: str | None = None """群名称""" - group_avatar: str = None + group_avatar: str | None = None """群头像""" - group_owner: str = None + group_owner: str | None = None """群主 id""" - group_admins: list[str] = None + group_admins: list[str] | None = None """群管理员 id""" - members: list[MessageMember] = None + members: list[MessageMember] | None = None """所有群成员""" def __str__(self): diff --git a/astrbot/core/platform/message_session.py b/astrbot/core/platform/message_session.py index 62240b621..bca5300b8 100644 --- a/astrbot/core/platform/message_session.py +++ b/astrbot/core/platform/message_session.py @@ -13,7 +13,7 @@ class MessageSession: """平台适配器实例的唯一标识符。自 AstrBot v4.0.0 起,该字段实际为 platform_id。""" message_type: MessageType session_id: str - platform_id: str = None + platform_id: str | None = None def __str__(self): return f"{self.platform_id}:{self.message_type.value}:{self.session_id}" diff --git a/astrbot/core/platform/platform_metadata.py b/astrbot/core/platform/platform_metadata.py index 37f8527a1..d75811245 100644 --- a/astrbot/core/platform/platform_metadata.py +++ b/astrbot/core/platform/platform_metadata.py @@ -7,12 +7,12 @@ class PlatformMetadata: """平台的名称,即平台的类型,如 aiocqhttp, discord, slack""" description: str """平台的描述""" - id: str = None + id: str | None = None """平台的唯一标识符,用于配置中识别特定平台""" - default_config_tmpl: dict = None + default_config_tmpl: dict | None = None """平台的默认配置模板""" - adapter_display_name: str = None + adapter_display_name: str | None = None """显示在 WebUI 配置页中的平台名称,如空则是 name""" - logo_path: str = None + logo_path: str | None = None """平台适配器的 logo 文件路径(相对于插件目录)""" diff --git a/astrbot/core/platform/register.py b/astrbot/core/platform/register.py index 4cd62ede0..0c6267492 100644 --- a/astrbot/core/platform/register.py +++ b/astrbot/core/platform/register.py @@ -11,9 +11,9 @@ platform_cls_map: dict[str, type] = {} def register_platform_adapter( adapter_name: str, desc: str, - default_config_tmpl: dict = None, - adapter_display_name: str = None, - logo_path: str = None, + default_config_tmpl: dict | None = None, + adapter_display_name: str | None = None, + logo_path: str | None = None, ): """用于注册平台适配器的带参装饰器。 diff --git a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py index 5fe605a74..ce8fd56df 100644 --- a/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py +++ b/astrbot/core/platform/sources/aiocqhttp/aiocqhttp_message_event.py @@ -94,7 +94,7 @@ class AiocqhttpMessageEvent(AstrMessageEvent): message_chain: MessageChain, event: Event | None = None, is_group: bool = False, - session_id: str = None, + session_id: str | None = None, ): """发送消息至 QQ 协议端(aiocqhttp)。 diff --git a/astrbot/core/platform/sources/discord/client.py b/astrbot/core/platform/sources/discord/client.py index 0a2982ce8..5d29e3429 100644 --- a/astrbot/core/platform/sources/discord/client.py +++ b/astrbot/core/platform/sources/discord/client.py @@ -14,7 +14,7 @@ else: class DiscordBotClient(discord.Bot): """Discord客户端封装""" - def __init__(self, token: str, proxy: str = None): + def __init__(self, token: str, proxy: str | None = None): self.token = token self.proxy = proxy diff --git a/astrbot/core/platform/sources/discord/components.py b/astrbot/core/platform/sources/discord/components.py index dbddd1686..d3e69e763 100644 --- a/astrbot/core/platform/sources/discord/components.py +++ b/astrbot/core/platform/sources/discord/components.py @@ -11,14 +11,14 @@ class DiscordEmbed(BaseMessageComponent): def __init__( self, - title: str = None, - description: str = None, - color: int = None, - url: str = None, - thumbnail: str = None, - image: str = None, - footer: str = None, - fields: list[dict] = None, + title: str | None = None, + description: str | None = None, + color: int | None = None, + url: str | None = None, + thumbnail: str | None = None, + image: str | None = None, + footer: str | None = None, + fields: list[dict] | None = None, ): self.title = title self.description = description @@ -66,10 +66,10 @@ class DiscordButton(BaseMessageComponent): def __init__( self, label: str, - custom_id: str = None, + custom_id: str | None = None, style: str = "primary", - emoji: str = None, - url: str = None, + emoji: str | None = None, + url: str | None = None, disabled: bool = False, ): self.label = label diff --git a/astrbot/core/platform/sources/discord/discord_platform_adapter.py b/astrbot/core/platform/sources/discord/discord_platform_adapter.py index 5dc1fd8a6..276d3dce5 100644 --- a/astrbot/core/platform/sources/discord/discord_platform_adapter.py +++ b/astrbot/core/platform/sources/discord/discord_platform_adapter.py @@ -386,7 +386,9 @@ class DiscordPlatformAdapter(Platform): def _create_dynamic_callback(self, cmd_name: str): """为每个指令动态创建一个异步回调函数""" - async def dynamic_callback(ctx: discord.ApplicationContext, params: str = None): + async def dynamic_callback( + ctx: discord.ApplicationContext, params: str | None = None + ): # 将平台特定的前缀'/'剥离,以适配通用的CommandFilter logger.debug(f"[Discord] 回调函数触发: {cmd_name}") logger.debug(f"[Discord] 回调函数参数: {ctx}") diff --git a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py index f3c2ef0e5..fe1496644 100644 --- a/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py +++ b/astrbot/core/platform/sources/qqofficial/qqofficial_message_event.py @@ -76,7 +76,7 @@ class QQOfficialMessageEvent(AstrMessageEvent): return await super().send_streaming(generator, use_fallback) - async def _post_send(self, stream: dict = None): + async def _post_send(self, stream: dict | None = None): if not self.send_buffer: return None @@ -265,17 +265,17 @@ class QQOfficialMessageEvent(AstrMessageEvent): self, openid: str, msg_type: int = 0, - content: str = None, - embed: message.Embed = None, - ark: message.Ark = None, - message_reference: message.Reference = None, - media: message.Media = None, - msg_id: str = None, + content: str | None = None, + embed: message.Embed | None = None, + ark: message.Ark | None = None, + message_reference: message.Reference | None = None, + media: message.Media | None = None, + msg_id: str | None = None, msg_seq: str = 1, - event_id: str = None, - markdown: message.MarkdownPayload = None, - keyboard: message.Keyboard = None, - stream: dict = None, + event_id: str | None = None, + markdown: message.MarkdownPayload | None = None, + keyboard: message.Keyboard | None = None, + stream: dict | None = None, ) -> message.Message: payload = locals() payload.pop("self", None) diff --git a/astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py b/astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py index d372211c9..09924edb6 100644 --- a/astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py +++ b/astrbot/core/platform/sources/wechatpadpro/xml_data_parser.py @@ -18,7 +18,7 @@ class GeweDataParser: is_private_chat: bool = False, cached_texts=None, cached_images=None, - raw_message: dict = None, + raw_message: dict | None = None, downloader=None, ): self._xml = None diff --git a/astrbot/core/platform_message_history_mgr.py b/astrbot/core/platform_message_history_mgr.py index fa9a9733c..0e079e893 100644 --- a/astrbot/core/platform_message_history_mgr.py +++ b/astrbot/core/platform_message_history_mgr.py @@ -11,8 +11,8 @@ class PlatformMessageHistoryManager: platform_id: str, user_id: str, content: list[dict], # TODO: parse from message chain - sender_id: str = None, - sender_name: str = None, + sender_id: str | None = None, + sender_name: str | None = None, ): """Insert a new platform message history record.""" await self.db.insert_platform_message_history( diff --git a/astrbot/core/provider/provider.py b/astrbot/core/provider/provider.py index 23abfcfc0..a46b9cf9f 100644 --- a/astrbot/core/provider/provider.py +++ b/astrbot/core/provider/provider.py @@ -85,12 +85,12 @@ class Provider(AbstractProvider): async def text_chat( self, prompt: str, - session_id: str = None, - image_urls: list[str] = None, - func_tool: ToolSet = None, - contexts: list = None, - system_prompt: str = None, - tool_calls_result: ToolCallsResult | list[ToolCallsResult] = None, + session_id: str | None = None, + image_urls: list[str] | None = None, + func_tool: ToolSet | None = None, + contexts: list | None = None, + system_prompt: str | None = None, + tool_calls_result: ToolCallsResult | list[ToolCallsResult] | None = None, model: str | None = None, **kwargs, ) -> LLMResponse: @@ -115,12 +115,12 @@ class Provider(AbstractProvider): async def text_chat_stream( self, prompt: str, - session_id: str = None, - image_urls: list[str] = None, - func_tool: ToolSet = None, - contexts: list = None, - system_prompt: str = None, - tool_calls_result: ToolCallsResult | list[ToolCallsResult] = None, + session_id: str | None = None, + image_urls: list[str] | None = None, + func_tool: ToolSet | None = None, + contexts: list | None = None, + system_prompt: str | None = None, + tool_calls_result: ToolCallsResult | list[ToolCallsResult] | None = None, model: str | None = None, **kwargs, ) -> AsyncGenerator[LLMResponse, None]: diff --git a/astrbot/core/provider/register.py b/astrbot/core/provider/register.py index eb8c72aea..1aead54df 100644 --- a/astrbot/core/provider/register.py +++ b/astrbot/core/provider/register.py @@ -15,8 +15,8 @@ def register_provider_adapter( provider_type_name: str, desc: str, provider_type: ProviderType = ProviderType.CHAT_COMPLETION, - default_config_tmpl: dict = None, - provider_display_name: str = None, + default_config_tmpl: dict | None = None, + provider_display_name: str | None = None, ): """用于注册平台适配器的带参装饰器""" diff --git a/astrbot/core/utils/io.py b/astrbot/core/utils/io.py index bd0bea920..03549dc97 100644 --- a/astrbot/core/utils/io.py +++ b/astrbot/core/utils/io.py @@ -77,8 +77,8 @@ def save_temp_img(img: Image.Image | str) -> str: async def download_image_by_url( url: str, post: bool = False, - post_data: dict = None, - path=None, + post_data: dict | None = None, + path: str | None = None, ) -> str: """下载图片, 返回 path""" try: diff --git a/astrbot/core/utils/pip_installer.py b/astrbot/core/utils/pip_installer.py index abe247146..6076a114a 100644 --- a/astrbot/core/utils/pip_installer.py +++ b/astrbot/core/utils/pip_installer.py @@ -6,15 +6,15 @@ logger = logging.getLogger("astrbot") class PipInstaller: - def __init__(self, pip_install_arg: str, pypi_index_url: str = None): + def __init__(self, pip_install_arg: str, pypi_index_url: str | None = None): self.pip_install_arg = pip_install_arg self.pypi_index_url = pypi_index_url async def install( self, - package_name: str = None, - requirements_path: str = None, - mirror: str = None, + package_name: str | None = None, + requirements_path: str | None = None, + mirror: str | None = None, ): args = ["install"] if package_name: diff --git a/astrbot/dashboard/routes/config.py b/astrbot/dashboard/routes/config.py index 59b07e47d..b947d26f2 100644 --- a/astrbot/dashboard/routes/config.py +++ b/astrbot/dashboard/routes/config.py @@ -926,7 +926,9 @@ class ConfigRoute(Route): return ret - async def _save_astrbot_configs(self, post_configs: dict, conf_id: str = None): + async def _save_astrbot_configs( + self, post_configs: dict, conf_id: str | None = None + ): try: if conf_id not in self.acm.confs: raise ValueError(f"配置文件 {conf_id} 不存在")