跳转至

构建钩子插件(Build hook plugins)


构建钩子提供了在构建过程的各个阶段执行的代码。有关 构建钩子配置的更多信息,请参阅文档。

知名第三方插件(Known third-party)

概述(Overview)

构建钩子会在每个选定的构建目标 版本 中运行。

初始化 阶段会在每次构建之前立即执行,而 终结 阶段则在每次构建之后立即执行。每个阶段都有机会查看或修改 构建数据

构建数据(Build data)

构建数据是一个简单的映射,其内容可以影响构建行为。哪些字段存在并被识别取决于每个构建目标。

以下字段始终存在并由构建系统本身识别:

字段 类型 描述
artifacts list[str] 这是一个额外的 artifact 模式 列表,通常只应附加内容
force_include dict[str, str] 这是一个额外的 强制包含路径 映射,若发生冲突,则优先使用此映射
build_hooks tuple[str, ...] 这是已配置构建钩子的名称的不可变序列,并与它们的执行顺序一致

Attention

虽然用户-facing TOML 选项使用连字符(hyphenated),但构建数据字段应使用下划线命名,以便插件可以将其用作有效的 Python 标识符。

注意事项(Notes)

在某些情况下,可能需要使用 force_include 而不是 artifacts。例如,假设你希望将 lib.so 直接安装到 site-packages 的根目录下,而项目定义了一个名为 src/foo。如果你创建 src/lib.so,则不会匹配,因为目录遍历是从 src/foo 开始的,而不是从 src 开始。在这种情况下,必须做以下操作之一:

build_data['force_include']['src/lib.so'] = 'src/lib.so'

或者

build_data['force_include']['/absolute/path/to/src/lib.so'] = 'src/lib.so'

BuildHookInterface

Example usage:

from hatchling.builders.hooks.plugin.interface import BuildHookInterface


class SpecialBuildHook(BuildHookInterface):
    PLUGIN_NAME = 'special'
    ...
from hatchling.plugin import hookimpl

from .plugin import SpecialBuildHook


@hookimpl
def hatch_register_build_hook():
    return SpecialBuildHook
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
class BuildHookInterface(Generic[BuilderConfigBound]):  # no cov
    """
    Example usage:

    ```python tab="plugin.py"
    from hatchling.builders.hooks.plugin.interface import BuildHookInterface


    class SpecialBuildHook(BuildHookInterface):
        PLUGIN_NAME = 'special'
        ...
    ```

    ```python tab="hooks.py"
    from hatchling.plugin import hookimpl

    from .plugin import SpecialBuildHook


    @hookimpl
    def hatch_register_build_hook():
        return SpecialBuildHook
    ```
    """

    PLUGIN_NAME = ''
    """The name used for selection."""

    def __init__(
        self,
        root: str,
        config: dict[str, Any],
        build_config: BuilderConfigBound,
        metadata: ProjectMetadata,
        directory: str,
        target_name: str,
        app: Application | None = None,
    ) -> None:
        self.__root = root
        self.__config = config
        self.__build_config = build_config
        self.__metadata = metadata
        self.__directory = directory
        self.__target_name = target_name
        self.__app = app

    @property
    def app(self) -> Application:
        """
        An instance of [Application](../utilities.md#hatchling.bridge.app.Application).
        """
        if self.__app is None:
            from hatchling.bridge.app import Application

            self.__app = cast(Application, Application().get_safe_application())

        return self.__app

    @property
    def root(self) -> str:
        """
        The root of the project tree.
        """
        return self.__root

    @property
    def config(self) -> dict[str, Any]:
        """
        The cumulative hook configuration.

        ```toml config-example
        [tool.hatch.build.hooks.<PLUGIN_NAME>]
        [tool.hatch.build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
        ```
        """
        return self.__config

    @property
    def metadata(self) -> ProjectMetadata:
        # Undocumented for now
        return self.__metadata

    @property
    def build_config(self) -> BuilderConfigBound:
        """
        An instance of [BuilderConfig](../utilities.md#hatchling.builders.config.BuilderConfig).
        """
        return self.__build_config

    @property
    def directory(self) -> str:
        """
        The build directory.
        """
        return self.__directory

    @property
    def target_name(self) -> str:
        """
        The plugin name of the build target.
        """
        return self.__target_name

    def dependencies(self) -> list[str]:  # noqa: PLR6301
        """
        A list of extra [dependencies](../../config/dependency.md) that must be installed
        prior to builds.

        !!! warning
            - For this to have any effect the hook dependency itself cannot be dynamic and
                must always be defined in `build-system.requires`.
            - As the hook must be imported to call this method, imports that require these
                dependencies must be evaluated lazily.
        """
        return []

    def clean(self, versions: list[str]) -> None:
        """
        This occurs before the build process if the `-c`/`--clean` flag was passed to
        the [`build`](../../cli/reference.md#hatch-build) command, or when invoking
        the [`clean`](../../cli/reference.md#hatch-clean) command.
        """

    def initialize(self, version: str, build_data: dict[str, Any]) -> None:
        """
        This occurs immediately before each build.

        Any modifications to the build data will be seen by the build target.
        """

    def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
        """
        This occurs immediately after each build and will not run if the `--hooks-only` flag
        was passed to the [`build`](../../cli/reference.md#hatch-build) command.

        The build data will reflect any modifications done by the target during the build.
        """

