uv项目管理

uv提供了完整的项目管理功能,从项目初始化到依赖管理,再到构建和发布。本章将详细介绍如何使用uv高效地管理Python项目生命周期。

项目管理基础概念

现代Python项目管理涉及多个方面,uv通过标准化的项目结构和配置文件来简化这一过程:

  • 项目初始化:快速创建标准项目结构
  • 依赖管理:声明式依赖管理,支持生产环境和开发环境
  • 构建系统:现代化的构建和打包流程
  • 发布管理:简化包的发布流程

项目初始化

1. 基本项目创建

bash
# 创建新的Python项目
uv init myproject

# 创建项目并指定Python版本
uv init myproject --python 3.11

# 创建库项目(可发布的包)
uv init myproject --lib

# 创建应用项目(不可发布的应用)
uv init myproject --app

# 创建项目并指定许可证
uv init myproject --license MIT

2. 项目结构

text
myproject/
├── src/
│   └── myproject/
│       ├── __init__.py
│       └── main.py
├── tests/
│   └── __init__.py
├── pyproject.toml
├── README.md
└── .python-version

3. 高级初始化选项

bash
# 在现有目录中初始化项目
cd myproject
uv init

# 指定包名(与目录名不同)
uv init myproject --name my_package

# 不创建虚拟环境
uv init myproject --no-venv

# 指定项目描述
uv init myproject --description "我的Python项目"

# 指定作者信息
uv init myproject --author "张三" --email "zhangsan@example.com"

依赖管理

1. 添加依赖

bash
# 添加生产依赖
uv add requests

# 添加特定版本的依赖
uv add django==4.2.0

# 添加开发依赖
uv add pytest --dev

# 添加可选依赖
uv add redis --optional cache

# 添加URL依赖
uv add git+https://github.com/user/repo.git

# 添加本地依赖
uv add ./local-package

2. 移除依赖

bash
# 移除生产依赖
uv remove requests

# 移除开发依赖
uv remove pytest --dev

# 移除可选依赖
uv remove redis --optional cache

# 移除所有依赖(谨慎使用)
uv remove --all

3. 依赖同步

bash
# 同步pyproject.toml中的依赖到虚拟环境
uv sync

# 同步并创建虚拟环境(如果不存在)
uv sync --all-extras

# 同步开发依赖
uv sync --dev

# 同步特定可选依赖
uv sync --extra cache

# 强制重新同步
uv sync --force

pyproject.toml配置文件

1. 基本项目配置

toml
[project]
name = "myproject"
version = "0.1.0"
description = "我的Python项目"
authors = [
    {name = "张三", email = "zhangsan@example.com"}
]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.8"
dependencies = [
    "requests>=2.25.0",
    "flask>=2.0.0"
]

[project.optional-dependencies]
dev = [
    "pytest>=6.0",
    "black>=21.0",
    "flake8>=3.9"
]
test = [
    "pytest>=6.0",
    "pytest-cov>=2.12"
]

2. 构建系统配置

toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project.scripts]
myproject = "myproject.main:main"

[project.gui-scripts]
myproject-gui = "myproject.gui:main"

[project.entry-points."console_scripts"]
myproject-cli = "myproject.cli:main"

3. uv工具配置

toml
[tool.uv]
python-preference = "managed"
python-downloads = "automatic"
default-index = "https://pypi.tuna.tsinghua.edu.cn/simple/"

[tool.uv.pip]
index-url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
extra-index-url = ["https://pypi.org/simple/"]
trusted-host = ["pypi.tuna.tsinghua.edu.cn"]

[tool.uv.workspace]
members = ["packages/*"]

项目构建和打包

1. 构建分发包

bash
# 构建源码分发包
uv build

# 构建wheel包
uv build --wheel

# 构建源码和wheel包
uv build --sdist --wheel

# 指定输出目录
uv build --out-dir ./dist

# 检查构建结果
uv build --check

2. 包验证

