Files
SimpleFarm/pyproject.toml
T
snowy-yang fcd4cb4649 style: 引入 ruff,474 项告警清零
配置见 pyproject.toml:
- line-length=100:贴着现有代码定。若用默认的 88 会重排 122 行,
  噪音淹没真正有价值的修复。
- 启用 E/W/F/I/UP/B/C4/SIM/RET/PERF/RUF;**不**启用 PTH。因为本项目的路径
  多是"字符串身份"——要塞进 subprocess 命令行、写进 JSON 存档、打印给用户,
  全换 pathlib 只是包一层再拆一层,换来 70 处纯风格改动。
- 忽略 RUF001/002/003:中文全角标点是正确写法,不是"歧义字符"。
- 忽略 PERF203:剩下两处都是"逐项容错"语义(逐个牧场存档要立刻上报失败、
  收获全部要跳过失败地块)。把 try 提到循环外会毁掉"一项失败不影响其它项"
  这个行为,是错的优化。

自动修复 358 项:Dict/List/Optional 换成 PEP 585/604 写法、导入排序、
失效的 noqa、空占位 f-string 等。

手工修复的(这些是真问题,不是风格偏好):
- B904 x9:except 中 raise 补异常链。刻意区分——网络/IO 失败用 from exc 保留
  根因;参数解析失败用 from None,因为底层 ValueError 对玩家只是噪音。
- RUF012 x2:StateView 的 plots/animals 原本是**类级共享可变列表**,
  改成在 __init__ 里初始化(apply({}) 会提前返回,所以必须显式摆好)。
- F841:TUI 里一个赋值后再没用过的死变量。
- SIM105 x11:try/except/pass 统一改成 contextlib.suppress。
- SIM115:日志句柄改用 with。Popen 已把 fd 复制给子进程,父进程可安全关闭。
- E501 x7:拆超长行;main.py 那处顺手提取变量,避免超长嵌套表达式。
- E741:把 l/r 改成 left_line/right_line。
- 其余:RUF046 / PERF401 / RET504 / RUF005 / UP031 / B007。

ruff format 重排 24 个文件。

验证:97 项测试全绿。
2026-09-18 21:18:22 +08:00

