(八)把源代码和测试放进项目
1. 项目目录与依赖方向
后续测试共用下面的 quality_project。src/bookdata 是第五章已经讲过的格式读写、记录校验和 SQLite 实现,完整文件已放在配套项目中;src/readingapp 负责本章的配置、统计、日志与入口。测试导入这些模块,业务模块不导入测试。
quality_project/
├── pyproject.toml
├── uv.lock
├── requirements-dev.txt
├── .gitignore
├── .vscode/launch.json
├── src/
│ ├── bookdata/ 第五章的 Book、格式转换与 Library
│ └── readingapp/
│ ├── __init__.py
│ ├── __main__.py
│ ├── stats.py
│ ├── config.py
│ ├── services.py
│ ├── logging_setup.py
│ └── cli.py
├── tests/
│ ├── conftest.py
│ ├── unit/
│ ├── integration/
│ └── e2e/
└── tools/check.py
src 是存放源码的目录名,不是导入路径的一部分;代码写 from readingapp.stats import count_met。tests/unit 检查小函数,tests/integration 检查格式、文件与数据库协作,tests/e2e 启动独立进程,检查真实命令行结果。目录表示观察范围,同一个行为可以在不同范围内留下互补的检查。
2. 用可编辑安装建立导入关系
进入 quality_project。项目根目录的 pyproject.toml 同时保存包信息、构建方式和工具配置:
# 项目文件:quality_project/pyproject.toml
# setuptools 从 src 寻找包;开发工具放入 dev 依赖组。
[build-system]
requires = ["setuptools>=80,<83"]
build-backend = "setuptools.build_meta"
[project]
name = "reading-log-notes"
version = "0.1.0"
description = "Python 学习笔记的书籍库与测试示例"
requires-python = ">=3.12,<3.13"
dependencies = []
[project.scripts]
reading-log = "readingapp.cli:main"
[dependency-groups]
dev = ["pytest>=9.1,<10", "ruff>=0.14,<1", "mypy>=1.18,<3", "build>=1.3,<2"]
[tool.setuptools.packages.find]
where = ["src"]
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-ra --import-mode=importlib"
[tool.ruff]
target-version = "py312"
line-length = 100
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "I"]
[tool.mypy]
python_version = "3.12"
files = ["src/readingapp/config.py", "src/readingapp/stats.py"]
strict = true[project] 的名字是安装分发名,导入名仍为 readingapp 和 bookdata。[build-system] 指定由哪个工具把源码组织成可安装的包,[project.scripts] 建立 reading-log 命令并调用 main。末尾几组 [tool...] 是对应工具的配置,稍后逐项使用。
使用 uv 路线:
# 配套项目已有锁定文件,按记录重建环境,再核对导入位置。
uv sync --locked
uv run python -c "import readingapp; print(readingapp.__file__)"
结果指向本项目的 src/readingapp/__init__.py。项目有构建配置时,uv sync 默认把当前项目以可编辑方式安装进 .venv。改动源码后,新启动的解释器读到这份源码;更改依赖或命令入口后,再同步环境。--locked 检查声明与锁定记录一致,不一致时提示错误。uv 的锁定与同步
使用 pip 路线:
# Windows PowerShell:新建环境,安装当前项目与配套的开发依赖快照。
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .
.\.venv\Scripts\python.exe -m pip install -r requirements-dev.txt
.\.venv\Scripts\python.exe -c "import readingapp; print(readingapp.__file__)"
-e . 表示可编辑安装当前目录的项目。普通 pip install . 会构建并安装一份包,修改本地源码后需要重新安装。src 布局让未安装的项目不会仅凭当前目录就找到业务包,能更早暴露“代码只在某个目录能导入”的问题。pip 本地项目安装、src 布局
在 macOS/Linux 中使用 .venv/bin/python,激活后两条路线都可以写 python -m pytest。后文命令中的 uv run 表示选用 uv 管理的项目环境;pip 路线用已激活的 python -m ... 运行相同工具。