Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 1 | .. _module-pw_build-python: |
| 2 | |
| 3 | ------------------- |
| 4 | Python GN templates |
| 5 | ------------------- |
| 6 | The Python build is implemented with GN templates defined in |
| 7 | ``pw_build/python.gni``. That file contains the complete usage documentation. |
| 8 | |
| 9 | .. seealso:: :ref:`docs-python-build` |
| 10 | |
| 11 | pw_python_package |
| 12 | ================= |
| 13 | The main Python template is ``pw_python_package``. Each ``pw_python_package`` |
| 14 | target represents a Python package. As described in |
| 15 | :ref:`module-pw_build-python-target`, each ``pw_python_package`` expands to |
| 16 | several 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 Hepler | b85cda4 | 2021-04-07 13:13:15 -0700 | [diff] [blame] | 24 | GN permits using abbreviated labels when the target name matches the directory |
| 25 | name (e.g. ``//foo`` for ``//foo:foo``). For consistency with this, Python |
| 26 | package subtargets are aliased to the directory when the target name is the |
| 27 | same 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 Hepler | f6f74f4 | 2021-04-13 19:26:20 -0700 | [diff] [blame] | 34 | The actions in a ``pw_python_package`` (e.g. installing packages and running |
| 35 | Pylint) are done within a single GN toolchain to avoid duplication in |
| 36 | multi-toolchain builds. This toolchain can be set with the |
| 37 | ``pw_build_PYTHON_TOOLCHAIN`` GN arg, which defaults to a dummy toolchain. |
| 38 | |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 39 | Arguments |
| 40 | --------- |
| 41 | - ``setup`` - List of setup file paths (setup.py or pyproject.toml & setup.cfg), |
| 42 | which must all be in the same directory. |
Wyatt Hepler | b85cda4 | 2021-04-07 13:13:15 -0700 | [diff] [blame] | 43 | - ``generate_setup``: As an alternative to ``setup``, generate setup files with |
| 44 | the keywords in this scope. ``name`` is required. For example: |
| 45 | |
| 46 | .. code-block:: |
| 47 | |
| 48 | generate_setup = { |
| 49 | name = "a_nifty_package" |
| 50 | version = "1.2a" |
| 51 | } |
| 52 | |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 53 | - ``sources`` - Python sources files in the package. |
| 54 | - ``tests`` - Test files for this Python package. |
| 55 | - ``python_deps`` - Dependencies on other pw_python_packages in the GN build. |
| 56 | - ``python_test_deps`` - Test-only pw_python_package dependencies. |
| 57 | - ``other_deps`` - Dependencies on GN targets that are not pw_python_packages. |
| 58 | - ``inputs`` - Other files to track, such as package_data. |
Wyatt Hepler | dcfcecf | 2021-03-01 08:36:19 -0800 | [diff] [blame] | 59 | - ``proto_library`` - A pw_proto_library target to embed in this Python package. |
Wyatt Hepler | b85cda4 | 2021-04-07 13:13:15 -0700 | [diff] [blame] | 60 | ``generate_setup`` is required in place of setup if proto_library is used. See |
Wyatt Hepler | dcfcecf | 2021-03-01 08:36:19 -0800 | [diff] [blame] | 61 | :ref:`module-pw_protobuf_compiler-add-to-python-package`. |
Wyatt Hepler | c2ce524 | 2021-03-17 08:42:14 -0700 | [diff] [blame] | 62 | - ``static_analysis`` List of static analysis tools to run; ``"*"`` (default) |
| 63 | runs all tools. The supported tools are ``"mypy"`` and ``"pylint"``. |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 64 | - ``pylintrc`` - Optional path to a pylintrc configuration file to use. If not |
| 65 | provided, Pylint's default rcfile search is used. Pylint is executed |
| 66 | from the package's setup directory, so pylintrc files in that directory |
| 67 | will take precedence over others. |
| 68 | - ``mypy_ini`` - Optional path to a mypy configuration file to use. If not |
| 69 | provided, mypy's default configuration file search is used. mypy is |
| 70 | executed from the package's setup directory, so mypy.ini files in that |
| 71 | directory will take precedence over others. |
| 72 | |
| 73 | Example |
| 74 | ------- |
| 75 | This is an example Python package declaration for a ``pw_my_module`` module. |
| 76 | |
| 77 | .. code-block:: |
| 78 | |
| 79 | import("//build_overrides/pigweed.gni") |
| 80 | |
| 81 | import("$dir_pw_build/python.gni") |
| 82 | |
| 83 | pw_python_package("py") { |
| 84 | setup = [ "setup.py" ] |
| 85 | sources = [ |
| 86 | "pw_my_module/__init__.py", |
| 87 | "pw_my_module/alfa.py", |
| 88 | "pw_my_module/bravo.py", |
| 89 | "pw_my_module/charlie.py", |
| 90 | ] |
| 91 | tests = [ |
| 92 | "alfa_test.py", |
| 93 | "charlie_test.py", |
| 94 | ] |
| 95 | python_deps = [ |
| 96 | "$dir_pw_status/py", |
| 97 | ":some_protos.python", |
| 98 | ] |
| 99 | python_test_deps = [ "$dir_pw_build/py" ] |
| 100 | pylintrc = "$dir_pigweed/.pylintrc" |
| 101 | } |
| 102 | |
Wyatt Hepler | af853ea | 2021-03-09 19:09:54 -0800 | [diff] [blame] | 103 | |
| 104 | .. _module-pw_build-python-wheels: |
| 105 | |
| 106 | Collecting Python wheels for distribution |
| 107 | ----------------------------------------- |
| 108 | The ``.wheel`` subtarget generates a wheel (``.whl``) for the Python package. |
| 109 | Wheels for a package and its transitive dependencies can be collected by |
| 110 | traversing the ``pw_python_package_wheels`` `GN metadata |
| 111 | <https://gn.googlesource.com/gn/+/master/docs/reference.md#var_metadata>`_ key, |
| 112 | which lists the output directory for each wheel. |
| 113 | |
| 114 | The ``pw_mirror_tree`` template can be used to collect wheels in an output |
| 115 | directory: |
| 116 | |
| 117 | .. code-block:: |
| 118 | |
| 119 | import("$dir_pw_build/mirror_tree.gni") |
| 120 | |
| 121 | pw_mirror_tree("my_wheels") { |
| 122 | path_data_keys = [ "pw_python_package_wheels" ] |
Wyatt Hepler | b85cda4 | 2021-04-07 13:13:15 -0700 | [diff] [blame] | 123 | deps = [ ":python_packages.wheel" ] |
Wyatt Hepler | af853ea | 2021-03-09 19:09:54 -0800 | [diff] [blame] | 124 | directory = "$root_out_dir/the_wheels" |
| 125 | } |
| 126 | |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 127 | pw_python_script |
| 128 | ================ |
| 129 | A ``pw_python_script`` represents a set of standalone Python scripts and/or |
| 130 | tests. These files support all of the arguments of ``pw_python_package`` except |
| 131 | those ``setup``. These targets can be installed, but this only installs their |
| 132 | dependencies. |
| 133 | |
Wyatt Hepler | 473efe0 | 2021-05-04 14:15:16 -0700 | [diff] [blame^] | 134 | ``pw_python_script`` allows creating a |
| 135 | :ref:`pw_python_action <module-pw_build-python-action>` associated with the |
| 136 | script. To create an action, pass an ``action`` scope to ``pw_python_script``. |
| 137 | If there is only a single source file, it serves as the action's ``script`` by |
| 138 | default. |
| 139 | |
| 140 | An action in ``pw_python_script`` can always be replaced with a standalone |
| 141 | ``pw_python_action``, but using the embedded action has some advantages: |
| 142 | |
| 143 | - The embedded action target bridges the gap between actions and Python targets. |
| 144 | A Python script can be expressed in a single, concise GN target, rather than |
| 145 | in two overlapping, dependent targets. |
| 146 | - The action automatically depends on the ``pw_python_script``. This ensures |
| 147 | that the script's dependencies are installed and the action automatically |
| 148 | reruns when the script's sources change, without needing to specify a |
| 149 | dependency, a step which is easy to forget. |
| 150 | - Using a ``pw_python_script`` with an embedded action is a simple way to check |
| 151 | an existing action's script with Pylint or Mypy or to add tests. |
| 152 | |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 153 | pw_python_group |
| 154 | =============== |
| 155 | Represents a group of ``pw_python_package`` and ``pw_python_script`` targets. |
| 156 | These targets do not add any files. Their subtargets simply forward to those of |
| 157 | their dependencies. |
| 158 | |
Wyatt Hepler | b3ea980 | 2021-02-23 09:46:09 -0800 | [diff] [blame] | 159 | pw_python_requirements |
| 160 | ====================== |
| 161 | Represents a set of local and PyPI requirements, with no associated source |
| 162 | files. These targets serve the role of a ``requirements.txt`` file. |