blob: d19c7a995b84ce84ff9d59a7155f671799ac6d4f [file] [log] [blame]
Wyatt Heplerb3ea9802021-02-23 09:46:09 -08001.. _module-pw_build-python:
2
3-------------------
4Python GN templates
5-------------------
6The Python build is implemented with GN templates defined in
Joe Ethierfbe66152021-03-31 16:02:36 -07007``pw_build/python.gni``. See the .gni file for complete usage documentation.
Wyatt Heplerb3ea9802021-02-23 09:46:09 -08008
9.. seealso:: :ref:`docs-python-build`
10
11pw_python_package
12=================
13The main Python template is ``pw_python_package``. Each ``pw_python_package``
14target represents a Python package. As described in
15:ref:`module-pw_build-python-target`, each ``pw_python_package`` expands to
16several subtargets. In summary, these are:
17
18- ``<name>`` - Represents the files themselves
19- ``<name>.lint`` - Runs static analysis
20- ``<name>.tests`` - Runs all tests for this package
21- ``<name>.install`` - Installs the package
22- ``<name>.wheel`` - Builds a Python wheel
23
Wyatt Heplerb85cda42021-04-07 13:13:15 -070024GN permits using abbreviated labels when the target name matches the directory
25name (e.g. ``//foo`` for ``//foo:foo``). For consistency with this, Python
26package subtargets are aliased to the directory when the target name is the
27same as the directory. For example, these two labels are equivalent:
28
29.. code-block::
30
31 //path/to/my_python_package:my_python_package.tests
32 //path/to/my_python_package:tests
33
Wyatt Heplerf6f74f42021-04-13 19:26:20 -070034The actions in a ``pw_python_package`` (e.g. installing packages and running
35Pylint) are done within a single GN toolchain to avoid duplication in
36multi-toolchain builds. This toolchain can be set with the
Joe Ethierfbe66152021-03-31 16:02:36 -070037``pw_build_PYTHON_TOOLCHAIN`` GN arg, which defaults to
38``$dir_pw_build/python_toolchain:python``.
Wyatt Heplerf6f74f42021-04-13 19:26:20 -070039
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080040Arguments
41---------
42- ``setup`` - List of setup file paths (setup.py or pyproject.toml & setup.cfg),
43 which must all be in the same directory.
Wyatt Heplerb85cda42021-04-07 13:13:15 -070044- ``generate_setup``: As an alternative to ``setup``, generate setup files with
45 the keywords in this scope. ``name`` is required. For example:
46
47 .. code-block::
48
49 generate_setup = {
50 name = "a_nifty_package"
51 version = "1.2a"
52 }
53
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080054- ``sources`` - Python sources files in the package.
55- ``tests`` - Test files for this Python package.
56- ``python_deps`` - Dependencies on other pw_python_packages in the GN build.
57- ``python_test_deps`` - Test-only pw_python_package dependencies.
58- ``other_deps`` - Dependencies on GN targets that are not pw_python_packages.
59- ``inputs`` - Other files to track, such as package_data.
Wyatt Heplerdcfcecf2021-03-01 08:36:19 -080060- ``proto_library`` - A pw_proto_library target to embed in this Python package.
Wyatt Heplerb85cda42021-04-07 13:13:15 -070061 ``generate_setup`` is required in place of setup if proto_library is used. See
Wyatt Heplerdcfcecf2021-03-01 08:36:19 -080062 :ref:`module-pw_protobuf_compiler-add-to-python-package`.
Wyatt Heplerc2ce5242021-03-17 08:42:14 -070063- ``static_analysis`` List of static analysis tools to run; ``"*"`` (default)
64 runs all tools. The supported tools are ``"mypy"`` and ``"pylint"``.
Wyatt Heplerb3ea9802021-02-23 09:46:09 -080065- ``pylintrc`` - Optional path to a pylintrc configuration file to use. If not
66 provided, Pylint's default rcfile search is used. Pylint is executed
67 from the package's setup directory, so pylintrc files in that directory
68 will take precedence over others.
69- ``mypy_ini`` - Optional path to a mypy configuration file to use. If not
70 provided, mypy's default configuration file search is used. mypy is
71 executed from the package's setup directory, so mypy.ini files in that
72 directory will take precedence over others.
73
74Example
75-------
76This is an example Python package declaration for a ``pw_my_module`` module.
77
78.. code-block::
79
80 import("//build_overrides/pigweed.gni")
81
82 import("$dir_pw_build/python.gni")
83
84 pw_python_package("py") {
85 setup = [ "setup.py" ]
86 sources = [
87 "pw_my_module/__init__.py",
88 "pw_my_module/alfa.py",
89 "pw_my_module/bravo.py",
90 "pw_my_module/charlie.py",
91 ]
92 tests = [
93 "alfa_test.py",
94 "charlie_test.py",
95 ]
96 python_deps = [
97 "$dir_pw_status/py",
98 ":some_protos.python",
99 ]
100 python_test_deps = [ "$dir_pw_build/py" ]
101 pylintrc = "$dir_pigweed/.pylintrc"
102 }
103
104pw_python_script
105================
106A ``pw_python_script`` represents a set of standalone Python scripts and/or
107tests. These files support all of the arguments of ``pw_python_package`` except
108those ``setup``. These targets can be installed, but this only installs their
109dependencies.
110
Wyatt Hepler473efe02021-05-04 14:15:16 -0700111``pw_python_script`` allows creating a
112:ref:`pw_python_action <module-pw_build-python-action>` associated with the
113script. To create an action, pass an ``action`` scope to ``pw_python_script``.
114If there is only a single source file, it serves as the action's ``script`` by
115default.
116
117An action in ``pw_python_script`` can always be replaced with a standalone
118``pw_python_action``, but using the embedded action has some advantages:
119
120- The embedded action target bridges the gap between actions and Python targets.
121 A Python script can be expressed in a single, concise GN target, rather than
122 in two overlapping, dependent targets.
123- The action automatically depends on the ``pw_python_script``. This ensures
124 that the script's dependencies are installed and the action automatically
125 reruns when the script's sources change, without needing to specify a
126 dependency, a step which is easy to forget.
127- Using a ``pw_python_script`` with an embedded action is a simple way to check
128 an existing action's script with Pylint or Mypy or to add tests.
129
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800130pw_python_group
131===============
132Represents a group of ``pw_python_package`` and ``pw_python_script`` targets.
133These targets do not add any files. Their subtargets simply forward to those of
134their dependencies.
135
Wyatt Heplerb3ea9802021-02-23 09:46:09 -0800136pw_python_requirements
137======================
138Represents a set of local and PyPI requirements, with no associated source
139files. These targets serve the role of a ``requirements.txt`` file.
Joe Ethierfbe66152021-03-31 16:02:36 -0700140
Michael Spang01faaf72021-06-09 22:38:40 -0400141When packages are installed by Pigweed, additional version constraints can be
142provided using the ``pw_build_PIP_CONSTRAINTS`` GN arg. This option should
143contain a list of paths to pass to the ``--constraint`` option of ``pip
144install``. This can be used to synchronize dependency upgrades across a project
145which facilitates reproducibility of builds.
146
147Note using multiple ``pw_python_requirements`` that install different versions
148of the same package will currently cause unpredictable results, while using
149constraints should have correct results (which may be an error indicating a
150conflict).
151
Joe Ethierfbe66152021-03-31 16:02:36 -0700152.. _module-pw_build-python-dist:
153
154---------------------
155Python distributables
156---------------------
157Pigweed also provides some templates to make it easier to bundle Python packages
158for deployment. These templates are found in ``pw_build/python_dist.gni``. See
159the .gni file for complete usage doclumentation.
160
161pw_python_wheels
162================
163Collects Python wheels for one or more ``pw_python_package`` targets, plus any
164additional ``pw_python_package`` targets they depend on, directly or indirectly.
165Note that this does not include Python dependencies that come from outside the
166GN build, like packages from PyPI, for example. Those should still be declared
167in the package's ``setup.py`` file as usual.
168
169Arguments
170---------
171- ``packages`` - List of ``pw_python_package`` targets whose wheels should be
172 included; their dependencies will be pulled in as wheels also.
173
174Wheel collection under the hood
175-------------------------------
176The ``.wheel`` subtarget of every ``pw_python_package`` generates a wheel
177(``.whl``) for the Python package. The ``pw_python_wheels`` template figures
178out which wheels to collect by traversing the ``pw_python_package_wheels``
179`GN metadata
Rob Mohr463700d2021-05-22 10:31:03 -0700180<https://gn.googlesource.com/gn/+/HEAD/docs/reference.md#var_metadata>`_ key,
Joe Ethierfbe66152021-03-31 16:02:36 -0700181which lists the output directory for each wheel.
182
183The ``pw_mirror_tree`` template is then used to collect wheels in an output
184directory:
185
186.. code-block::
187
188 import("$dir_pw_build/mirror_tree.gni")
189
190 pw_mirror_tree("my_wheels") {
191 path_data_keys = [ "pw_python_package_wheels" ]
192 deps = [ ":python_packages.wheel" ]
193 directory = "$root_out_dir/the_wheels"
194 }
195
196pw_python_zip_with_setup
197========================
198Generates a ``.zip`` archive suitable for deployment outside of the project's
199developer environment. The generated ``.zip`` contains Python wheels
200(``.whl`` files) for one or more ``pw_python_package`` targets, plus wheels for
201any additional ``pw_python_package`` targets in the GN build they depend on,
202directly or indirectly. Dependencies from outside the GN build, such as packages
203from PyPI, must be listed in packages' ``setup.py`` files as usual.
204
205The ``.zip`` also includes simple setup scripts for Linux,
206MacOS, and Windows. The setup scripts automatically create a Python virtual
207environment and install the whole collection of wheels into it using ``pip``.
208
209Optionally, additional files and directories can be included in the archive.
210
211Arguments
212---------
213- ``packages`` - A list of `pw_python_package` targets whose wheels should be
214 included; their dependencies will be pulled in as wheels also.
215- ``inputs`` - An optional list of extra files to include in the generated
216 ``.zip``, formatted the same way as the ``inputs`` argument to ``pw_zip``
217 targets.
218- ``dirs`` - An optional list of directories to include in the generated
219 ``.zip``, formatted the same was as the ``dirs`` argument to ``pw_zip``
220 targets.
221
222Example
223-------
224
225.. code-block::
226
227 import("//build_overrides/pigweed.gni")
228
229 import("$dir_pw_build/python_dist.gni")
230
231 pw_python_zip_with_setup("my_tools") {
232 packages = [ ":some_python_package" ]
233 inputs = [ "$dir_pw_build/python_dist/README.md > /${target_name}/" ]
234 }