
uv 的 project.scripts 配置生成的入口脚本在未激活虚拟环境时无法导入本地包,根本原因是脚本未将项目根目录加入 sys.path;需确保包已正确安装为可编辑模式,并验证模块路径结构与 pyproject.toml 中的 packages 或 include 配置一致。
uv 的 `project.scripts` 配置生成的入口脚本在未激活虚拟环境时无法导入本地包,根本原因是脚本未将项目根目录加入 `sys.path`;需确保包已正确安装为可编辑模式,并验证模块路径结构与 `pyproject.toml` 中的 `packages` 或 `include` 配置一致。
你遇到的问题非常典型:使用 uv pip install -e . 安装后,生成的脚本(如 .venv/bin/trap_download_obs.py)能正确调用 Python 解释器,却因 ModuleNotFoundError: No module named 'trapallada' 失败——这并非环境未“激活”,而是 Python 运行时无法定位你的本地包。
根本原因在于:uv(及标准 pip install -e)依赖 PEP 517 构建后生成的 .pth 文件或 egg-link 来让解释器识别开发版包。但若项目结构或配置不满足隐式发现规则,该机制就会失效。
✅ 正确解决方案分三步:
1. 显式声明包路径(关键!)
uv 默认不会自动推断包目录。你必须在 pyproject.toml 中明确指定源码位置。推荐使用 [[tool.uv.workspace.members]] 或更通用的 project.packages(兼容 PEP 621):
[project]
name = "trapallada"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"pandas>=2.2.3",
"plotly>=6.0.1",
]
# ✅ 显式声明包:告诉构建工具 'trapallada/' 是一个可导入的包
[project.packages]
trapallada = {from = "src"}
# 或者如果你的代码直接放在项目根目录(即 ./trapallada/),用:
# [project.packages]
# trapallada = {from = "."}⚠️ 注意:
[tool.uv] package = true不是标准配置项,uv 当前(v0.4+)并不识别该字段,应删除,避免误导。
2. 修正 project.scripts 命名规范
脚本名称应为简洁命令名(如 trap-download),而非带 .py 后缀的文件名。uv/pip 会自动生成无扩展名的可执行入口:
[project.scripts] "trap-download" = "trapallada.xsa.util:cl_download_observations" "trap-plot" = "trapallada.xsa.plot:main"
安装后即可直接运行:
# 无需 source 激活!只要 .venv/bin 在 PATH 中(推荐用 uv run) uv run trap-download --help # 或手动确保 PATH 包含 venv bin export PATH="./.venv/bin:$PATH" trap-download
3. 验证安装与路径
执行以下命令确认包已被正确识别为“可编辑安装”:
uv pip list | grep trapallada # 应显示 "trapallada 0.1.0 /path/to/your/project" python -c "import trapallada; print(trapallada.__file__)" # 应指向 ./trapallada/__init__.py
若仍报错,请检查:
-
trapallada/__init__.py是否存在(即使为空,也必须存在以标识为合法包); - 项目根目录下是否有
src/子目录?如有,确保project.packages指向src,且trapallada/位于src/内; - 运行
uv clean && uv pip install -e . --verbose查看构建日志中是否成功生成egg-link或.pth文件。
? 小技巧:开发阶段优先使用 uv run,它会自动激活环境并注入 sys.path,绕过脚本路径问题:
uv run python -m trapallada.xsa.util cl_download_observations --arg1 val
总结:project.scripts 脚本本身不负责环境激活,它依赖 Python 解释器能正确导入目标模块。确保 project.packages 显式声明、包结构合规、且安装方式为可编辑模式(-e),才是解决该问题的正交路径。

















