生命周期和钩子

作为任何 Python 可交付成果,您的项目将经历 Python 项目生命周期的不同阶段,PDM 提供命令来执行这些阶段所期望的任务。

它还提供了附加到这些步骤的钩子,允许:

  • 插件监听相同名称的[pdm.signals][pdm.signals]信号。
  • 开发人员定义同名的自定义脚本。

此外,在调用任何命令之前,都会发出 pre_invoke 信号,允许插件事先修改项目或选项。

内置命令当前分为 3 组:

您可能需要在安装和发布阶段之间执行一些经常性任务(家务管理、代码检查、测试…), 这就是为什么 PDM 允许您使用 用户脚本 定义自己的任务/阶段。

为了提供完全的灵活性,PDM 允许根据需求跳过一些钩子和任务

初始化

初始化阶段应在项目生命周期中仅发生一次,通过运行 pdm init 命令来初始化现有项目(提示填写 pyproject.toml 文件)。

它们触发以下钩子:

  • [post_init][pdm.signals.post_init]
  1. flowchart LR
  2. subgraph pdm-init [pdm init]
  3. direction LR
  4. post-init{{触发 post_init}}
  5. init --> post-init
  6. end

依赖管理

依赖管理对于开发人员能够工作并执行以下操作是必需的:

  • lock: 从 pyproject.toml 依赖项计算锁定文件。
  • sync: 从锁定文件同步(添加/删除/更新)PEP582 包,并以可编辑方式安装当前项目。
  • add: 添加依赖项
  • remove: 移除依赖项

所有这些步骤都可以直接使用以下命令:

  • pdm lock: 执行 lock 任务
  • pdm sync: 执行 sync 任务
  • pdm install: 执行 sync 任务,在需要时由 lock 前置执行
  • pdm add: 添加依赖要求,重新锁定然后同步
  • pdm remove: 移除依赖要求,重新锁定然后同步
  • pdm update: 从最新版本重新锁定依赖项然后同步

它们触发以下钩子:

  • [pre_install][pdm.signals.pre_install]
  • [post_install][pdm.signals.post_install]
  • [pre_lock][pdm.signals.pre_lock]
  • [post_lock][pdm.signals.post_lock]
  1. flowchart LR
  2. subgraph pdm-install [pdm install]
  3. direction LR
  4. subgraph pdm-lock [pdm lock]
  5. direction TB
  6. pre-lock{{触发 pre_lock}}
  7. post-lock{{触发 post_lock}}
  8. pre-lock --> lock --> post-lock
  9. end
  10. subgraph pdm-sync [pdm sync]
  11. direction TB
  12. pre-install{{触发 pre_install}}
  13. post-install{{触发 post_install}}
  14. pre-install --> sync --> post-install
  15. end
  16. pdm-lock --> pdm-sync
  17. end

切换 Python 版本

这是依赖管理中的一个特殊情况: 你可以使用 pdm use 切换当前 Python 版本 它将发出带有新 Python 解释器的 [post_use][pdm.signals.post_use] 信号。

  1. flowchart LR
  2. subgraph pdm-use [pdm use]
  3. direction LR
  4. post-use{{触发 post_use}}
  5. use --> post-use
  6. end

发布

一旦您准备好发布您的包/库,您将需要发布任务:

  • build: 构建/编译需要的资产,并将所有内容打包成 Python 包(sdist,wheel)
  • upload: 将包上传/发布到远程 PyPI 索引

所有这些步骤都可以通过以下命令获得:

它们触发以下钩子:

  • [pre_publish][pdm.signals.pre_publish]
  • [post_publish][pdm.signals.post_publish]
  • [pre_build][pdm.signals.pre_build]
  • [post_build][pdm.signals.post_build]
  1. flowchart LR
  2. subgraph pdm-publish [pdm publish]
  3. direction LR
  4. pre-publish{{触发 pre_publish}}
  5. post-publish{{触发 post_publish}}
  6. subgraph pdm-build [pdm build]
  7. pre-build{{触发 pre_build}}
  8. post-build{{触发 post_build}}
  9. pre-build --> build --> post-build
  10. end
  11. %% subgraph pdm-upload [pdm upload]
  12. %% pre-upload{{触发 pre_upload}}
  13. %% post-upload{{触发 post_upload}}
  14. %% pre-upload --> upload --> post-upload
  15. %% end
  16. pre-publish --> pdm-build --> upload --> post-publish
  17. end