bash
# 验证包的元数据
uv publish --dry-run

# 检查包的安全性
uv pip audit

# 验证包的完整性
uv pip check

项目发布

1. 发布到PyPI

bash
# 发布到TestPyPI(测试)
uv publish --repository testpypi

# 发布到PyPI(正式)
uv publish

# 指定仓库URL
uv publish --repository-url https://upload.pypi.org/legacy/

# 使用API令牌
uv publish --token YOUR_API_TOKEN

# 发布特定文件
uv publish dist/myproject-0.1.0-py3-none-any.whl

2. 发布配置

toml
[tool.uv.publish]
repository = "https://upload.pypi.org/legacy/"
username = "__token__"
# password应通过环境变量或.keyring设置

工作区管理

1. 创建工作区

toml
# pyproject.toml (根目录)
[tool.uv.workspace]
members = [
    "packages/*",
    "tools/*"
]

# packages/package-a/pyproject.toml
[project]
name = "package-a"
version = "0.1.0"
dependencies = [
    "package-b"  # 工作区内依赖
]

2. 工作区操作

bash
# 在工作区所有成员中运行命令
uv run --workspace pytest

# 在工作区中同步所有依赖
uv sync --workspace

# 在工作区中添加依赖到所有成员
uv add --workspace requests

# 构建工作区中的所有包
uv build --workspace

项目模板和脚手架

1. 自定义项目模板

bash
# 使用自定义模板创建项目
uv init myproject --template https://github.com/user/template.git

# 使用本地模板
uv init myproject --template ./templates/my-template

# 指定模板参数
uv init myproject --template my-template --param key=value

2. 模板配置

toml
# template.toml
[template]
name = "My Project Template"
description = "一个标准的Python项目模板"

[template.variables]
project_name = { prompt = "项目名称", default = "my-project" }
author_name = { prompt = "作者姓名", default = "Anonymous" }
python_version = { prompt = "Python版本", default = "3.11" }

[template.conditions]
include_cli = { prompt = "包含CLI工具?", default = false }

项目最佳实践

1. 项目结构最佳实践

text
myproject/
├── src/
│   └── myproject/
│       ├── __init__.py
│       ├── main.py
│       └── utils/
│           ├── __init__.py
│           └── helpers.py
├── tests/
│   ├── __init__.py
│   ├── test_main.py
│   └── test_utils.py
├── docs/
│   └── README.md
├── scripts/
│   └── deploy.sh
├── pyproject.toml
├── .gitignore
├── .python-version
└── Makefile

2. 依赖管理最佳实践

toml
[project]
# 使用范围版本约束
dependencies = [
    "requests>=2.25.0,<3.0.0",
    "flask>=2.0.0,<3.0.0"
]

[project.optional-dependencies]
# 分离不同类型依赖
test = [
    "pytest>=6.0",
    "pytest-cov>=2.12"
]
docs = [
    "sphinx>=4.0",
    "sphinx-rtd-theme>=1.0"
]
dev = [
    "black>=21.0",
    "flake8>=3.9",
    "mypy>=0.910"
]

3. 配置文件最佳实践

toml
[tool.uv]
# 配置默认行为
python-preference = "managed"
concurrent-downloads = 50
native-tls = true

[tool.black]
line-length = 88
target-version = ['py38']

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
addopts = "-v --tb=short"

[tool.mypy]
python_version = "3.8"
warn_return_any = true
warn_unused_configs = true

项目故障排除

1. 常见问题及解决方案

bash
# 依赖解析冲突
uv lock --clear

# 构建失败
uv build --no-build-isolation

# 虚拟环境问题
uv venv --force

# 缓存问题
uv cache clean

# 权限问题
uv init myproject --no-venv

2. 调试和诊断

bash
# 显示详细输出
uv sync --verbose

# 显示调试信息
uv sync --debug

# 生成诊断报告
uv debug info

# 检查项目配置
uv init --check