From 4972a3cdeaac805476cd2913a4882af61b5e5630 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Thu, 10 Sep 2026 10:19:16 +0800 Subject: [PATCH] fix(ci): close post-merge mypy regressions --- app/api/endpoints/download.py | 7 ++++--- app/api/endpoints/media.py | 12 +++++++----- docs/architecture/optimization-checklist.md | 2 +- tests/fixtures/architecture/mypy-baseline.json | 3 +-- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/api/endpoints/download.py b/app/api/endpoints/download.py index 5da105142..06e53a55a 100644 --- a/app/api/endpoints/download.py +++ b/app/api/endpoints/download.py @@ -255,7 +255,7 @@ def download( return _SchemaResponse(success=True, data={"download_id": did}) -@router.post( +@router.post( # type: ignore[misc] "/artist-collection", summary="添加艺术家合集下载", response_model=_SchemaResponse[_SchemaDownloadAddedData], @@ -293,13 +293,14 @@ def download_artist_collection( library_category=MUSIC_ARTIST_COLLECTION_CATEGORY, ) metainfo = MetaInfo( - title=torrent_in.title, + title=torrent_in.title or "", subtitle=torrent_in.description, mtype=MediaType.MUSIC, ) torrentinfo = TorrentInfo() torrentinfo.from_dict(torrent_in.model_dump()) - torrentinfo.site_downloader = downloader + if downloader is not None: + torrentinfo.site_downloader = downloader context = Context(meta_info=metainfo, media_info=mediainfo, torrent_info=torrentinfo) did = DownloadChain().download_single( context=context, diff --git a/app/api/endpoints/media.py b/app/api/endpoints/media.py index be47e8654..bcd240af8 100644 --- a/app/api/endpoints/media.py +++ b/app/api/endpoints/media.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Annotated, Any, List, Optional, Union +from typing import Annotated, Any, List, Optional, Union, cast from uuid import UUID from fastapi import Depends, Query @@ -101,21 +101,23 @@ MediaSourceQuery = Annotated[ ] -def _get_search_result_source(obj: Union[_SchemaMediaInfo, _SchemaMediaPerson, dict]) -> Any: +def _get_search_result_source( + obj: Union[_SchemaMediaInfo, _SchemaMediaPerson, dict[str, Any]], +) -> Any: """读取影视、人物或音乐搜索结果中的媒体来源标识。""" if isinstance(obj, dict): return obj.get("media_source") or obj.get("source") return getattr(obj, "media_source", None) or getattr(obj, "source", None) -def _serialize_search_result(obj: Any) -> dict: +def _serialize_search_result(obj: Any) -> dict[str, Any]: """将域对象或 Pydantic 人物对象转换为统一搜索响应字典。""" if isinstance(obj, dict): return obj if hasattr(obj, "to_dict"): - return obj.to_dict() + return cast(dict[str, Any], obj.to_dict()) if hasattr(obj, "model_dump"): - return obj.model_dump() + return cast(dict[str, Any], obj.model_dump()) return {} diff --git a/docs/architecture/optimization-checklist.md b/docs/architecture/optimization-checklist.md index f3a65e63f..4ac659c65 100644 --- a/docs/architecture/optimization-checklist.md +++ b/docs/architecture/optimization-checklist.md @@ -102,7 +102,7 @@ ARCH-201 至 ARCH-204 均达到实现、验证、提交、推送和远端门禁 | Event Contract | 53 | 均已有 payload model,但当前全部是 diagnostic enforcement | | Python 源码量 | 305,884 行 | 排除 `app/plugins/**`;61 个文件超过 1,000 行,11 个超过 2,000 行 | | 长方法 | 290 个超过 80 行 | AST 统计排除 `app/plugins/**`;65 个超过 150 行,21 个超过 250 行 | -| 全量 mypy 历史债务 | 9,408 / 510 文件 | Agent API 重构后的现状基线;canonical Facade 与 endpoint 类型边界已补齐,低水位只允许继续下降 | +| 全量 mypy 历史债务 | 9,406 / 510 文件 | Agent API 重构后的现状基线;canonical Facade 与 endpoint 类型边界已补齐,低水位只允许继续下降 | | Ruff 历史诊断 | 530 | 低水位门禁通过,但规则集只覆盖 `E4/E7/E9/F/I` | | 覆盖率固定基线 | Application 80.00%,Domain 80.00% | Chain、Runtime、Agent、Adapter、Startup 未进入包级覆盖率门禁 | diff --git a/tests/fixtures/architecture/mypy-baseline.json b/tests/fixtures/architecture/mypy-baseline.json index cad69c28e..a2858d3b1 100644 --- a/tests/fixtures/architecture/mypy-baseline.json +++ b/tests/fixtures/architecture/mypy-baseline.json @@ -454,8 +454,7 @@ "attr-defined": 3, "misc": 13, "no-untyped-call": 5, - "no-untyped-def": 2, - "type-arg": 1 + "no-untyped-def": 1 }, "app/api/endpoints/mediaserver.py": { "arg-type": 4,