Python pdm 的 PEP 582 本地包支持

6次阅读

不用手动创建,pdm 会自动管理 __pypackages__,但需项目根目录下有 pdm.toml 或 pyproject.toml 且启用 pep 582;手动创建易引发冲突。

Python pdm 的 PEP 582 本地包支持

PEP 582 的 __pypackages__ 目录到底要不要手动创建

不用,pdm 会自动管理 __pypackages__,但前提是项目根目录下有 pdm.tomlpyproject.toml(且已启用 PEP 582)。手动建目录、放包、改 pythonPATH 是旧思路,现在反而容易冲突。

常见错误现象:ModuleNotFoundError 即使包已安装;或 import 成功但 ide 提示未解析 —— 很可能是没激活 PEP 582,或终端没加载 pdm 的 shell hook。

  • 确认已运行 pdm --pep582 <shell></shell>(如 pdm --pep582 bash),并把输出的 export PYTHONPATH=... 加入 shell 配置
  • pdm install 后检查是否生成了 __pypackages__/<cp3x>/lib</cp3x>cp311 等取决于你用的 Python 版本)
  • 不要在非项目目录下执行 python 脚本——PEP 582 只在当前目录向上查找 __pypackages__,跨目录不生效

为什么 python -m pip install 不走 PEP 582

因为 pip 本身不读取 __pypackages__,它只认 sys.path[0] 和传统 site-packages。用 pip 安装的包不会进 __pypackages__,也不会被 PEP 582 机制识别。

使用场景:想给当前项目装一个临时调试包,或需要指定 --find-links 源 —— 正确做法是用 pdm add --no-self 或直接 pdm add -e ./some-local-package

立即学习Python免费学习笔记(深入)”;

  • pdm add requests → 走 PEP 582,进 __pypackages__
  • python -m pip install requests → 进全局或 venv site-packages,对当前项目无效
  • IDE(如 VS Code)需配置 Python 解释器为项目根目录下的 .pdm-python,否则即使 shell 里能 import,编辑器仍报错

pdm run 和直接 python 的行为差异

pdm run 会自动注入 __pypackages__PYTHONPATH,并确保使用项目锁定的 Python 解释器;而裸 python 命令只依赖当前 shell 的 PYTHONPATH 和解释器版本,极易错配。

性能影响几乎为零,但兼容性风险明显:比如项目锁的是 python 3.11,你本地默认是 3.12,裸 python 就可能因字节码不兼容报 Bad magic number

  • 脚本执行统一用 pdm run python script.py,别图省事写 python script.py
  • pdm run继承 pdm 的环境变量,包括 PYTHONPATH 注入逻辑,也支持 --help 查参数
  • CI/CD 中若用 python -m pytest,应改为 pdm run pytest,否则测试可能漏掉本地包依赖

windows 下 PowerShell 的 PYTHONPATH 注入失败

PowerShell 默认禁止执行脚本,pdm --pep582 powershell 输出的是一个 .ps1 片段,直接粘贴执行会报错 ExecutionPolicy —— 这是最常被忽略的卡点。

不是 pdmbug,是 PowerShell 安全策略限制。绕过方法简单但必须显式操作:

  • 以管理员身份打开 PowerShell,运行 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
  • 然后执行 pdm --pep582 powershell | Out-String | Invoke-Expression
  • 验证:启动新 PowerShell,运行 echo $env:PYTHONPATH,应看到含 __pypackages__ 的路径

复杂点在于,VS Code 的集成终端可能用的是旧会话,改完策略后要重启终端,否则 import 依然失败。

text=ZqhQzanResources