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:
1 parent
fcd4cb4649
commit
d7a7107b0a
11 files changed
+200
-74
No files matched your search
+25
-16
@@ -9,6 +9,7 @@ TUI 会退化为无输入的只读模式。
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -40,28 +41,36 @@ class KeyReader:
|
||||
"""把终端的原始字节流转换成按键名。"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.available = sys.stdin is not None and sys.stdin.isatty()
|
||||
self._fd: int | None = None
|
||||
self._saved_term = None
|
||||
|
||||
if self.available and not IS_WINDOWS:
|
||||
try:
|
||||
import termios
|
||||
import tty
|
||||
# 先把 stdin 取到局部变量:下面每处都要用它。同时它的类型被收窄到非 None,
|
||||
# 省掉反复 `sys.stdin.xxx` 时"可能是 None"的隐患。
|
||||
stdin = sys.stdin
|
||||
if stdin is None or not stdin.isatty():
|
||||
self.available = False
|
||||
return
|
||||
self.available = True
|
||||
|
||||
self._fd = sys.stdin.fileno()
|
||||
self._saved_term = termios.tcgetattr(self._fd)
|
||||
# cbreak: 立即返回按键,但保留 Ctrl-C 等信号
|
||||
tty.setcbreak(self._fd)
|
||||
except Exception:
|
||||
if IS_WINDOWS:
|
||||
# Windows 靠 msvcrt 做非阻塞读;拿不到就认为终端不可用
|
||||
if importlib.util.find_spec("msvcrt") is None:
|
||||
self.available = False
|
||||
self._saved_term = None
|
||||
return
|
||||
|
||||
if self.available and IS_WINDOWS:
|
||||
try:
|
||||
import msvcrt # noqa: F401
|
||||
except Exception:
|
||||
self.available = False
|
||||
try:
|
||||
import termios
|
||||
import tty
|
||||
|
||||
# 用局部变量:self._fd 声明为 int | None,直接传进去会被判为可能为 None
|
||||
fd = stdin.fileno()
|
||||
self._fd = fd
|
||||
self._saved_term = termios.tcgetattr(fd)
|
||||
# cbreak: 立即返回按键,但保留 Ctrl-C 等信号
|
||||
tty.setcbreak(fd)
|
||||
except Exception:
|
||||
self.available = False
|
||||
self._saved_term = None
|
||||
|
||||
# ------------------------------------------------------------------ 读取
|
||||
def poll(self) -> str | None:
|
||||
|
||||
Reference in new issue
Block a user