PLUGIN_NAME = '' class-attribute instance-attribute

The name used for selection.

__app = app instance-attribute

__build_config = build_config instance-attribute

__config = config instance-attribute

__directory = directory instance-attribute

__metadata = metadata instance-attribute

__root = root instance-attribute

__target_name = target_name instance-attribute

app: Application property

An instance of Application.

build_config: BuilderConfigBound property

An instance of BuilderConfig.

config: dict[str, Any] property

The cumulative hook configuration.

[tool.hatch.build.hooks.<PLUGIN_NAME>]
[tool.hatch.build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]
[build.hooks.<PLUGIN_NAME>]
[build.targets.<TARGET_NAME>.hooks.<PLUGIN_NAME>]

directory: str property

The build directory.

metadata: ProjectMetadata property

root: str property

The root of the project tree.

target_name: str property

The plugin name of the build target.

__init__(root: str, config: dict[str, Any], build_config: BuilderConfigBound, metadata: ProjectMetadata, directory: str, target_name: str, app: Application | None = None) -> None

Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def __init__(
    self,
    root: str,
    config: dict[str, Any],
    build_config: BuilderConfigBound,
    metadata: ProjectMetadata,
    directory: str,
    target_name: str,
    app: Application | None = None,
) -> None:
    self.__root = root
    self.__config = config
    self.__build_config = build_config
    self.__metadata = metadata
    self.__directory = directory
    self.__target_name = target_name
    self.__app = app

clean(versions: list[str]) -> None

This occurs before the build process if the -c/--clean flag was passed to the build command, or when invoking the clean command.

Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def clean(self, versions: list[str]) -> None:
    """
    This occurs before the build process if the `-c`/`--clean` flag was passed to
    the [`build`](../../cli/reference.md#hatch-build) command, or when invoking
    the [`clean`](../../cli/reference.md#hatch-clean) command.
    """

dependencies() -> list[str]

A list of extra dependencies that must be installed prior to builds.

Warning

  • For this to have any effect the hook dependency itself cannot be dynamic and must always be defined in build-system.requires.
  • As the hook must be imported to call this method, imports that require these dependencies must be evaluated lazily.
Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def dependencies(self) -> list[str]:  # noqa: PLR6301
    """
    A list of extra [dependencies](../../config/dependency.md) that must be installed
    prior to builds.

    !!! warning
        - For this to have any effect the hook dependency itself cannot be dynamic and
            must always be defined in `build-system.requires`.
        - As the hook must be imported to call this method, imports that require these
            dependencies must be evaluated lazily.
    """
    return []

finalize(version: str, build_data: dict[str, Any], artifact_path: str) -> None

This occurs immediately after each build and will not run if the --hooks-only flag was passed to the build command.

The build data will reflect any modifications done by the target during the build.

Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def finalize(self, version: str, build_data: dict[str, Any], artifact_path: str) -> None:
    """
    This occurs immediately after each build and will not run if the `--hooks-only` flag
    was passed to the [`build`](../../cli/reference.md#hatch-build) command.

    The build data will reflect any modifications done by the target during the build.
    """

initialize(version: str, build_data: dict[str, Any]) -> None

This occurs immediately before each build.

Any modifications to the build data will be seen by the build target.

Source code in backend/src/hatchling/builders/hooks/plugin/interface.py
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
    """
    This occurs immediately before each build.

    Any modifications to the build data will be seen by the build target.
    """