diff --git a/docs/packaging.md b/docs/packaging.md index 86ba81e477..b750db64f5 100755 --- a/docs/packaging.md +++ b/docs/packaging.md @@ -26,21 +26,84 @@ This rule is intended to be used as data dependency to py_wheel rule. | packages | List of Python packages to include in the distribution. Sub-packages are automatically included. | List of strings | optional | [] | + + +## py_wheel_rule + +
+py_wheel_rule(name, abi, author, author_email, classifiers, console_scripts, deps, description_file,
+              distribution, entry_points, extra_distinfo_files, extra_requires, homepage, license,
+              platform, python_requires, python_tag, requires, stamp, strip_path_prefixes, version)
+
+ +Internal rule used by the [py_wheel macro](/docs/packaging.md#py_wheel). + +These intentionally have the same name to avoid sharp edges with Bazel macros. +For example, a `bazel query` for a user's `py_wheel` macro expands to `py_wheel` targets, +in the way they expect. + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| abi | Python ABI tag. 'none' for pure-Python wheels. | String | optional | "none" | +| author | A string specifying the author of the package. | String | optional | "" | +| author_email | A string specifying the email address of the package author. | String | optional | "" | +| classifiers | A list of strings describing the categories for the package. For valid classifiers see https://pypi.org/classifiers | List of strings | optional | [] | +| console_scripts | Deprecated console_script entry points, e.g. {'main': 'examples.wheel.main:main'}.

Deprecated: prefer the entry_points attribute, which supports console_scripts as well as other entry points. | Dictionary: String -> String | optional | {} | +| deps | Targets to be included in the distribution.

The targets to package are usually py_library rules or filesets (for packaging data files).

Note it's usually better to package py_library targets and use entry_points attribute to specify console_scripts than to package py_binary rules. py_binary targets would wrap a executable script that tries to locate .runfiles directory which is not packaged in the wheel. | List of labels | optional | [] | +| description_file | A file containing text describing the package. | Label | optional | None | +| distribution | Name of the distribution.

This should match the project name onm PyPI. It's also the name that is used to refer to the package in other packages' dependencies. | String | required | | +| entry_points | entry_points, e.g. {'console_scripts': ['main = examples.wheel.main:main']}. | Dictionary: String -> List of strings | optional | {} | +| extra_distinfo_files | Extra files to add to distinfo directory in the archive. | Dictionary: Label -> String | optional | {} | +| extra_requires | List of optional requirements for this package | Dictionary: String -> List of strings | optional | {} | +| homepage | A string specifying the URL for the package homepage. | String | optional | "" | +| license | A string specifying the license of the package. | String | optional | "" | +| platform | Supported platform. Use 'any' for pure-Python wheel.

If you have included platform-specific data, such as a .pyd or .so extension module, you will need to specify the platform in standard pip format. If you support multiple platforms, you can define platform constraints, then use a select() to specify the appropriate specifier, eg:

platform = select({ "//platforms:windows_x86_64": "win_amd64", "//platforms:macos_x86_64": "macosx_10_7_x86_64", "//platforms:linux_x86_64": "manylinux2014_x86_64", }) | String | optional | "any" | +| python_requires | Python versions required by this distribution, e.g. '>=3.5,<3.7' | String | optional | "" | +| python_tag | Supported Python version(s), eg py3, cp35.cp36, etc | String | optional | "py3" | +| requires | List of requirements for this package. See the section on [Declaring required dependency](https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#declaring-dependencies) for details and examples of the format of this argument. | List of strings | optional | [] | +| stamp | Whether to encode build information into the wheel. Possible values:

- stamp = 1: Always stamp the build information into the wheel, even in [--nostamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) builds. This setting should be avoided, since it potentially kills remote caching for the target and any downstream actions that depend on it.

- stamp = 0: Always replace build information by constant values. This gives good build result caching.

- stamp = -1: Embedding of build information is controlled by the [--[no]stamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) flag.

Stamped targets are not rebuilt unless their dependencies change. | Integer | optional | -1 | +| strip_path_prefixes | path prefixes to strip from files added to the generated package | List of strings | optional | [] | +| version | Version number of the package. Note that this attribute supports stamp format strings (eg. 1.2.3-{BUILD_TIMESTAMP}) as well as 'make variables' (e.g. 1.2.3-$(VERSION)). | String | required | | + + + + +## PyWheelInfo + +
+PyWheelInfo(name_file, wheel)
+
+ +Information about a wheel produced by `py_wheel` + +**FIELDS** + + +| Name | Description | +| :------------- | :------------- | +| name_file | File: A file containing the canonical name of the wheel (after stamping, if enabled). | +| wheel | File: The wheel file itself. | + + ## py_wheel
-py_wheel(name, abi, author, author_email, classifiers, console_scripts, deps, description_file,
-         distribution, entry_points, extra_distinfo_files, extra_requires, homepage, license,
-         platform, python_requires, python_tag, requires, stamp, strip_path_prefixes, version)
+py_wheel(name, kwargs)
 
-A rule for building Python Wheels. +Builds a Python Wheel. Wheels are Python distribution format defined in https://www.python.org/dev/peps/pep-0427/. -This rule packages a set of targets into a single wheel. +This macro packages a set of targets into a single wheel. +It wraps the [py_wheel rule](#py_wheel_rule). Currently only pure-python wheels are supported. @@ -80,50 +143,12 @@ py_wheel( ``` -**ATTRIBUTES** - - -| Name | Description | Type | Mandatory | Default | -| :------------- | :------------- | :------------- | :------------- | :------------- | -| name | A unique name for this target. | Name | required | | -| abi | Python ABI tag. 'none' for pure-Python wheels. | String | optional | "none" | -| author | A string specifying the author of the package. | String | optional | "" | -| author_email | A string specifying the email address of the package author. | String | optional | "" | -| classifiers | A list of strings describing the categories for the package. For valid classifiers see https://pypi.org/classifiers | List of strings | optional | [] | -| console_scripts | Deprecated console_script entry points, e.g. {'main': 'examples.wheel.main:main'}.

Deprecated: prefer the entry_points attribute, which supports console_scripts as well as other entry points. | Dictionary: String -> String | optional | {} | -| deps | Targets to be included in the distribution.

The targets to package are usually py_library rules or filesets (for packaging data files).

Note it's usually better to package py_library targets and use entry_points attribute to specify console_scripts than to package py_binary rules. py_binary targets would wrap a executable script that tries to locate .runfiles directory which is not packaged in the wheel. | List of labels | optional | [] | -| description_file | A file containing text describing the package. | Label | optional | None | -| distribution | Name of the distribution.

This should match the project name onm PyPI. It's also the name that is used to refer to the package in other packages' dependencies. | String | required | | -| entry_points | entry_points, e.g. {'console_scripts': ['main = examples.wheel.main:main']}. | Dictionary: String -> List of strings | optional | {} | -| extra_distinfo_files | Extra files to add to distinfo directory in the archive. | Dictionary: Label -> String | optional | {} | -| extra_requires | List of optional requirements for this package | Dictionary: String -> List of strings | optional | {} | -| homepage | A string specifying the URL for the package homepage. | String | optional | "" | -| license | A string specifying the license of the package. | String | optional | "" | -| platform | Supported platform. Use 'any' for pure-Python wheel.

If you have included platform-specific data, such as a .pyd or .so extension module, you will need to specify the platform in standard pip format. If you support multiple platforms, you can define platform constraints, then use a select() to specify the appropriate specifier, eg:

platform = select({ "//platforms:windows_x86_64": "win_amd64", "//platforms:macos_x86_64": "macosx_10_7_x86_64", "//platforms:linux_x86_64": "manylinux2014_x86_64", }) | String | optional | "any" | -| python_requires | Python versions required by this distribution, e.g. '>=3.5,<3.7' | String | optional | "" | -| python_tag | Supported Python version(s), eg py3, cp35.cp36, etc | String | optional | "py3" | -| requires | List of requirements for this package. See the section on [Declaring required dependency](https://setuptools.readthedocs.io/en/latest/userguide/dependency_management.html#declaring-dependencies) for details and examples of the format of this argument. | List of strings | optional | [] | -| stamp | Whether to encode build information into the wheel. Possible values:

- stamp = 1: Always stamp the build information into the wheel, even in [--nostamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) builds. This setting should be avoided, since it potentially kills remote caching for the target and any downstream actions that depend on it.

- stamp = 0: Always replace build information by constant values. This gives good build result caching.

- stamp = -1: Embedding of build information is controlled by the [--[no]stamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) flag.

Stamped targets are not rebuilt unless their dependencies change. | Integer | optional | -1 | -| strip_path_prefixes | path prefixes to strip from files added to the generated package | List of strings | optional | [] | -| version | Version number of the package. Note that this attribute supports stamp format strings (eg. 1.2.3-{BUILD_TIMESTAMP}) as well as 'make variables' (e.g. 1.2.3-$(VERSION)). | String | required | | - - - - -## PyWheelInfo - -
-PyWheelInfo(name_file, wheel)
-
- -Information about a wheel produced by `py_wheel` - -**FIELDS** +**PARAMETERS** -| Name | Description | -| :------------- | :------------- | -| name_file | File: A file containing the canonical name of the wheel (after stamping, if enabled). | -| wheel | File: The wheel file itself. | +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | A unique name for this target. | none | +| kwargs | other named parameters passed to the underlying [py_wheel rule](#py_wheel_rule) | none | diff --git a/python/packaging.bzl b/python/packaging.bzl index 763d7c5486..3b0b016321 100644 --- a/python/packaging.bzl +++ b/python/packaging.bzl @@ -15,7 +15,7 @@ """Public API for for building wheels.""" load("//python/private:py_package.bzl", "py_package_lib") -load("//python/private:py_wheel.bzl", "py_wheel_lib", _PyWheelInfo = "PyWheelInfo") +load("//python/private:py_wheel.bzl", _PyWheelInfo = "PyWheelInfo", _py_wheel = "py_wheel") # Re-export as public API PyWheelInfo = _PyWheelInfo @@ -31,51 +31,64 @@ This rule is intended to be used as data dependency to py_wheel rule. attrs = py_package_lib.attrs, ) -py_wheel = rule( - implementation = py_wheel_lib.implementation, - doc = """\ -A rule for building Python Wheels. +def py_wheel(name, **kwargs): + """Builds a Python Wheel. -Wheels are Python distribution format defined in https://www.python.org/dev/peps/pep-0427/. + Wheels are Python distribution format defined in https://www.python.org/dev/peps/pep-0427/. -This rule packages a set of targets into a single wheel. + This macro packages a set of targets into a single wheel. + It wraps the [py_wheel rule](#py_wheel_rule). -Currently only pure-python wheels are supported. + Currently only pure-python wheels are supported. -Examples: + Examples: -```python -# Package some specific py_library targets, without their dependencies -py_wheel( - name = "minimal_with_py_library", - # Package data. We're building "example_minimal_library-0.0.1-py3-none-any.whl" - distribution = "example_minimal_library", - python_tag = "py3", - version = "0.0.1", - deps = [ - "//examples/wheel/lib:module_with_data", - "//examples/wheel/lib:simple_module", - ], -) + ```python + # Package some specific py_library targets, without their dependencies + py_wheel( + name = "minimal_with_py_library", + # Package data. We're building "example_minimal_library-0.0.1-py3-none-any.whl" + distribution = "example_minimal_library", + python_tag = "py3", + version = "0.0.1", + deps = [ + "//examples/wheel/lib:module_with_data", + "//examples/wheel/lib:simple_module", + ], + ) -# Use py_package to collect all transitive dependencies of a target, -# selecting just the files within a specific python package. -py_package( - name = "example_pkg", - # Only include these Python packages. - packages = ["examples.wheel"], - deps = [":main"], -) + # Use py_package to collect all transitive dependencies of a target, + # selecting just the files within a specific python package. + py_package( + name = "example_pkg", + # Only include these Python packages. + packages = ["examples.wheel"], + deps = [":main"], + ) -py_wheel( - name = "minimal_with_py_package", - # Package data. We're building "example_minimal_package-0.0.1-py3-none-any.whl" - distribution = "example_minimal_package", - python_tag = "py3", - version = "0.0.1", - deps = [":example_pkg"], -) -``` -""", - attrs = py_wheel_lib.attrs, -) + py_wheel( + name = "minimal_with_py_package", + # Package data. We're building "example_minimal_package-0.0.1-py3-none-any.whl" + distribution = "example_minimal_package", + python_tag = "py3", + version = "0.0.1", + deps = [":example_pkg"], + ) + ``` + + Args: + name: A unique name for this target. + **kwargs: other named parameters passed to the underlying [py_wheel rule](#py_wheel_rule) + """ + _py_wheel(name = name, **kwargs) + + # TODO(alexeagle): produce an executable target like this: + # py_publish_wheel( + # name = "{}.publish".format(name), + # wheel = name, + # # Optional: override the label for a py_binary that runs twine + # # https://twine.readthedocs.io/en/stable/ + # twine_bin = "//path/to:twine", + # ) + +py_wheel_rule = _py_wheel diff --git a/python/private/py_wheel.bzl b/python/private/py_wheel.bzl index 6d2c9b36bb..b2ecce9e2c 100644 --- a/python/private/py_wheel.bzl +++ b/python/private/py_wheel.bzl @@ -357,3 +357,15 @@ tries to locate `.runfiles` directory which is not packaged in the wheel. _other_attrs, ), ) + +py_wheel = rule( + implementation = py_wheel_lib.implementation, + doc = """\ +Internal rule used by the [py_wheel macro](/docs/packaging.md#py_wheel). + +These intentionally have the same name to avoid sharp edges with Bazel macros. +For example, a `bazel query` for a user's `py_wheel` macro expands to `py_wheel` targets, +in the way they expect. +""", + attrs = py_wheel_lib.attrs, +)