119 lines
5.2 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SimpleFarm —— 项目元数据与工具配置
#
# 这个文件是**唯一真源**:依赖、Python 版本、lint 规则、类型检查规则全都写在这里。
# 日常操作全部交给 uv,不需要手动激活虚拟环境:
#
# uv sync # 按 uv.lock 建好 .venv(含开发依赖)
# uv run main.py serve --daemon
# uv run ruff check . # 静态检查
# uv run ruff format . # 格式化
# uv run pyright # 类型检查
#
# 为什么写 package = false:这是一个**应用**,不是要发布到 PyPI 的库。
# 关掉打包之后,uv 只负责环境与依赖,不引入任何构建后端(hatchling/setuptools 都不需要),
# `python main.py` 与 `uv run main.py` 行为完全一致。
[project]
name = "simplefarm"
version = "2.0.0"
description = "终端农场经营游戏 + 小型多人游戏服务器:人玩 TUI,AI 走 HTTP/WebSocket 接口"
readme = "README.md"
requires-python = ">=3.10"
license = "MIT"
keywords = ["game", "tui", "cli", "fastapi", "websocket", "llm", "agent"]
classifiers = [
"Programming Language :: Python :: 3 :: Only",
"Topic :: Games/Entertainment :: Simulation",
]
# 运行依赖 —— 只有**服务端**需要。
# 终端界面、命令行客户端、规则机器人全部只用标准库,
# 所以 `uv run main.py solo` 这类离线玩法不需要装下面这两个。
dependencies = [
"fastapi>=0.110",
"uvicorn[standard]>=0.27", # [standard] 带上 websockets,实时推送靠它
]
# 开发依赖(`uv sync` 默认就会装,用 `uv sync --no-dev` 可以跳过)。
# httpx 不是可选项:FastAPI 的 TestClient 建立在它之上,测试必需。
[dependency-groups]
dev = [
"ruff>=0.8.0",
"pyright>=1.1.390",
"httpx>=0.27",
]
[tool.uv]
package = false
# --------------------------------------------------------------------- ruff
# 职责二合一:`ruff format` 管格式,`ruff check` 管正确性与一致性。
# 之所以不用 Black + isort + flake8 三件套,是因为 ruff 一个二进制就覆盖了它们,
# 而且配置在同一次解析里生效,不会出现"格式化完 lint 又报"的拉锯。
[tool.ruff]
line-length = 100 # 贴着现有代码定:只有 18 行超 100,用默认的 88 会重排 122 行
target-version = "py310" # 与 requires-python 对齐
src = ["farm", "tests", "tools"]
# 文档里的示例代码是"给人看的排版",不交给格式化器管
extend-exclude = ["README.md"]
[tool.ruff.lint]
select = [
"E", # pycodestyle 错误
"W", # pycodestyle 警告
"F", # pyflakes:未使用的导入/变量、未定义的名字
"I", # isort:导入排序
"UP", # pyupgrade:用新语法替换过时写法
"B", # flake8-bugbear:容易踩坑的写法(可变默认值、裸 except、丢异常链……)
"C4", # flake8-comprehensions
"SIM", # flake8-simplify
"RET", # flake8-return:多余的 else / 多余的中间变量
"PERF",# 明显的性能坑(比如循环里做成员判断)
"RUF", # ruff 自带规则
]
# 为什么**没有**启用 PTH(flake8-use-pathlib):
# 这个项目的路径绝大多数是"字符串身份"——要塞进 subprocess 命令行、要写进 JSON
# 存档、要打印给用户看。全部换成 pathlib 只是把字符串包一层再拆一层,
# 换来 70 处纯风格改动,却掩盖了真正有价值的修复。路径运算本来就少,
# 现有 os.path 用法是合适的选择。
ignore = [
# RUF001/002/003 会把中文全角标点当成"含糊的 Unicode 字符"报出来。
# 这个项目注释与界面文案本来就是中文,全角括号是正确写法,不是错误。
"RUF001",
"RUF002",
"RUF003",
# PERF203 提示"循环里 try 有性能开销"。剩下两处都是**逐项容错**语义:
# 逐个牧场存档(失败要立刻上报,不能静默跳过)、收获全部时跳过失败的地块。
# 把 try 提到循环外会让"一项失败不影响其它项"这个行为消失——那是错的优化。
# 而且循环规模是牧场数 / 地块数级别(个位数),性能开销在这里无关紧要。
"PERF203",
]
[tool.ruff.lint.per-file-ignores]
# 内嵌的 HTML/JS 模板:整块写在一个字符串里,按 100 列硬拆反而更难读也更难改
"farm/server/webui.py" = ["E501"]
# 测试里注释是"解释为什么这么断言",紧跟断言更清楚;含长中文行属正常
"tests/*" = ["E501"]
[tool.ruff.lint.isort]
known-first-party = ["farm"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto" # Windows/Linux 混用时不要强改行尾,避免整文件 diff
# ------------------------------------------------------------------ pyright
# 只做到"能进 CI 拦住真问题"的程度:
# - basic 模式抓得住 None 误用、参数个数/类型不符、属性不存在这类真 bug;
# - 不去追 Unknown 类型(本项目的快照是 dict[str, Any] 结构,追下去全是噪音)。
[tool.pyright]
include = ["farm", "tests", "tools", "main.py", "ai_player.py"]
exclude = [".venv", "**/__pycache__", ".ruff_cache", "saves", "run", "tests/_tmp"]
pythonVersion = "3.10"
typeCheckingMode = "basic"
reportMissingTypeStubs = false # 让"没装 third-party 存根"保持安静
reportUnusedImport = true
reportUnnecessaryIsInstance = true