chore: 引入 pyright 类型检查清零 + README 工程化章节

pyright(basic 模式)从 15 errors / 10 warnings 降到 0/0:

- pyproject: pythonPlatform="All"(termios/msvcrt 双平台分支不再误报),
  reportUnsupportedDunderAll=false(__init__ 惰性导出属正常写法)
- keys.py: 捕获 sys.stdin 局部变量 + 提前返回,消除 fileno() 的 None 收窄告警
- server/app.py: lifespan 改用 @asynccontextmanager 并标注 AsyncIterator[None]
- server/actions.py: 显式标注 result: dict[str, Any],消除 isinstance 冗余报错
- server/__main__.py: 用 importlib.util.find_spec 探测 websockets
- tests/test_server.py: 同上,uvicorn 探测改为 find_spec
- tools/preview_tui.py: TYPE_CHECKING 下引入 RemoteFarm,修正返回类型标注
- farm/tui.py: 取消未使用变量,统一 round/取整写法

其他:
- README: 新增第 11 节「工程化:uv + ruff + pyright」,快速开始全部改用
  uv sync / uv run;原第 11 节起顺延为 12
- requirements.txt: 由 uv export --no-dev --no-hashes 重新生成(锁定版本)
- 清理临时日志文件

验收:ruff check 全通过 / ruff format 26 文件无改动 / pyright 0 错误 /
unittest 97 项全部通过
This commit is contained in:
snowy-yang committed 2026-09-18 21:24:30 +08:00
1 parent fcd4cb4649
commit d7a7107b0a
11 files changed
+200 -74

No files matched your search

+5 -2
View File
@@ -18,7 +18,7 @@ import asyncio
import contextlib
import json
import time
from collections.abc import Callable
from collections.abc import AsyncIterator, Callable
from dataclasses import dataclass, field
from typing import Any
@@ -164,7 +164,10 @@ def create_app(cfg: ServerConfig | None = None) -> FastAPI:
started_at = time.time()
counters = {"requests": 0, "actions": 0, "ws_messages": 0, "errors": 0}
async def lifespan(_app: FastAPI) -> Any:
# 标注成 asynccontextmanager:FastAPI 的 lifespan 参数要的就是
# "返回异步上下文管理器",裸 async generator 在类型上并不匹配
@contextlib.asynccontextmanager
async def lifespan(_app: FastAPI) -> AsyncIterator[None]:
clock.start()
publisher.start()
# 端口已经绑定成功(uvicorn 先 bind 再跑 lifespan),可以对外宣告"我在了"