//python:packaging.bzl
Public API for for building wheels.
- rule py_package(name, deps=[], packages=[])
A rule to select all files in transitive dependencies of deps which belong to given set of Python packages.
This rule is intended to be used as data dependency to py_wheel rule.
- py_wheel(name, twine=None, twine_binary='@rules_python//tools/publish:twine', publish_args=[], **kwargs)
Builds a Python Wheel.
Wheels are Python distribution format defined in https://www.python.org/dev/peps/pep-0427/.
This macro packages a set of targets into a single wheel. It wraps the py_wheel rule.
Currently only pure-python wheels are supported.
Changed in version 1.4.0: From now on, an empty
requires_fileis treated as if it were omitted, resulting in a validMETADATAfile.Examples:
# 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"], ) 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"], )
To publish the wheel to PyPI, the twine package is required and it is installed by default on
bzlmodsetups. On legacyWORKSPACE,rules_pythondoesn’t providetwineitself (see https://github.com/bazel-contrib/rules_python/issues/1016), but you can install it withpip_parse, just like we do any other dependencies.Once you’ve installed twine, you can pass its label to the
twineattribute of this macro, to get a “[name].publish” target.Example:
py_wheel( name = "my_wheel", twine = "@publish_deps//twine", ... )
Now you can run a command like the following, which publishes to https://test.pypi.org/
% TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-*** \ bazel run --stamp --embed_label=1.2.4 -- \ //path/to:my_wheel.publish --repository testpypi
- Args:
name– A unique name for this target.twine– (default None)A label of the external location of the py_library target for twine
twine_binary– (default “@rules_python//tools/publish:twine”)A label of the external location of a binary target for twine.
publish_args– (default [])arguments passed to twine, e.g. [”–repository-url”, “https://pypi.my.org/simple/”]. These are subject to make var expansion, as with the
argsattribute. Note that you can also pass additional args to the bazel run command as in the example above.kwargs– other named parameters passed to the underlying py_wheel rule
- rule py_wheel_dist(name, out, wheel=None)
Prepare a dist/ folder, following Python’s packaging standard practice.
See https://packaging.python.org/en/latest/tutorials/packaging-projects/#generating-distribution-archives which recommends a dist/ folder containing the wheel file(s), source distributions, etc.
This also has the advantage that stamping information is included in the wheel’s filename.
- Attributes:
A unique name for this target.
mandatory
name of the resulting directory
mandatory
wheel– (label) (default None)optional
Required providers:
PyWheelInfo
- rule py_wheel_rule(name, distribution, version, abi='none', author='', author_email='', classifiers=[], compress=True, config_settings={}, console_scripts={}, data_files={}, deps=[], description_content_type='', description_file=None, entry_points={}, extra_distinfo_files={}, extra_requires={}, extra_requires_files={}, homepage='', license='', platform='any', project_urls={}, python_requires='', python_tag='py3', requires=[], requires_file=None, stamp=-1, strip_path_prefixes=[], summary='')
Internal rule used by the py_wheel macro.
These intentionally have the same name to avoid sharp edges with Bazel macros. For example, a
bazel queryfor a user’spy_wheelmacro expands topy_wheeltargets, in the way they expect.- Attributes:
A unique name for this target.
mandatory
distribution– (str)Name of the distribution.
This should match the project name on PyPI. It’s also the name that is used to refer to the package in other packages’ dependencies.
Workspace status keys are expanded using
{NAME}format, for example:distribution = "package.{CLASSIFIER}"distribution = "{DISTRIBUTION}"
For the available keys, see https://bazel.build/docs/user-manual#workspace-status
mandatory
Version number of the package.
Note that this attribute supports stamp format strings as well as ‘make variables’. For example:
version = "1.2.3-{BUILD_TIMESTAMP}"version = "{BUILD_EMBED_LABEL}"version = "$(VERSION)"
Note that Bazel’s output filename cannot include the stamp information, as outputs must be known during the analysis phase and the stamp data is available only during the action execution.
The
py_wheelmacro produces a.dist-suffix target which creates adist/folder containing the wheel with the stamped name, suitable for publishing.See
py_wheel_distfor more info.mandatory
Python ABI tag. ‘none’ for pure-Python wheels.
optional
– (
str) (default “”)A string specifying the author of the package.
optional
– (
str) (default “”)A string specifying the email address of the package author.
optional
classifiers– (list[str]) (default [])A list of strings describing the categories for the package. For valid classifiers see https://pypi.org/classifiers
optional
compress– (bool) (default True)Enable compression of the final archive.
optional
config_settings– (dict[label,str]) (default {})Config settings to change for this target.
The keys are labels for settings, and the values are strings for the new value to use. Pass
Labelobjects or canonical label strings for the keys to ensure they resolve as expected (canonical labels start with@@and can be obtained by callingstr(Label(...))).Most
@rules_python//python/config_settingsettings can be used here, which allows, for example, making only a certainpy_binaryuse--boostrap_impl=script.Additional or custom config settings can be registered using the
add_transition_settingAPI. This allows, for example, forcing a particular CPU, or defining a custom setting thatselect()uses elsewhere to pick betweenpip.parsehubs. See the [How to guide on multiple versions of a library] for a more concrete example.Note
These values are transitioned on, so will affect the analysis graph and the associated memory overhead. The more unique configurations in your overall build, the more memory and (often unnecessary) re-analysis and re-building can occur. See https://bazel.build/extending/config#memory-performance-considerations for more information about risks and considerations.
Added in version 1.7.0.
optional
console_scripts– (dict[str,str]) (default {})Deprecated console_script entry points, e.g.
{'main': 'examples.wheel.main:main'}.Deprecated: prefer the
entry_pointsattribute, which supportsconsole_scriptsas well as other entry points.optional
data_files– (dict[label,str]) (default {})Any file that is not normally installed inside site-packages goes into the .data directory, named as the .dist-info directory but with the .data/ extension. Allowed paths: (“purelib”, “platlib”, “headers”, “scripts”, “data”)
optional
deps– (list[label]) (default [])Targets to be included in the distribution.
The targets to package are usually
py_libraryrules or filesets (for packaging data files).Note it’s usually better to package
py_librarytargets and useentry_pointsattribute to specifyconsole_scriptsthan to packagepy_binaryrules.py_binarytargets would wrap a executable script that tries to locate.runfilesdirectory which is not packaged in the wheel.optional
description_content_type– (str) (default “”)The type of contents in description_file. If not provided, the type will be inferred from the extension of description_file. Also see https://packaging.python.org/en/latest/specifications/core-metadata/#description-content-type
optional
description_file– (label) (default None)A file containing text describing the package.
optional
entry_points– (dict[str,list[str]]) (default {})entry_points, e.g.
{'console_scripts': ['main = examples.wheel.main:main']}.optional
extra_distinfo_files– (dict[label,str]) (default {})Extra files to add to distinfo directory in the archive.
optional
extra_requires– (dict[str,list[str]]) (default {})A mapping of extras options to lists of requirements (similar to
requires). This attribute is mutually exclusive withextra_requires_file.optional
extra_requires_files– (dict[label,str]) (default {})A mapping of requirements files (similar to
requires_file) to the name of an extras option This attribute is mutually exclusive withextra_requires.optional
A string specifying the URL for the package homepage.
optional
A string specifying the license of the package.
optional
platform– (str) (default “any”)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", })optional
project_urls– (dict[str,str]) (default {})A string dict specifying additional browsable URLs for the project and corresponding labels, where label is the key and url is the value. e.g
{{"Bug Tracker": "http://bitbucket.org/tarek/distribute/issues/"}}optional
python_requires– (str) (default “”)Python versions required by this distribution, e.g. ‘>=3.5,<3.7’
optional
python_tag– (str) (default “py3”)Supported Python version(s), eg
py3,cp35.cp36, etcoptional
requires– (list[str]) (default [])List of requirements for this package. See the section on Declaring required dependency for details and examples of the format of this argument. This attribute is mutually exclusive with
requires_file.optional
requires_file– (label) (default None)A file containing a list of requirements for this package. See the section on Declaring required dependency for details and examples of the format of this argument. This attribute is mutually exclusive with
requires.optional
Whether to encode build information into the wheel. Possible values:
stamp = 1: Always stamp the build information into the wheel, even in –nostamp 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 flag.
Stamped targets are not rebuilt unless their dependencies change.
optional
strip_path_prefixes– (list[str]) (default [])Path prefixes to strip from files added to the generated package. Prefixes are checked in order and only the first match will be used.
For example:
["foo", "foo/bar/baz"]will strip"foo/bar/baz/file.py"to"bar/baz/file.py"["foo/bar/baz", "foo"]will strip"foo/bar/baz/file.py"to"file.py"and"foo/file2.py"to"file2.py"
optional
A one-line summary of what the distribution does
optional