From fcecf5a01fa7c640f37f0099e525ac27766049d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=B5=E5=91=B5=E3=81=A7=E3=81=99?= <51957264+shoucandanghehe@users.noreply.github.com> Date: Thu, 25 Dec 2025 22:32:25 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20=E4=BF=AE=E6=94=B9=20basedpyrigh?= =?UTF-8?q?t=20=E9=85=8D=E7=BD=AE=20(#573)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🔧 修改 basedpyright 配置 * :rotating_light: auto fix by pre-commit hooks --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- ...a91210ce14d_correct_the_data_in_historicaldata.py | 2 +- ...bdafc339a_add_user_unique_identifier_field_to_.py | 2 +- nonebot_plugin_tetris_stats/games/schemas.py | 2 ++ .../games/tetrio/api/cache.py | 4 ++-- .../games/tetrio/api/leaderboards.py | 11 ++++------- .../games/tetrio/api/player.py | 8 ++++---- .../games/tetrio/api/schemas/base/__init__.py | 12 ++++++------ .../games/tetrio/api/schemas/summaries/league.py | 2 +- nonebot_plugin_tetris_stats/games/tetrio/query/v1.py | 3 --- nonebot_plugin_tetris_stats/games/tos/api/player.py | 2 +- nonebot_plugin_tetris_stats/games/tos/query.py | 2 +- nonebot_plugin_tetris_stats/utils/exception.py | 5 +++++ nonebot_plugin_tetris_stats/utils/host.py | 10 +++++----- .../utils/render/schemas/base.py | 4 ++-- .../utils/render/schemas/v2/tetrio/record/base.py | 3 ++- pyproject.toml | 6 ++++++ 16 files changed, 43 insertions(+), 35 deletions(-) diff --git a/nonebot_plugin_tetris_stats/config/migrations/8a91210ce14d_correct_the_data_in_historicaldata.py b/nonebot_plugin_tetris_stats/config/migrations/8a91210ce14d_correct_the_data_in_historicaldata.py index 7a02c55..514372c 100644 --- a/nonebot_plugin_tetris_stats/config/migrations/8a91210ce14d_correct_the_data_in_historicaldata.py +++ b/nonebot_plugin_tetris_stats/config/migrations/8a91210ce14d_correct_the_data_in_historicaldata.py @@ -67,7 +67,7 @@ def upgrade(name: str = '') -> None: # noqa: C901 logger.critical(msg) raise RuntimeError(msg) - from nonebot_plugin_tetris_stats.game_data_processor.schemas import ( # type: ignore[import-untyped] # noqa: PLC0415 + from nonebot_plugin_tetris_stats.game_data_processor.schemas import ( # type: ignore[import-untyped] # pyright: ignore[reportMissingImports] # noqa: PLC0415 BaseProcessedData, ) diff --git a/nonebot_plugin_tetris_stats/config/migrations/b7fbdafc339a_add_user_unique_identifier_field_to_.py b/nonebot_plugin_tetris_stats/config/migrations/b7fbdafc339a_add_user_unique_identifier_field_to_.py index c3544f5..0d6c1c2 100644 --- a/nonebot_plugin_tetris_stats/config/migrations/b7fbdafc339a_add_user_unique_identifier_field_to_.py +++ b/nonebot_plugin_tetris_stats/config/migrations/b7fbdafc339a_add_user_unique_identifier_field_to_.py @@ -66,7 +66,7 @@ def upgrade(name: str = '') -> None: # noqa: C901 msg = '本迁移需要1.0.4版本, 请先锁定版本至1.0.4版本再执行本迁移' logger.critical(msg) raise RuntimeError(msg) - from nonebot_plugin_tetris_stats.game_data_processor.schemas import ( # type: ignore[import-untyped] # noqa: PLC0415 + from nonebot_plugin_tetris_stats.game_data_processor.schemas import ( # type: ignore[import-untyped] # pyright: ignore[reportMissingImports] # noqa: PLC0415 BaseUser, ) diff --git a/nonebot_plugin_tetris_stats/games/schemas.py b/nonebot_plugin_tetris_stats/games/schemas.py index e66b81c..8274691 100644 --- a/nonebot_plugin_tetris_stats/games/schemas.py +++ b/nonebot_plugin_tetris_stats/games/schemas.py @@ -2,6 +2,7 @@ from abc import ABC, abstractmethod from typing import Generic, TypeVar from pydantic import BaseModel +from typing_extensions import override from ..utils.typedefs import GameType @@ -13,6 +14,7 @@ class BaseUser(BaseModel, ABC, Generic[T]): platform: T + @override def __eq__(self, other: object) -> bool: if isinstance(other, BaseUser): return self.unique_identifier == other.unique_identifier diff --git a/nonebot_plugin_tetris_stats/games/tetrio/api/cache.py b/nonebot_plugin_tetris_stats/games/tetrio/api/cache.py index 5a79994..c74e2fd 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/api/cache.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/api/cache.py @@ -17,7 +17,7 @@ UTC = timezone.utc request = Request(config.tetris.proxy.tetrio or config.tetris.proxy.main) -request.request = limit(timedelta(seconds=1))(request.request) # type: ignore[method-assign] +request.request = limit(timedelta(seconds=1))(request.request) # type: ignore[method-assign] # pyright: ignore[reportAttributeAccessIssue] class Cache: @@ -32,7 +32,7 @@ class Cache: logger.debug(f'{url}: Cache hit!') return cached_data response_data = await request.request(url, extra_headers, enable_anti_cloudflare=True) - parsed_data: SuccessModel | FailedModel = type_validate_json(SuccessModel | FailedModel, response_data) # type: ignore[arg-type] + parsed_data: SuccessModel | FailedModel = type_validate_json(SuccessModel | FailedModel, response_data) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] if isinstance(parsed_data, SuccessModel): await cls.cache.add( url, diff --git a/nonebot_plugin_tetris_stats/games/tetrio/api/leaderboards.py b/nonebot_plugin_tetris_stats/games/tetrio/api/leaderboards.py index 8775e44..ac3eefa 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/api/leaderboards.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/api/leaderboards.py @@ -20,7 +20,7 @@ async def by( by_type: Literal['league', 'xp', 'ar'], parameter: Parameter, x_session_id: UUID | None = None ) -> BySuccessModel: model: By = type_validate_json( - By, # type: ignore[arg-type] + By, # type: ignore[arg-type] # pyright: ignore[reportArgumentType] await get( BASE_URL / f'users/by/{by_type}', parameter, @@ -69,7 +69,7 @@ async def records( match records_type: case '40l' | 'blitz': model = type_validate_json( - Solo, # type: ignore[arg-type] + Solo, # type: ignore[arg-type] # pyright: ignore[reportArgumentType] await get( BASE_URL / 'records' / f'{records_type}{scope}{revolution_id if revolution_id is not None else ""}', parameter, @@ -77,17 +77,14 @@ async def records( ) case 'zenith' | 'zenithex': model = type_validate_json( - Zenith, # type: ignore[arg-type] + Zenith, # type: ignore[arg-type] # pyright: ignore[reportArgumentType] await get( BASE_URL / 'records' / f'{records_type}{scope}{revolution_id if revolution_id is not None else ""}', parameter, ), ) - case _: - msg = f'records_type: {records_type} is not supported' - raise ValueError(msg) if isinstance(model, FailedModel): - msg = f'排行榜信息请求错误:\n{model.error}' # type: ignore[attr-defined] + msg = f'排行榜信息请求错误:\n{model.error}' raise RequestError(msg) return model diff --git a/nonebot_plugin_tetris_stats/games/tetrio/api/player.py b/nonebot_plugin_tetris_stats/games/tetrio/api/player.py index 3c0a601..24d7d63 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/api/player.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/api/player.py @@ -114,7 +114,7 @@ class Player: """Get User Info""" if self._user_info is None: raw_user_info = await Cache.get(BASE_URL / 'users' / self._request_user_parameter) - user_info: UserInfo = type_validate_json(UserInfo, raw_user_info) # type: ignore[arg-type] + user_info: UserInfo = type_validate_json(UserInfo, raw_user_info) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] if isinstance(user_info, FailedModel): msg = f'用户信息请求错误:\n{user_info.error}' raise RequestError(msg) @@ -146,7 +146,7 @@ class Player: BASE_URL / 'users' / self._request_user_parameter / 'summaries' / summaries_type ) summaries: SummariesModel | FailedModel = type_validate_json( - self.__SUMMARIES_MAPPING[summaries_type] | FailedModel, # type: ignore[assignment, arg-type] #! waiting for [PEP 747](https://peps.python.org/pep-0747/) + self.__SUMMARIES_MAPPING[summaries_type] | FailedModel, # type: ignore[assignment, arg-type] # pyright: ignore[reportArgumentType] #! waiting for [PEP 747](https://peps.python.org/pep-0747/) raw_summaries, ) if isinstance(summaries, FailedModel): @@ -166,7 +166,7 @@ class Player: async def get_leagueflow(self) -> LeagueFlowSuccess: if self._leagueflow is None: leagueflow: LeagueFlow = type_validate_json( - LeagueFlow, # type: ignore[arg-type] + LeagueFlow, # type: ignore[arg-type] # pyright: ignore[reportArgumentType] await Cache.get(BASE_URL / 'labs/leagueflow' / self._request_user_parameter), ) if isinstance(leagueflow, FailedModel): @@ -227,7 +227,7 @@ class Player: raw_records = await Cache.get( BASE_URL / 'users' / self._request_user_parameter / 'records' / mode_type / records_type, ) - records: RecordsSoloSuccessModel | FailedModel = type_validate_json(SoloRecord, raw_records) # type: ignore[arg-type] + records: RecordsSoloSuccessModel | FailedModel = type_validate_json(SoloRecord, raw_records) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] if isinstance(records, FailedModel): msg = f'用户Summaries数据请求错误:\n{records.error}' raise RequestError(msg) diff --git a/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/base/__init__.py b/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/base/__init__.py index 74d04af..b874ba8 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/base/__init__.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/base/__init__.py @@ -52,12 +52,12 @@ class P(BaseModel): # fmt: off class ArCounts(BaseModel): - bronze: int | None = Field(default=None, alias='1') # pyright: ignore [reportGeneralTypeIssues] - silver: int | None = Field(default=None, alias='2') # pyright: ignore [reportGeneralTypeIssues] - gold: int | None = Field(default=None, alias='3') # pyright: ignore [reportGeneralTypeIssues] - platinum: int | None = Field(default=None, alias='4') # pyright: ignore [reportGeneralTypeIssues] - diamond: int | None = Field(default=None, alias='5') # pyright: ignore [reportGeneralTypeIssues] - issued: int | None = Field(default=None, alias='100') # pyright: ignore [reportGeneralTypeIssues] + bronze: int | None = Field(default=None, alias='1') + silver: int | None = Field(default=None, alias='2') + gold: int | None = Field(default=None, alias='3') + platinum: int | None = Field(default=None, alias='4') + diamond: int | None = Field(default=None, alias='5') + issued: int | None = Field(default=None, alias='100') top3: int | None = Field(default=None, alias='t3') top5: int | None = Field(default=None, alias='t5') top10: int | None = Field(default=None, alias='t10') diff --git a/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/summaries/league.py b/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/summaries/league.py index 8e97dba..386a01e 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/summaries/league.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/api/schemas/summaries/league.py @@ -32,7 +32,7 @@ class PastInner(BaseModel): class Past(BaseModel): - first: PastInner | None = Field(default=None, alias='1') # pyright: ignore [reportGeneralTypeIssues] + first: PastInner | None = Field(default=None, alias='1') class BaseData(BaseModel): diff --git a/nonebot_plugin_tetris_stats/games/tetrio/query/v1.py b/nonebot_plugin_tetris_stats/games/tetrio/query/v1.py index 2d97042..4b90452 100644 --- a/nonebot_plugin_tetris_stats/games/tetrio/query/v1.py +++ b/nonebot_plugin_tetris_stats/games/tetrio/query/v1.py @@ -5,7 +5,6 @@ from hashlib import md5 from yarl import URL from ....utils.chart import get_split, get_value_bounds, handle_history_data -from ....utils.exception import FallbackError from ....utils.host import get_self_netloc from ....utils.lang import get_lang from ....utils.metrics import get_metrics @@ -28,8 +27,6 @@ async def make_query_image_v1(player: Player) -> bytes: gather(player.avatar_revision), ) league_data = get_league_data(league, RatedData) - if league_data.vs is None: - raise FallbackError histories = flow_to_history(leagueflow, handle_history_data) values = get_value_bounds([i.score for i in histories]) split_value, offset = get_split(values, TR_MAX, TR_MIN) diff --git a/nonebot_plugin_tetris_stats/games/tos/api/player.py b/nonebot_plugin_tetris_stats/games/tos/api/player.py index c7e773d..a692558 100644 --- a/nonebot_plugin_tetris_stats/games/tos/api/player.py +++ b/nonebot_plugin_tetris_stats/games/tos/api/player.py @@ -68,7 +68,7 @@ class Player: raw_user_info = await request.failover_request( [i / path % query for i in BASE_URL], failover_code=[502], failover_exc=(TimeoutException,) ) - user_info: UserInfo = type_validate_json(UserInfo, raw_user_info) # type: ignore[arg-type] + user_info: UserInfo = type_validate_json(UserInfo, raw_user_info) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] if not isinstance(user_info, UserInfoSuccess): msg = f'用户信息请求错误:\n{user_info.error}' raise RequestError(msg) diff --git a/nonebot_plugin_tetris_stats/games/tos/query.py b/nonebot_plugin_tetris_stats/games/tos/query.py index 05d8ff8..c9c87bf 100644 --- a/nonebot_plugin_tetris_stats/games/tos/query.py +++ b/nonebot_plugin_tetris_stats/games/tos/query.py @@ -178,7 +178,7 @@ async def get_game_data(player: Player, query_num: int = 50) -> GameData | None: for i in user_profile.data: # 排除单人局和时间为0的游戏 # 茶: 不计算没挖掘的局, 即使apm和lpm也如此 - if i.num_players == 1 or i.time == 0 or i.dig is None: + if i.num_players == 1 or i.time == 0: continue # 加权计算 time = i.time / 1000 diff --git a/nonebot_plugin_tetris_stats/utils/exception.py b/nonebot_plugin_tetris_stats/utils/exception.py index 938e815..fb64a15 100644 --- a/nonebot_plugin_tetris_stats/utils/exception.py +++ b/nonebot_plugin_tetris_stats/utils/exception.py @@ -1,12 +1,17 @@ +from typing_extensions import override + + class TetrisStatsError(Exception): """所有 TetrisStats 发生的异常基类""" def __init__(self, message: str = ''): self.message = message + @override def __str__(self) -> str: return self.message + @override def __repr__(self) -> str: return self.message diff --git a/nonebot_plugin_tetris_stats/utils/host.py b/nonebot_plugin_tetris_stats/utils/host.py index 60bba97..7a6f96b 100644 --- a/nonebot_plugin_tetris_stats/utils/host.py +++ b/nonebot_plugin_tetris_stats/utils/host.py @@ -20,7 +20,11 @@ from .templates import TEMPLATES_DIR if TYPE_CHECKING: from pydantic import IPvAnyAddress -app: FastAPI = get_app() +app = get_app() + +if not isinstance(app, FastAPI): + msg = '本插件需要 FastAPI 驱动器才能运行' + raise RuntimeError(msg) # noqa: TRY004 driver = get_driver() @@ -28,10 +32,6 @@ global_config = driver.config BASE_URL = URL('https://tetr.io/user-content/') -if not isinstance(app, FastAPI): - msg = '本插件需要 FastAPI 驱动器才能运行' - raise RuntimeError(msg) # noqa: TRY004 - NOT_FOUND = HTMLResponse('404 Not Found', status_code=status.HTTP_404_NOT_FOUND) diff --git a/nonebot_plugin_tetris_stats/utils/render/schemas/base.py b/nonebot_plugin_tetris_stats/utils/render/schemas/base.py index e240e0b..5b65f0b 100644 --- a/nonebot_plugin_tetris_stats/utils/render/schemas/base.py +++ b/nonebot_plugin_tetris_stats/utils/render/schemas/base.py @@ -1,4 +1,4 @@ -from abc import abstractmethod +from abc import ABC, abstractmethod from datetime import datetime from typing import Literal @@ -8,7 +8,7 @@ from strenum import StrEnum from ...typedefs import Lang, Number -class Base(BaseModel): +class Base(BaseModel, ABC): @property @abstractmethod def path(self) -> str: diff --git a/nonebot_plugin_tetris_stats/utils/render/schemas/v2/tetrio/record/base.py b/nonebot_plugin_tetris_stats/utils/render/schemas/v2/tetrio/record/base.py index 5912f65..7aaac81 100644 --- a/nonebot_plugin_tetris_stats/utils/render/schemas/v2/tetrio/record/base.py +++ b/nonebot_plugin_tetris_stats/utils/render/schemas/v2/tetrio/record/base.py @@ -1,3 +1,4 @@ +from abc import ABC from datetime import datetime from typing import Literal @@ -61,7 +62,7 @@ class Statistic(BaseModel): finesse: Finesse -class Record(Base): +class Record(Base, ABC): type: Literal['best', 'personal_best', 'recent', 'disputed'] user: User diff --git a/pyproject.toml b/pyproject.toml index 2a0b4f1..0a462c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -160,6 +160,12 @@ pythonVersion = "3.10" pythonPlatform = "All" defineConstant = { PYDANTIC_V2 = true } typeCheckingMode = "standard" +reportExplicitAny = 'hint' +reportUnnecessaryTypeIgnoreComment = 'error' +reportImplicitOverride = 'error' +reportUnnecessaryComparison = 'error' +reportImplicitAbstractClass = 'error' +enableTypeIgnoreComments = false [tool.bumpversion] current_version = "1.11.0"