题记与说明
- 日期:2026-10-31
- 类型:主题研究(先检索 3-5 个来源并精读;本篇实际精读 9 个来源,全部有网络抓取记录,无凭记忆编造)
- 主题:为 Windows 开发者整理一套可复制粘贴的可维护 Python 项目模板,覆盖五个工具:uv(环境与依赖)、Ruff(lint + format)、Pyright(类型检查)、pytest(测试)、pre-commit(提交门禁)
- 版本基准:以下版本号均来自本次实际抓取/核实:uv 文档默认示例
uv_build>=0.13.0,<0.14、默认requires-python = ">=3.14"(页面发布 2026-10-09);ruff-pre-commitv0.17.2(Ruff 官方教程原文);pre-commit 运行时4.6.2(官网 Quick start 输出);pyright-pythonv1.1.414(README 示例);pre-commit-hooks 最新 tagv6.0.0(用git ls-remote --tags https://github.com/pre-commit/pre-commit-hooks实测核实,输出末行为refs/tags/v6.0.0)。
0. 七维总览
| 维度 | 内容 |
|---|---|
| 核心问题 | Python 官方不统一项目工程化:环境、格式化、lint、类型、测试、提交门禁曾分散在 pip/virtualenv、Black+isort+Flake8+pyupgrade、mypy、unittest、手写 git hook 等一串工具里,新项目搭一套标准脚手架成本高,Windows 上还有安装与换行等额外摩擦 |
| 主要主张 | 2025-2026 共识栈收敛为:uv(替代 pip/pipx/pyenv/virtualenv/poetry)+ Ruff(一个 Rust 工具替代 Black/isort/Flake8/pyupgrade 大部分)+ Pyright 或 mypy(类型)+ pytest(测试)+ pre-commit(把前四者挂到 git hook 上强制执行);全部工具配置可集中进一个 pyproject.toml |
| 方法 | 逐工具精读官方文档(uv projects/installation、Ruff tutorial、Pyright getting-started/configuration、pytest customize、pre-commit 全文、pre-commit-hooks README、pyright-python README)+ 一篇第三方工具链观点文(pydevtools.com);从官方文档提取可复制配置片段,再按 Windows 约束(PowerShell、CRLF、大小写不敏感、py launcher)重新拼装 |
| 数据与证据 | uv.lock 跨平台锁文件必须入库;uv run 每次先校验锁文件与环境同步;Ruff 900+ 规则、默认启用 F/E/B/UP/RUF;Pyright typeCheckingMode 默认 standard;pytest 配置文件"first match wins"永不合并;pre-commit 的 python hook 官方声明 tested on windows;Windows 专属 hook(check-case-conflict / check-illegal-windows-names / destroyed-symlinks)有官方定义 |
| 结论 | 给出完整可复制模板(PowerShell 安装命令、pyproject.toml 全量、.pre-commit-config.yaml 全量、.gitattributes、命令速查);Windows 侧最大的坑是换行策略与 hook 的交互、pyright 在 pre-commit 独立 venv 里找不到依赖这两点,均有文档级解法 |
| 局限 | 各 rev 版本号会过时;pre-commit pytest 钩子的 language: unsupported 写法需 pre-commit ≥4.4.0;Windows Store 版 Python 的 PATH 问题仅在搜索摘要中看到线索、未深读原帖;模板未在真实机器上端到端跑过(本子任务未创建 uv 项目实测) |
| 对我的启发 | 锁文件入库 + uv run 自动同步 = 新机器 5 分钟复现环境;pre-commit 只做"快门禁"(lint/format/类型),pytest 挂 pre-push,重测试留给 CI;Windows 团队第一天就该提交 .gitattributes,否则换行问题会被拖到协作中期 |
1. 来源清单(本次实际精读)
| # | 来源 | 抓取方式 | 说明 |
|---|---|---|---|
| 1 | uv — Working on projects(页面发布 2026-10-09) | WebReader 全文 | uv 项目工作流官方指南 |
| 2 | uv — Installation(页面发布 2026-10-21) | WebReader 全文 | 含 Windows PowerShell / winget / scoop 安装 |
| 3 | Ruff — Tutorial | WebReader 全文 | 含规则选择、配置发现、ruff-pre-commit 集成 |
| 4 | Pyright — Getting Started | WebReader 全文 | 类型检查渐进式采纳路径 |
| 5 | Pyright — Configuration | WebFetch 摘要 | pyrightconfig.json / [tool.pyright] / venv 解析 |
| 6 | pyright-python README | WebFetch 摘要 | pyright CLI 安装、pre-commit hook、venv 陷阱 |
| 7 | pre-commit 官方文档 | WebReader 全文 | 设计理念、配置项全表、Windows 相关注记 |
| 8 | pytest — Configuration reference | WebFetch 摘要 | 配置文件优先级、[tool.pytest.ini_options] |
| 9 | pre-commit/pre-commit-hooks README | WebFetch 摘要 + git ls-remote | Windows 相关 hook 原文定义 |
| 10 | Effective Python Developer Tooling (Dec 2024), pydevtools.com | WebFetch 摘要 | 第三方观点佐证工具收敛趋势 |
辅助检索(未深读、仅作为线索标注):WebSearch 结果中提到的 MicroPython GitHub Discussion #12045(Windows 上 pre-commit 装不上)、Reddit r/Python "Ultra-strict Python template v2"(uv + basedpyright 超严格模板)。
2. 核心问题
这份"模板"在解决什么问题?综合 pydevtools.com 与各官方文档:
- 工具链碎片化:传统 Python 项目要装 pip、virtualenv、pip-tools、pipx、pyenv、Black、isort、Flake8、pyupgrade、mypy……pydevtools.com 直接说 uv "replac[es] pip, pip-tools, pipx, poetry, pyenv, twine, and virtualenv",Ruff 是 "linter/formatter replacing Black, flake8 (mostly), and isort"。
- 约束不自动执行:lint/格式/类型规则写在文档里没人遵守;pre-commit 官网对动机的原文:"We run our hooks on every commit to automatically point out issues in code such as missing semicolons, trailing whitespace, and debug statements. By pointing these issues out before code review, this allows a code reviewer to focus on the architecture of a change while not wasting time with trivial style nitpicks."
- 跨机器可复现:uv 用锁文件解决;pytest/pyright/Ruff 配置集中到 pyproject.toml 解决"每台机器配置漂移"。
- Windows 额外摩擦:安装脚本、venv 激活路径、py launcher、大小写不敏感文件系统、CRLF 换行——官方文档各有零散注记,本笔记把它们收拢成清单。
3. 主要主张(逐来源)
3.1 uv:一个二进制管完环境与依赖
- 项目即
pyproject.toml:uv init hello-world生成.gitignore / .python-version / pyproject.toml / README.md / src/hello_world/__init__.py,首次运行项目命令时自动创建.venv与uv.lock(来源 1)。 - 锁文件入库是官方立场(来源 1 原文):
"uv.lock is a cross-platform lockfile that contains exact information about your project's dependencies. … This file should be checked into version control, allowing for consistent and reproducible installations across machines."
uv run是"自动同步的入口"(来源 1 原文):
"Prior to everyuv runinvocation, uv will verify that the lockfile is up-to-date with thepyproject.toml, and that the environment is up-to-date with the lockfile, keeping your project in-sync without the need for manual intervention."
- Windows 安装有三种官方路径(来源 2):PowerShell 独立安装脚本、winget、scoop。PowerShell 原文命令:
PS> powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
并有注记 "Changing the execution policy allows running a script from the internet.";winget 原文:winget install --id=astral-sh.uv -e。
- venv 激活的 Windows 写法在多个官方页面重复出现(来源 1/3):
.venv\Scripts\activate。
3.2 Ruff:lint + format 合一,默认规则就是起点
- 规模声明(来源 3 原文):"Ruff supports over 900 lint rules split across over 50 built-in plugins"。
- 默认规则集(来源 3 原文):"By default, Ruff enables rules from the
F,E,B,UP, andRUFcategories, as well as many more, omitting any stylistic rules that overlap with the use of a formatter, likeruff formator Black." 官方还明确说 "the default rule set is a great place to start: it catches a wide variety of common errors (like unused imports) with zero configuration." - 配置发现机制(来源 3 原文):"To determine the appropriate settings for each Python file, Ruff looks for the first
pyproject.toml,ruff.toml, or.ruff.tomlfile in the file's directory or any parent directory." → 模板里只需根目录一份 pyproject.toml。 - 官方推荐的 pre-commit 集成(来源 3 原文,rev 为抓取时最新):
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.17.2
hooks:
# Run the linter.
- id: ruff-check
# Run the formatter.
- id: ruff-format3.3 Pyright:渐进式类型检查,standard 起步
- 官方给的采纳路径是四步渐进(来源 4):① minimal
pyrightconfig.json(或 pyproject.toml 里的 pyright 节)跑默认设置 → ② 开reportMissingTypeStubs、补 stub → ③ 增量加注解,"The annotations that provide most value are on function input parameters, instance variables, and return parameters (in that order)",并启用reportUnknownParameterType等严格选项 → ④ 按文件开启严格模式:
"On a file-by-file basis, enable all type checking options by adding the comment # pyright: strict somewhere in the file."
- 配置位置(来源 5):"Pyright settings can also be specified in a [tool.pyright] section of a 'pyproject.toml' file.",但两处都存在时 "a pyrightconfig.json takes precedence"。
typeCheckingMode取值 "off", "basic", "standard", "strict","The default value for this setting is 'standard'."(来源 5)。- venv 解析(来源 5):
venvPath+venv让 pyright "search for imports in the virtual environment's site-packages directory";文档提醒不要把 venvPath 放进共享配置(路径因人而异)——但在 uv 的世界里.venv永远在项目根,路径全队一致,这正是 pyright-python README 对 pre-commit 场景给出的推荐(见 3.4)。
3.4 pyright-python:CLI 与 pre-commit hook 的官方接入点
- 安装(来源 6 原文):
pip install pyright,推荐pip install pyright[nodejs],因为它 "uses nodejs-wheel to download Node.js binaries as it is more reliable than the default nodeenv solution"。 - 运行机制(来源 6 原文):"This project works by first checking if node is in the PATH. If it is not, then we download node at runtime using nodeenv, then install the pyright npm package using npm and finally, run the downloaded JS with node." 相关环境变量:
PYRIGHT_PYTHON_GLOBAL_NODE、PYRIGHT_PYTHON_NODE_VERSION、PYRIGHT_PYTHON_ENV_DIR、PYRIGHT_PYTHON_CACHE_DIR。 - pre-commit 用法(来源 6 原文):
repos:
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.414
hooks:
- id: pyright
- 关键陷阱(来源 6 原文):"Pre-commit will install pyright-python in its own virtual environment which can cause pyright to not be able to detect your installed dependencies." 解法(同页给出的配置):
[tool.pyright]
venvPath = "."
venv = ".venv"
- 注意:pre-commit 组织下没有官方
mirrors-pyright(mypy/black 那种镜像仓库不存在,pyright 包装了 npm 所以镜像难做)——这是 WebSearch 检索结论,RobertCraigie/pyright-python 就是事实上的官方接入点。
3.5 pytest:配置进 pyproject.toml,优先级"先到先得"
[tool.pytest.ini_options]自 pytest 6.0 起支持;pytest 9.0 起另支持原生 TOML 的[tool.pytest]表,且新增pytest.toml/.pytest.toml文件类型(来源 8)。- 优先级原文(来源 8):"Options from multiple
configfilescandidates are never merged - the first match wins." 具体顺序:pytest.toml > pytest.ini > pyproject.toml > tox.ini > setup.cfg。 - pyproject.toml 只有在"contains a
[tool.pytest]or[tool.pytest.ini_options]table"时才算配置文件(来源 8)——空表也行,否则 pytest 会往上找别的文件。 - 官方示例(来源 8 原文):
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q"
testpaths = [
"tests",
"integration",
]
- 常见坑(来源 8 + 检索佐证):目录里残留一个旧
pytest.ini会整个屏蔽 pyproject.toml 的配置(first match wins,不合并),表现为"filterwarnings/addopts 不生效";rootdir "is NOT used to modifysys.path/PYTHONPATH"。
3.6 pre-commit:多语言 hook 包管理器
- 设计定位(来源 7 原文):"We built pre-commit to solve our hook issues. It is a multi-language package manager for pre-commit hooks.";"pre-commit is specifically designed to not require root access."
- 失败判定的原文:"The hook must exit nonzero on failure or modify files." → 格式化类 hook 改文件即算失败,配合
--show-diff-on-failure使用。 - 四步 Quick start:
pre-commit --version→ 写.pre-commit-config.yaml(可pre-commit sample-config生成骨架)→pre-commit install(输出 "pre-commit installed at .git/hooks/pre-commit")→pre-commit run --all-files(对存量代码跑一遍,官网建议 "it's usually a good idea to run the hooks against all of the files when adding new hooks")。 - Windows 直接相关的原文注记(来源 7):
- python hook 平台支持:"python hooks work without any system-level dependencies. It has been tested on linux, macOS, windows, and cygwin."
language_version的 Windows 翻译:"on windows the pep394 name will be translated into a py launcher call for portability. So continue to use names likepython3(py -3) orpython3.6(py -3.6) even on windows."init-templatedir的 PowerShell 写法:pre-commit init-templatedir $HOME\.git-template(cmd 用%HOMEPATH%)。- 临时跳过单个 hook:
SKIP环境变量(SKIP=flake8 git commit -m "foo"),比--no-verify全跳更精细。
- 配置层关键项(来源 7):
default_install_hook_types: [pre-commit, pre-push, commit-msg]决定pre-commit install装哪几个 hook;default_language_version统一 python 版本;stages: [manual]定义"不自动触发、只手动跑"的钩子;CI 用法即pre-commit run --all-files。 repo: local钩子允许把项目内命令(如uv run pytest)挂进 pre-commit(来源 7:local hooks 适用于 "Hooks require state that is only present in a built artifact of your repository")。
3.7 pre-commit-hooks:Windows 专属防线(官方仓库)
来源 9 原文定义,逐条摘录:
| hook | 官方原文/摘要 |
|---|---|
check-case-conflict | "Check for files with names that would conflict on a case-insensitive filesystem like MacOS HFS+ or Windows FAT." |
check-illegal-windows-names | "flags files that cannot be created on Windows"(如 aux.py、con.py 等保留名) |
destroyed-symlinks | 捕捉"符号链接退化成内容为指向路径的普通文件"——"a common problem on Windows" |
mixed-line-ending | "Replaces or checks mixed line ending.";强制替换为 LF 时官方警告 "This option isn't compatible with git setup check-in LF check-out CRLF",因为 git smudge 会在 hook 跑完后又把换行改回去 |
end-of-file-fixer | "Makes sure files end in a newline and only a newline." |
check-toml / check-yaml | "Attempts to load all TOML/yaml files to verify syntax." |
3.8 第三方观点佐证(pydevtools.com, Tim Hopper, 2024-12)
- 对 Astral 的评价:"The team at Astral has been doing groundbreaking work in the Python tooling space."
- 对生态的判断:"The things people complain about (e.g. installing Python and packaging) are mostly solved problems."——即工具问题已解决,剩下的是把它自动化、模板化。
- 对模板本身的冷静提醒:"Building and maintaining a robust template requires considerable effort."——模板不是一次性的,要跟上工具版本。
- 该文用 mypy 而非 Pyright(并称在等 Astral 出类型检查器),与 Reddit 检索结果"mypy + pyright 二选一即可"一致:本模板选 Pyright 的理由是 pre-commit 集成路径(pyright-python)文档明确、VS Code(Pylance) 同引擎、配置语义与 VSC 零漂移。
4. Windows 专属要点汇总(全部有出处)
- uv 安装:PowerShell 用
irm … install.ps1 | iex(配-ExecutionPolicy ByPass),或winget install --id=astral-sh.uv -e,或 Scoop(来源 2)。 - venv 激活:PowerShell 下
.venv\Scripts\activate(来源 1/3 原文给出该路径)。若遇脚本执行策略限制,官方 uv 安装脚本自身的处理方式就是-ExecutionPolicy ByPass;venv 激活脚本被拦时的通用解法Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser属于社区常识,未在本次抓取页面中验证,特此标注。 uv run优先于激活:Windows 上最容易踩的就是"激活失败就放弃"。文档语义(来源 1)保证uv run每次自动校验并同步环境,等价于"永远在正确的 venv 里"。模板的 hook entry 全部用uv run前缀正是基于此。- py launcher:pre-commit 的
language_version在 Windows 上自动把python3.x翻译成py -3.x调用(来源 7 原文),所以配置里照写python3.12即可,不要写 Windows 特有写法。 - 大小写不敏感文件系统:加
check-case-conflict(来源 9);Git for Windows 默认core.ignorecase=true,文件名大小写冲突在 Windows 上无感、推到 Linux CI 才炸。 - Windows 保留文件名:加
check-illegal-windows-names(来源 9),防aux.py/con.py这类在 Windows 上根本建不出来的文件名入库。 - 符号链接退化:Windows 上 clone 含 symlink 的仓库常见"链接变文本文件",加
destroyed-symlinks(来源 9)。 - 换行(最大的坑):来源 9 明确警告
mixed-line-ending强制替换与 "check-in LF check-out CRLF" 的 git 配置互斥。工程上稳定的组合是:仓库提交.gitattributes统一eol=lf(文本文件),.bat/.cmd/.ps1保留 CRLF——这是我的综合建议(文档只给了警告与机制,未给完整 .gitattributes),并在模板第 6 节给出。 - init-templatedir:PowerShell 下
pre-commit init-templatedir $HOME\.git-template(来源 7 原文),想让所有新 clone 的仓库自动带 hook 时用。 - pyright 的 Node 依赖:Windows 上若没装 Node,pyright CLI 会现场下载(来源 6);国内网络环境建议
pip install pyright[nodejs](nodejs-wheel 走 pip 源,比 nodeenv 稳)或预先装 Node,并用PYRIGHT_PYTHON_CACHE_DIR等变量控制缓存位置。 - Windows Store Python 的 PATH 问题:WebSearch 摘要显示有"Store 版 Python 3.11 + pre-commit 3.3.3 装不上 hook"的社区讨论(来源线索 10),未深读原帖;规避方式是安装 python.org 发行版或干脆全用 uv 管理的 Python(
uv python install),避免 PATH 上多解释器打架。
5. 结论:可复制模板(Windows / PowerShell)
使用方式:逐块复制。所有命令在 PowerShell 下运行。版本号截至 2026-10-31,rev 以各仓库最新 tag 为准(pre-commit autoupdate 可自动升级)。5.1 安装工具链(一次性)
# uv:三选一
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
winget install --id=astral-sh.uv -e
scoop install uv
# (可选)uv 的 PowerShell 补全
if (!(Test-Path -Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
Add-Content -Path $PROFILE -Value '(& uv generate-shell-completion powershell) | Out-String | Invoke-Expression'5.2 初始化项目
uv init myproj
cd myproj
# uv init 已生成:pyproject.toml、README.md、.python-version、.gitignore、src/myproj/__init__.py
# dev 依赖一把装齐(写入 [dependency-groups] dev 组并更新 uv.lock)
uv add --dev pytest pytest-cov pre-commit pyright5.3 pyproject.toml(在 uv init 产物上追加)
[project]
name = "myproj"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
# uv init 默认给 ">=3.14";团队要兼容旧机可自行下调(我的取舍,非文档默认)
requires-python = ">=3.12"
dependencies = []
# ---- Ruff:lint + format ----
[tool.ruff]
line-length = 100
target-version = "py312"
[tool.ruff.lint]
# 官方默认 F/E/B/UP/RUF 之外只加 I(isort 等价物);需要更严再加 D(pydocstyle)
select = ["E", "F", "B", "UP", "RUF", "I"]
[tool.ruff.lint.isort]
known-first-party = ["myproj"]
# ---- Pyright:类型检查(也可拆成单独 pyrightconfig.json,优先级更高) ----
[tool.pyright]
include = ["src", "tests"]
pythonVersion = "3.12"
typeCheckingMode = "standard" # off/basic/standard/strict,默认 standard
venvPath = "." # pyright-python README 对 pre-commit 场景的推荐写法
venv = ".venv" # uv 的 venv 固定在项目根,全队路径一致
# ---- pytest ----
[tool.pytest.ini_options]
minversion = "8.0"
testpaths = ["tests"]
addopts = "-ra --strict-markers" # --strict-markers 防止自定义 marker 拼错静默通过
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
]
# filterwarnings = ["error"] # 严格团队再开:警告即失败
# ---- 依赖组(uv add --dev 会自动维护) ----
[dependency-groups]
dev = [
"pytest>=8.3",
"pytest-cov>=5.0",
"pre-commit>=4.0",
"pyright>=1.1.414",
]5.4 .pre-commit-config.yaml(项目根,全新文件)
# pre-commit >= 4.4.0 才支持 language: unsupported;旧版请写 language: system
default_install_hook_types: [pre-commit, pre-push]
default_language_version:
# Windows 上 pre-commit 会自动翻译成 py -3.12 调用(官方文档原文)
python: python3.12
repos:
# ① 通用卫生检查(Windows 防线 + 文件尾/空白)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0 # 2026-10-31 经 git ls-remote 核实的最新 tag
hooks:
- id: check-case-conflict # 大小写冲突(Windows/FAT 无感、CI 才炸)
- id: check-illegal-windows-names # Windows 保留文件名
- id: destroyed-symlinks # 符号链接退化检测
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
# ② Ruff:lint(带自动修复)+ format
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.17.2 # Ruff 官方教程给出的 rev
hooks:
- id: ruff-check
args: [--fix]
- id: ruff-format
# ③ Pyright:类型检查(读 pyproject.toml 的 [tool.pyright])
- repo: https://github.com/RobertCraigie/pyright-python
rev: v1.1.414 # pyright-python README 示例 rev
hooks:
- id: pyright
# ④ pytest:挂 pre-push,不拖慢每次 commit(本模板的综合取舍)
- repo: local
hooks:
- id: pytest
name: pytest
entry: uv run pytest # uv run 保证锁文件与环境同步后再跑测试
language: unsupported # pre-commit <4.4.0 写 language: system
pass_filenames: false
always_run: true
stages: [pre-push]启用与首次全量跑:
uv run pre-commit install # 按 default_install_hook_types 装 pre-commit + pre-push 两个钩子
uv run pre-commit run --all-files # 存量代码先全量过一遍;改文件类 hook 失败后 git add 再跑
uv run pre-commit autoupdate # 日后一键升级所有 rev5.5 .gitattributes(项目根,全新文件;Windows 团队第一天就提交)
# 文本文件统一 LF 入库;脚本类保留 CRLF(综合建议:依据 mixed-line-ending 的
# 官方警告 "isn't compatible with git setup check-in LF check-out CRLF" 推出)
* text=auto
*.py text eol=lf
*.toml text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
*.md text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf5.6 命令速查(PowerShell)
uv sync # 按 uv.lock 精确还原环境(clone 后第一步)
uv add requests # 加运行依赖;uv add --dev pytest 加开发依赖
uv run myproj # 运行项目入口(自动校验锁文件+环境)
uv run pytest # 跑测试
uv run ruff check --fix && uv run ruff format # 手动 lint+format
uv run pyright # 手动类型检查
uv run pre-commit run --all-files # 全量过门禁
uv lock --upgrade-package requests # 定点升级某依赖
uv build # 构建 sdist/wheel 到 dist/
SKIP=pytest git commit -m "wip" # 临时跳过某个 hook(比 --no-verify 精细)6. 局限(作者承认的 + 我推断的)
- rev 会过时:
v0.17.2(ruff-pre-commit)、v1.1.414(pyright-python)、v6.0.0(pre-commit-hooks)都是抓取时点的值;官方文档自己也在 yaml 注释里写 "Ruff version."——模板必须配合pre-commit autoupdate使用。 - 端到端未实测:本子任务只做了文档精读与
git ls-remote核实,没有在真实 Windows 机器上执行uv init→pre-commit run --all-files全流程验证模板(无法在本环境中创建 uv 项目实测),模板中标注"综合建议/取舍"的块(.gitattributes、pytest 挂 pre-push、line-length=100)是经验性配置而非文档原文。 - Windows Store Python 问题未深读:检索摘要显示存在 Store 版 Python + pre-commit 的兼容问题讨论,但原帖未精读,只能给出规避建议而非确认性结论。
- pytest hook 的
language: unsupported:pre-commit 4.4.0 才引入该名字(官方注记 "previouslylanguage: system. the alias will be removed in a future version"),旧版本 pre-commit 会报不认识的 language。 - mypy vs Pyright 无定论:pydevtools.com 用 mypy、Reddit 共识是"二选一",Reddit 检索摘要明确提到 "running pyright *and* mypy is often overkill";本模板选 Pyright 是工程取舍(与 Pylance 同引擎),非社区唯一答案。
- pre-commit 不是 CI 的替代:官方文档明确 "consider running that in CI too"——hook 只守本地提交,CI 仍需
pre-commit run --all-files+uv run pytest作为最终门禁。 - uv 默认 Python 版本激进:抓取的 uv 文档中
uv init默认requires-python = ">=3.14",对存量 Windows 环境(公司里常见 3.10/3.11)偏激进,模板中手动下调到 3.12,需按团队实情改。
7. 对我的启发(可迁移原则)
- "配置集中 + 锁文件入库 + 自动同步入口"三件套是可维护性的最小闭环:uv.lock 入库(文档明说跨机器复现)+
uv run自动校验同步 + 所有工具配置收进一个 pyproject.toml——新机器从 clone 到可跑测试只剩两条命令(uv sync、uv run pytest)。我自己的项目脚本/工具链迁移时直接照此模式。 - 门禁分层:快的挂 pre-commit,慢的挂 pre-push,最重的留 CI:lint/format/类型是秒级,挂 pre-commit;pytest 分钟级,挂 pre-push 或 CI。不要把全量测试塞进每次 commit——这是"规则自动执行"与"开发流畅度"的平衡点。
- Windows 不该是二等公民,但有四道专属防线:check-case-conflict、check-illegal-windows-names、destroyed-symlinks、.gitattributes 换行策略——前三个是现成 hook,第四个必须第一天提交,否则 CRLF 问题会在第一个协作者加入时爆发。
- 包装器工具的"独立 venv 陷阱"具有普适性:pyright-python 在 pre-commit 的独立 venv 里看不到项目依赖(README 原文承认),解法是显式指回项目 venv(venvPath/venv)。凡是用 pre-commit 挂"需要项目环境上下文"的工具(pylint 同理,官方 local hooks 一节也点名了),都要检查它的 import 解析路径。
- 模板是负债不是资产:"Building and maintaining a robust template requires considerable effort."(pydevtools.com)——模板里的每个 rev 都是会腐烂的引用,
pre-commit autoupdate+uv lock --upgrade应写进团队例行操作,而不是等报错才升级。 - 写"可复制配置"时,每个版本号都要给核实方式:本次笔记对四个 rev/版本分别标注了出处(官方页面原文 / git ls-remote 实测),并统一加"过时风险"提示——这比给一堆无出处的版本号可信得多。