PEP 582
PEP 582 已被拒绝
这是一个已被拒绝的 PEP。然而,由于这个特性是 PDM 诞生的原因,PDM 将继续保留对它的支持。我们建议改用虚拟环境。
通过PEP 582,依赖项将被安装到项目根目录下的__pypackages__
目录中。当全局启用 PEP 582时,你还可以使用项目解释器直接运行脚本。
如果项目解释器是一个普通的 Python,此模式将被启用。
此外,在首次在机器上使用的项目中,如果它包含一个空的__pypackages__
目录,PEP 582 将自动启用,并且不会创建 virtualenv。
全局启用 PEP 582
要使 Python 解释器了解 PEP 582 包,需要将pdm/pep582/sitecustomize.py
添加到 Python 库搜索路径中。
Windows
只需执行pdm --pep582
,环境变量将自动更改。不要忘记重新启动终端会话以生效。
Mac 和 Linux
pdm --pep582 [<SHELL>]
可以打印出更改环境变量的命令。如果未给出<SHELL>
,PDM 将基于一些猜测选择一个。
你可以运行eval "$(pdm --pep582)"
来执行该命令。
你可能希望在.bash_profile
(或类似的配置文件)中写入一行,以便在登录时生效。例如,在 bash 中,你可以这样做:
pdm --pep582 >> ~/.bash_profile
再一次,不要忘记重新启动终端会话以生效。
如何实现?
感谢 Python 启动时的站点包加载。通过执行 PDM 附带的sitecustomize.py
,可以修改sys.path
。解释器可以搜索目录中最近的___pypackage__
文件夹,并将其添加到sys.path
变量中。
配置 IDE 以支持 PEP 582
现在大多数 IDE 中没有内置支持或插件用于 PEP 582,你需要手动配置你的工具。
PyCharm
将__pypackages__/<major.minor>/lib
标记为源代码根目录。
然后,选择一个具有相同<major.minor>
版本的 Python 安装作为Python 解释器。
此外,如果你想使用环境中的工具(例如pytest
),你必须将__pypackages__/<major.minor>/bin
目录添加到相应运行/调试配置中的PATH
变量。
VSCode
在.vscode/settings.json
的顶层字典中添加以下两个条目:
{
"python.autoComplete.extraPaths": ["__pypackages__/<major.minor>/lib"],
"python.analysis.extraPaths": ["__pypackages__/<major.minor>/lib"]
}
这个文件可以使用插件pdm-vscode自动生成。
全局启用 PEP582,并确保 VSCode 使用你启用 PEP582 的相同用户和 shell 运行。
Neovim
如果使用nvim-lsp与pyright,并且希望将你的__pypackages__
目录添加到路径中,你可以将它添加到项目的pyproject.toml
中。
[tool.pyright]
extraPaths = ["__pypackages__/<major.minor>/lib/"]
Emacs
你有几个选项,但基本上你将想要告诉 LSP 客户端将__pypackages__
添加到它查看的路径中。这里有一些可用的选项:
使用 pyproject.toml
和 pyright
将此添加到项目的pyproject.toml
中:
[tool.pyright]
extraPaths = ["__pypackages__/<major.minor>/lib/"]
eglot + pyright
使用pyright和eglot(包含在 Emacs 29 中),将以下内容添加到你的配置中:
(defun get-pdm-packages-path ()
"For the current PDM project, find the path to the packages."
(let ((packages-path (string-trim (shell-command-to-string "pdm info --packages"))))
(concat packages-path "/lib")))
(defun my/eglot-workspace-config (server)
"For the current PDM project, dynamically generate a python lsp config."
`(:python.analysis (:extraPaths ,(vector (get-pdm-packages-path)))))
(setq-default eglot-workspace-configuration #'my/eglot-workspace-config)
你将需要全局安装 pyright,或者在项目中安装(可能作为开发依赖)。你可以使用以下命令添加:
pdm add --dev --group devel pyright
LSP-Mode + lsp-python-ms
以下是如何在 Emacs 中使用lsp-python-ms使 PDM 工作的示例代码片段。由@linw1995贡献。
;; TODO: Cache result
(defun linw1995/pdm-get-python-executable (&optional dir)
(let ((pdm-get-python-cmd "pdm info --python"))
(string-trim
(shell-command-to-string
(if dir
(concat "cd "
dir
" && "
pdm-get-python-cmd)
pdm-get-python-cmd)))))
(defun linw1995/pdm-get-packages-path (&optional dir)
(let ((pdm-get-packages-cmd "pdm info --packages"))
(concat (string-trim
(shell-command-to-string
(if dir
(concat "cd "
dir
" && "
pdm-get-packages-cmd)
pdm-get-packages-cmd)))
"/lib")))
(use-package lsp-python-ms
:ensure t
:init (setq lsp-python-ms-auto-install-server t)
:hook (python-mode
. (lambda ()
(setq lsp-python-ms-python-executable (linw1995/pdm-get-python-executable))
(setq lsp-python-ms-extra-paths (vector (linw1995/pdm-get-packages-path)))
(require 'lsp-python-ms)
(lsp)))) ; or lsp-deferred