执行将在第一次失败时停止,包括钩子。

用户脚本

用户脚本在它们自己的部分中有详细说明,但您应该知道:

  • 每个用户脚本可以定义一个 pre_*post_* 脚本,包括复合脚本。
  • 每次 run 执行将触发 [pre_run][pdm.signals.pre_run] 和 [post_run][pdm.signals.post_run] 钩子
  • 每次脚本执行将触发 [pre_script][pdm.signals.pre_script] 和 [post_script][pdm.signals.post_script] 钩子

给定以下 scripts 定义:

  1. [tool.pdm.scripts]
  2. pre_script = ""
  3. post_script = ""
  4. pre_test = ""
  5. post_test = ""
  6. test = ""
  7. pre_composite = ""
  8. post_composite = ""
  9. composite = {composite = ["test"]}

一个 pdm run test 将具有以下生命周期:

  1. flowchart LR
  2. subgraph pdm-run-test [pdm run test]
  3. direction LR
  4. pre-run{{触发 pre_run}}
  5. post-run{{触发 post_run}}
  6. subgraph run-test [test task]
  7. direction TB
  8. pre-script{{触发 pre_script}}
  9. post-script{{触发 post_script}}
  10. pre-test[执行 pre_test]
  11. post-test[执行 post_test]
  12. test[执行 test]
  13. pre-script --> pre-test --> test --> post-test --> post-script
  14. end
  15. pre-run --> run-test --> post-run
  16. end

pdm run composite 将具有以下:

  1. flowchart LR
  2. subgraph pdm-run-composite [pdm run composite]
  3. direction LR
  4. pre-run{{触发 pre_run}}
  5. post-run{{触发 post_run}}
  6. subgraph run-composite [composite task]
  7. direction TB
  8. pre-script-composite{{触发 pre_script}}
  9. post-script-composite{{触发 post_script}}
  10. pre-composite[执行 pre_composite]
  11. post-composite[执行 post_composite]
  12. subgraph run-test [test task]
  13. direction TB
  14. pre-script-test{{触发 pre_script}}
  15. post-script-test{{触发 post_script}}
  16. pre-test[执行 pre_test]
  17. post-test[执行 post_test]
  18. pre-script-test --> pre-test --> test --> post-test --> post-script-test
  19. end
  20. pre-script-composite --> pre-composite --> run-test --> post-composite --> post-script-composite
  21. end
  22. pre-run --> run-composite --> post-run
  23. end

跳过

可以使用 --skip 选项控制任何内置命令以及自定义用户脚本运行的任务和钩子。

它接受一个逗号分隔的钩子/任务名称列表来跳过, 以及预定义的 :all:pre:post 快捷方式, 分别跳过所有钩子、所有 pre_* 钩子和所有 post_* 钩子。 您也可以在 PDM_SKIP_HOOKS 环境变量中提供跳过列表, 但一旦提供了 --skip 参数,它将被覆盖。

给定前面的脚本块,运行 pdm run --skip=:pre,post_test composite 将产生以下简化的生命周期:

  1. flowchart LR
  2. subgraph pdm-run-composite [pdm run composite]
  3. direction LR
  4. post-run{{触发 post_run}}
  5. subgraph run-composite [composite task]
  6. direction TB
  7. post-script-composite{{触发 post_script}}
  8. post-composite[执行 post_composite]
  9. subgraph run-test [test task]
  10. direction TB
  11. post-script-test{{触发 post_script}}
  12. test --> post-script-test
  13. end
  14. run-test --> post-composite --> post-script-composite
  15. end
  16. run-composite --> post-run
  17. end