xref: /aosp_15_r20/external/pigweed/pw_build/python.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-python:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker===================
4*61c4878aSAndroid Build Coastguard WorkerPython GN Templates
5*61c4878aSAndroid Build Coastguard Worker===================
6*61c4878aSAndroid Build Coastguard Worker.. pigweed-module-subpage::
7*61c4878aSAndroid Build Coastguard Worker   :name: pw_build
8*61c4878aSAndroid Build Coastguard Worker
9*61c4878aSAndroid Build Coastguard WorkerThe Python build is implemented with GN templates defined in
10*61c4878aSAndroid Build Coastguard Worker``pw_build/python.gni``. See the .gni file for complete usage documentation.
11*61c4878aSAndroid Build Coastguard Worker
12*61c4878aSAndroid Build Coastguard Worker.. seealso::
13*61c4878aSAndroid Build Coastguard Worker
14*61c4878aSAndroid Build Coastguard Worker   - :bdg-ref-primary-line:`docs-python-build` for an overview on how Python in
15*61c4878aSAndroid Build Coastguard Worker     GN is built.
16*61c4878aSAndroid Build Coastguard Worker   - The :bdg-ref-primary-line:`module-pw_build` docs for other GN templates
17*61c4878aSAndroid Build Coastguard Worker     available within Pigweed.
18*61c4878aSAndroid Build Coastguard Worker
19*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-python-base-templates:
20*61c4878aSAndroid Build Coastguard Worker
21*61c4878aSAndroid Build Coastguard Worker---------------------
22*61c4878aSAndroid Build Coastguard WorkerPython Base Templates
23*61c4878aSAndroid Build Coastguard Worker---------------------
24*61c4878aSAndroid Build Coastguard WorkerThe core subset of templates where you can create Python packages, actions,
25*61c4878aSAndroid Build Coastguard Workerscripts and group them together are listed below.
26*61c4878aSAndroid Build Coastguard Worker
27*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_package`
28*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_action`
29*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_script`
30*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_group`
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_package:
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard Workerpw_python_package
35*61c4878aSAndroid Build Coastguard Worker=================
36*61c4878aSAndroid Build Coastguard WorkerThe main Python template is ``pw_python_package``. Each ``pw_python_package``
37*61c4878aSAndroid Build Coastguard Workertarget represents a Python package. As described in
38*61c4878aSAndroid Build Coastguard Worker:ref:`module-pw_build-python-target`, each ``pw_python_package`` expands to
39*61c4878aSAndroid Build Coastguard Workerseveral subtargets. In summary, these are:
40*61c4878aSAndroid Build Coastguard Worker
41*61c4878aSAndroid Build Coastguard Worker- ``<name>`` - Represents the files themselves
42*61c4878aSAndroid Build Coastguard Worker- ``<name>.lint`` - Runs static analysis
43*61c4878aSAndroid Build Coastguard Worker- ``<name>.tests`` - Runs all tests for this package
44*61c4878aSAndroid Build Coastguard Worker- ``<name>.install`` - Installs the package
45*61c4878aSAndroid Build Coastguard Worker- ``<name>.wheel`` - Builds a Python wheel
46*61c4878aSAndroid Build Coastguard Worker
47*61c4878aSAndroid Build Coastguard WorkerGN permits using abbreviated labels when the target name matches the directory
48*61c4878aSAndroid Build Coastguard Workername (e.g. ``//foo`` for ``//foo:foo``). For consistency with this, Python
49*61c4878aSAndroid Build Coastguard Workerpackage subtargets are aliased to the directory when the target name is the
50*61c4878aSAndroid Build Coastguard Workersame as the directory. For example, these two labels are equivalent:
51*61c4878aSAndroid Build Coastguard Worker
52*61c4878aSAndroid Build Coastguard Worker.. code-block::
53*61c4878aSAndroid Build Coastguard Worker
54*61c4878aSAndroid Build Coastguard Worker   //path/to/my_python_package:my_python_package.tests
55*61c4878aSAndroid Build Coastguard Worker   //path/to/my_python_package:tests
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard WorkerThe actions in a ``pw_python_package`` (e.g. installing packages and running
58*61c4878aSAndroid Build Coastguard WorkerPylint) are done within a single GN toolchain to avoid duplication in
59*61c4878aSAndroid Build Coastguard Workermulti-toolchain builds. This toolchain can be set with the
60*61c4878aSAndroid Build Coastguard Worker``pw_build_PYTHON_TOOLCHAIN`` GN arg, which defaults to
61*61c4878aSAndroid Build Coastguard Worker``$dir_pw_build/python_toolchain:python``.
62*61c4878aSAndroid Build Coastguard Worker
63*61c4878aSAndroid Build Coastguard Worker.. note::
64*61c4878aSAndroid Build Coastguard Worker
65*61c4878aSAndroid Build Coastguard Worker   By default, ``<name>.lint`` and ``<name>.tests`` will transitively test and
66*61c4878aSAndroid Build Coastguard Worker   lint any dependencies. This is done for backwards compatibility, but if you
67*61c4878aSAndroid Build Coastguard Worker   don't rely on this behavior you should turn this off by adding
68*61c4878aSAndroid Build Coastguard Worker   ``pw_build_TEST_TRANSITIVE_PYTHON_DEPS = false`` to your project's ``.gn``
69*61c4878aSAndroid Build Coastguard Worker   file.
70*61c4878aSAndroid Build Coastguard Worker
71*61c4878aSAndroid Build Coastguard WorkerArguments
72*61c4878aSAndroid Build Coastguard Worker---------
73*61c4878aSAndroid Build Coastguard Worker- ``setup`` - List of setup file paths (setup.cfg and pyproject.toml), which
74*61c4878aSAndroid Build Coastguard Worker  must all be in the same directory.
75*61c4878aSAndroid Build Coastguard Worker- ``generate_setup``: As an alternative to ``setup``, generate setup files with
76*61c4878aSAndroid Build Coastguard Worker  the keywords in this scope. ``name`` is required. This follows the same
77*61c4878aSAndroid Build Coastguard Worker  structure as a ``setup.cfg`` file's `declarative config
78*61c4878aSAndroid Build Coastguard Worker  <https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html>`_
79*61c4878aSAndroid Build Coastguard Worker  For example:
80*61c4878aSAndroid Build Coastguard Worker
81*61c4878aSAndroid Build Coastguard Worker  .. code-block::
82*61c4878aSAndroid Build Coastguard Worker
83*61c4878aSAndroid Build Coastguard Worker     generate_setup = {
84*61c4878aSAndroid Build Coastguard Worker       metadata = {
85*61c4878aSAndroid Build Coastguard Worker         name = "a_nifty_package"
86*61c4878aSAndroid Build Coastguard Worker         version = "1.2a"
87*61c4878aSAndroid Build Coastguard Worker       }
88*61c4878aSAndroid Build Coastguard Worker       options = {
89*61c4878aSAndroid Build Coastguard Worker         install_requires = [ "a_pip_package" ]
90*61c4878aSAndroid Build Coastguard Worker       }
91*61c4878aSAndroid Build Coastguard Worker     }
92*61c4878aSAndroid Build Coastguard Worker
93*61c4878aSAndroid Build Coastguard Worker- ``sources`` - Python sources files in the package.
94*61c4878aSAndroid Build Coastguard Worker- ``tests`` - Test files for this Python package.
95*61c4878aSAndroid Build Coastguard Worker
96*61c4878aSAndroid Build Coastguard Worker  .. tip::
97*61c4878aSAndroid Build Coastguard Worker     It is best to keep these files within the same folder as the ``BUILD.gn``
98*61c4878aSAndroid Build Coastguard Worker     and not nested within another folder that contains an ``__init__.py``
99*61c4878aSAndroid Build Coastguard Worker     file. That could cause your tests to be included within the package
100*61c4878aSAndroid Build Coastguard Worker     distributions (See :ref:`module-pw_build-pw_python_distribution`). For
101*61c4878aSAndroid Build Coastguard Worker     example pip installed into the bootstrapped Python virtual environment or
102*61c4878aSAndroid Build Coastguard Worker     as part of a Python wheel.
103*61c4878aSAndroid Build Coastguard Worker
104*61c4878aSAndroid Build Coastguard Worker     If you need to nest your test source files under a sub-folder exclude it in
105*61c4878aSAndroid Build Coastguard Worker     the ``setup.cfg`` file with:
106*61c4878aSAndroid Build Coastguard Worker
107*61c4878aSAndroid Build Coastguard Worker     .. code-block:: cfg
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard Worker        [options]
110*61c4878aSAndroid Build Coastguard Worker        packages = find:
111*61c4878aSAndroid Build Coastguard Worker
112*61c4878aSAndroid Build Coastguard Worker        # Exclude the tests and test_scripts folders.
113*61c4878aSAndroid Build Coastguard Worker        [options.packages.find]
114*61c4878aSAndroid Build Coastguard Worker        exclude =
115*61c4878aSAndroid Build Coastguard Worker            tests
116*61c4878aSAndroid Build Coastguard Worker            test_scripts
117*61c4878aSAndroid Build Coastguard Worker
118*61c4878aSAndroid Build Coastguard Worker- ``python_deps`` - Dependencies on other pw_python_packages in the GN build.
119*61c4878aSAndroid Build Coastguard Worker- ``python_test_deps`` - Test-only pw_python_package dependencies.
120*61c4878aSAndroid Build Coastguard Worker- ``other_deps`` - Dependencies on GN targets that are not pw_python_packages.
121*61c4878aSAndroid Build Coastguard Worker- ``inputs`` - Other files to track, such as package_data.
122*61c4878aSAndroid Build Coastguard Worker- ``proto_library`` - A pw_proto_library target to embed in this Python package.
123*61c4878aSAndroid Build Coastguard Worker  ``generate_setup`` is required in place of setup if proto_library is used. See
124*61c4878aSAndroid Build Coastguard Worker  :ref:`module-pw_protobuf_compiler-add-to-python-package`.
125*61c4878aSAndroid Build Coastguard Worker- ``static_analysis`` List of static analysis tools to run; ``"*"`` (default)
126*61c4878aSAndroid Build Coastguard Worker  runs all tools. The supported tools are ``"mypy"`` and ``"pylint"``.
127*61c4878aSAndroid Build Coastguard Worker- ``pylintrc`` - Optional path to a pylintrc configuration file to use. If not
128*61c4878aSAndroid Build Coastguard Worker  provided, Pylint's default rcfile search is used. Pylint is executed
129*61c4878aSAndroid Build Coastguard Worker  from the package's setup directory, so pylintrc files in that directory
130*61c4878aSAndroid Build Coastguard Worker  will take precedence over others.
131*61c4878aSAndroid Build Coastguard Worker- ``mypy_ini`` - Optional path to a mypy configuration file to use. If not
132*61c4878aSAndroid Build Coastguard Worker  provided, mypy's default configuration file search is used. mypy is
133*61c4878aSAndroid Build Coastguard Worker  executed from the package's setup directory, so mypy.ini files in that
134*61c4878aSAndroid Build Coastguard Worker  directory will take precedence over others.
135*61c4878aSAndroid Build Coastguard Worker
136*61c4878aSAndroid Build Coastguard WorkerExample
137*61c4878aSAndroid Build Coastguard Worker-------
138*61c4878aSAndroid Build Coastguard WorkerThis is an example Python package declaration for a ``pw_my_module`` module.
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard Worker.. code-block::
141*61c4878aSAndroid Build Coastguard Worker
142*61c4878aSAndroid Build Coastguard Worker   import("//build_overrides/pigweed.gni")
143*61c4878aSAndroid Build Coastguard Worker
144*61c4878aSAndroid Build Coastguard Worker   import("$dir_pw_build/python.gni")
145*61c4878aSAndroid Build Coastguard Worker
146*61c4878aSAndroid Build Coastguard Worker   pw_python_package("py") {
147*61c4878aSAndroid Build Coastguard Worker     setup = [
148*61c4878aSAndroid Build Coastguard Worker       "pyproject.toml",
149*61c4878aSAndroid Build Coastguard Worker       "setup.cfg",
150*61c4878aSAndroid Build Coastguard Worker     ]
151*61c4878aSAndroid Build Coastguard Worker     sources = [
152*61c4878aSAndroid Build Coastguard Worker       "pw_my_module/__init__.py",
153*61c4878aSAndroid Build Coastguard Worker       "pw_my_module/alfa.py",
154*61c4878aSAndroid Build Coastguard Worker       "pw_my_module/bravo.py",
155*61c4878aSAndroid Build Coastguard Worker       "pw_my_module/charlie.py",
156*61c4878aSAndroid Build Coastguard Worker     ]
157*61c4878aSAndroid Build Coastguard Worker     tests = [
158*61c4878aSAndroid Build Coastguard Worker       "alfa_test.py",
159*61c4878aSAndroid Build Coastguard Worker       "charlie_test.py",
160*61c4878aSAndroid Build Coastguard Worker     ]
161*61c4878aSAndroid Build Coastguard Worker     python_deps = [
162*61c4878aSAndroid Build Coastguard Worker       "$dir_pw_status/py",
163*61c4878aSAndroid Build Coastguard Worker       ":some_protos.python",
164*61c4878aSAndroid Build Coastguard Worker     ]
165*61c4878aSAndroid Build Coastguard Worker     python_test_deps = [ "$dir_pw_build/py" ]
166*61c4878aSAndroid Build Coastguard Worker     pylintrc = "$dir_pigweed/.pylintrc"
167*61c4878aSAndroid Build Coastguard Worker   }
168*61c4878aSAndroid Build Coastguard Worker
169*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_action:
170*61c4878aSAndroid Build Coastguard Worker
171*61c4878aSAndroid Build Coastguard Workerpw_python_action
172*61c4878aSAndroid Build Coastguard Worker================
173*61c4878aSAndroid Build Coastguard WorkerThe ``pw_python_action`` template is a convenience wrapper around GN's `action
174*61c4878aSAndroid Build Coastguard Workerfunction <https://gn.googlesource.com/gn/+/main/docs/reference.md#func_action>`_
175*61c4878aSAndroid Build Coastguard Workerfor running Python scripts. See
176*61c4878aSAndroid Build Coastguard Worker:bdg-ref-primary-line:`module-pw_build-python-action` in the ``pw_build``
177*61c4878aSAndroid Build Coastguard Workerdocumentation for usage.
178*61c4878aSAndroid Build Coastguard Worker
179*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_script:
180*61c4878aSAndroid Build Coastguard Worker
181*61c4878aSAndroid Build Coastguard Workerpw_python_script
182*61c4878aSAndroid Build Coastguard Worker================
183*61c4878aSAndroid Build Coastguard WorkerA ``pw_python_script`` represents a set of standalone Python scripts and/or
184*61c4878aSAndroid Build Coastguard Workertests. These files support all of the arguments of ``pw_python_package`` except
185*61c4878aSAndroid Build Coastguard Workerthose ``setup``. These targets can be installed, but this only installs their
186*61c4878aSAndroid Build Coastguard Workerdependencies.
187*61c4878aSAndroid Build Coastguard Worker
188*61c4878aSAndroid Build Coastguard Worker``pw_python_script`` allows creating a
189*61c4878aSAndroid Build Coastguard Worker:ref:`pw_python_action <module-pw_build-python-action>` associated with the
190*61c4878aSAndroid Build Coastguard Workerscript. To create an action, pass an ``action`` scope to ``pw_python_script``.
191*61c4878aSAndroid Build Coastguard WorkerIf there is only a single source file, it serves as the action's ``script`` by
192*61c4878aSAndroid Build Coastguard Workerdefault.
193*61c4878aSAndroid Build Coastguard Worker
194*61c4878aSAndroid Build Coastguard WorkerAn action in ``pw_python_script`` can always be replaced with a standalone
195*61c4878aSAndroid Build Coastguard Worker``pw_python_action``, but using the embedded action has some advantages:
196*61c4878aSAndroid Build Coastguard Worker
197*61c4878aSAndroid Build Coastguard Worker- The embedded action target bridges the gap between actions and Python targets.
198*61c4878aSAndroid Build Coastguard Worker  A Python script can be expressed in a single, concise GN target, rather than
199*61c4878aSAndroid Build Coastguard Worker  in two overlapping, dependent targets.
200*61c4878aSAndroid Build Coastguard Worker- The action automatically depends on the ``pw_python_script``. This ensures
201*61c4878aSAndroid Build Coastguard Worker  that the script's dependencies are installed and the action automatically
202*61c4878aSAndroid Build Coastguard Worker  reruns when the script's sources change, without needing to specify a
203*61c4878aSAndroid Build Coastguard Worker  dependency, a step which is easy to forget.
204*61c4878aSAndroid Build Coastguard Worker- Using a ``pw_python_script`` with an embedded action is a simple way to check
205*61c4878aSAndroid Build Coastguard Worker  an existing action's script with Pylint or Mypy or to add tests.
206*61c4878aSAndroid Build Coastguard Worker
207*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_group:
208*61c4878aSAndroid Build Coastguard Worker
209*61c4878aSAndroid Build Coastguard Workerpw_python_group
210*61c4878aSAndroid Build Coastguard Worker===============
211*61c4878aSAndroid Build Coastguard WorkerRepresents a group of ``pw_python_package`` and ``pw_python_script`` targets.
212*61c4878aSAndroid Build Coastguard WorkerThese targets do not add any files. Their subtargets simply forward to those of
213*61c4878aSAndroid Build Coastguard Workertheir dependencies.
214*61c4878aSAndroid Build Coastguard Worker
215*61c4878aSAndroid Build Coastguard Worker.. code-block::
216*61c4878aSAndroid Build Coastguard Worker
217*61c4878aSAndroid Build Coastguard Worker   pw_python_group("solar_system_python_packages") {
218*61c4878aSAndroid Build Coastguard Worker     python_deps = [
219*61c4878aSAndroid Build Coastguard Worker       "//planets/mercury/py",
220*61c4878aSAndroid Build Coastguard Worker       "//planets/venus/py",
221*61c4878aSAndroid Build Coastguard Worker       "//planets/earth/py",
222*61c4878aSAndroid Build Coastguard Worker       "//planets/mars/py",
223*61c4878aSAndroid Build Coastguard Worker       "//planets/jupiter/py",
224*61c4878aSAndroid Build Coastguard Worker       "//planets/saturn/py",
225*61c4878aSAndroid Build Coastguard Worker       "//planets/uranus/py",
226*61c4878aSAndroid Build Coastguard Worker       "//planets/neptune/py",
227*61c4878aSAndroid Build Coastguard Worker       "//planetoids/ceres/py",
228*61c4878aSAndroid Build Coastguard Worker       "//planetoids/pluto/py",
229*61c4878aSAndroid Build Coastguard Worker     ]
230*61c4878aSAndroid Build Coastguard Worker   }
231*61c4878aSAndroid Build Coastguard Worker
232*61c4878aSAndroid Build Coastguard Worker----------------------------
233*61c4878aSAndroid Build Coastguard WorkerPython Environment Templates
234*61c4878aSAndroid Build Coastguard Worker----------------------------
235*61c4878aSAndroid Build Coastguard WorkerTemplates that manage the Python build and bootstrap environment are listed
236*61c4878aSAndroid Build Coastguard Workerhere.
237*61c4878aSAndroid Build Coastguard Worker
238*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_venv`
239*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_pip_install`
240*61c4878aSAndroid Build Coastguard Worker
241*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_venv:
242*61c4878aSAndroid Build Coastguard Worker
243*61c4878aSAndroid Build Coastguard Workerpw_python_venv
244*61c4878aSAndroid Build Coastguard Worker==============
245*61c4878aSAndroid Build Coastguard WorkerDefines and creates a Python virtualenv. This template is used by Pigweed in
246*61c4878aSAndroid Build Coastguard Workerhttps://cs.pigweed.dev/pigweed/+/main:pw_env_setup/BUILD.gn to create a
247*61c4878aSAndroid Build Coastguard Workervirtualenv for use within the GN build that all Python actions will run in.
248*61c4878aSAndroid Build Coastguard Worker
249*61c4878aSAndroid Build Coastguard WorkerExample
250*61c4878aSAndroid Build Coastguard Worker-------
251*61c4878aSAndroid Build Coastguard Worker.. code-block::
252*61c4878aSAndroid Build Coastguard Worker   :caption: Example of a typical Python venv definition in a top level
253*61c4878aSAndroid Build Coastguard Worker             :octicon:`file;1em` ``BUILD.gn``
254*61c4878aSAndroid Build Coastguard Worker
255*61c4878aSAndroid Build Coastguard Worker   declare_args() {
256*61c4878aSAndroid Build Coastguard Worker     pw_build_PYTHON_BUILD_VENV = "//:my_build_venv"
257*61c4878aSAndroid Build Coastguard Worker   }
258*61c4878aSAndroid Build Coastguard Worker
259*61c4878aSAndroid Build Coastguard Worker   pw_python_group("my_product_packages") {
260*61c4878aSAndroid Build Coastguard Worker     python_deps = [
261*61c4878aSAndroid Build Coastguard Worker       "//product_dev_tools/py",
262*61c4878aSAndroid Build Coastguard Worker       "//product_release_tools/py",
263*61c4878aSAndroid Build Coastguard Worker     ]
264*61c4878aSAndroid Build Coastguard Worker   }
265*61c4878aSAndroid Build Coastguard Worker
266*61c4878aSAndroid Build Coastguard Worker   pw_python_venv("my_build_venv") {
267*61c4878aSAndroid Build Coastguard Worker     path = "$root_build_dir/python-build-venv"
268*61c4878aSAndroid Build Coastguard Worker     constraints = [ "//tools/constraints.list" ]
269*61c4878aSAndroid Build Coastguard Worker     requirements = [ "//tools/requirements.txt" ]
270*61c4878aSAndroid Build Coastguard Worker     source_packages = [
271*61c4878aSAndroid Build Coastguard Worker       "$dir_pw_env_setup:core_pigweed_python_packages",
272*61c4878aSAndroid Build Coastguard Worker       "//tools:another_pw_python_package",
273*61c4878aSAndroid Build Coastguard Worker       "//:my_product_packages",
274*61c4878aSAndroid Build Coastguard Worker     ]
275*61c4878aSAndroid Build Coastguard Worker     pip_generate_hashes = true
276*61c4878aSAndroid Build Coastguard Worker   }
277*61c4878aSAndroid Build Coastguard Worker
278*61c4878aSAndroid Build Coastguard WorkerArguments
279*61c4878aSAndroid Build Coastguard Worker---------
280*61c4878aSAndroid Build Coastguard Worker- ``path``: The directory where the virtualenv will be created. This is relative
281*61c4878aSAndroid Build Coastguard Worker  to the GN root and must begin with "$root_build_dir/" if it lives in the
282*61c4878aSAndroid Build Coastguard Worker  output directory or "//" if it lives in elsewhere.
283*61c4878aSAndroid Build Coastguard Worker
284*61c4878aSAndroid Build Coastguard Worker- ``constraints``: A list of constraint files used when performing pip install
285*61c4878aSAndroid Build Coastguard Worker  into this virtualenv. By default this is set to the
286*61c4878aSAndroid Build Coastguard Worker  ``pw_build_PIP_CONSTRAINTS`` GN arg.
287*61c4878aSAndroid Build Coastguard Worker
288*61c4878aSAndroid Build Coastguard Worker- ``requirements``: A list of requirements files to install into this virtualenv
289*61c4878aSAndroid Build Coastguard Worker  on creation. By default this is set to the ``pw_build_PIP_REQUIREMENTS`` GN
290*61c4878aSAndroid Build Coastguard Worker  arg.
291*61c4878aSAndroid Build Coastguard Worker
292*61c4878aSAndroid Build Coastguard Worker  .. seealso::
293*61c4878aSAndroid Build Coastguard Worker
294*61c4878aSAndroid Build Coastguard Worker     For more info on the ``pw_build_PIP_CONSTRAINTS`` and
295*61c4878aSAndroid Build Coastguard Worker     ``pw_build_PIP_REQUIREMENTS`` GN args see:
296*61c4878aSAndroid Build Coastguard Worker     :ref:`docs-python-build-python-gn-requirements-files`
297*61c4878aSAndroid Build Coastguard Worker
298*61c4878aSAndroid Build Coastguard Worker- ``pip_generate_hashes``: (Default: false) Use ``--generate-hashes`` When
299*61c4878aSAndroid Build Coastguard Worker  running ``pip-compile <A list of requirements files to install into this
300*61c4878aSAndroid Build Coastguard Worker  virtualenv>`` to compute the final ``requirements.txt``
301*61c4878aSAndroid Build Coastguard Worker
302*61c4878aSAndroid Build Coastguard Worker- ``source_packages``: A list of in-tree
303*61c4878aSAndroid Build Coastguard Worker  :ref:`module-pw_build-pw_python_package` or targets that will be checked for
304*61c4878aSAndroid Build Coastguard Worker  external third_party pip dependencies to install into this
305*61c4878aSAndroid Build Coastguard Worker  virtualenv. Note this list of targets isn't actually installed into the
306*61c4878aSAndroid Build Coastguard Worker  virtualenv. Only packages defined inside the ``[options] install_requires``
307*61c4878aSAndroid Build Coastguard Worker  section of each pw_python_package's setup.cfg will be pip installed.
308*61c4878aSAndroid Build Coastguard Worker
309*61c4878aSAndroid Build Coastguard Worker  .. seealso::
310*61c4878aSAndroid Build Coastguard Worker
311*61c4878aSAndroid Build Coastguard Worker     For an example ``setup.cfg`` file see: `Configuring setuptools using
312*61c4878aSAndroid Build Coastguard Worker     setup.cfg files
313*61c4878aSAndroid Build Coastguard Worker     <https://setuptools.pypa.io/en/latest/userguide/declarative_config.html>`_
314*61c4878aSAndroid Build Coastguard Worker
315*61c4878aSAndroid Build Coastguard Worker- ``output_logs``: (Default: true) If this is true then the virtual environment will output to logs.
316*61c4878aSAndroid Build Coastguard Worker
317*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_pip_install:
318*61c4878aSAndroid Build Coastguard Worker
319*61c4878aSAndroid Build Coastguard Workerpw_python_pip_install
320*61c4878aSAndroid Build Coastguard Worker=====================
321*61c4878aSAndroid Build Coastguard WorkerThis will pip install ``pw_python_package`` targets into the bootstrapped
322*61c4878aSAndroid Build Coastguard Workerdeveloper environment.
323*61c4878aSAndroid Build Coastguard Worker
324*61c4878aSAndroid Build Coastguard WorkerExample
325*61c4878aSAndroid Build Coastguard Worker-------
326*61c4878aSAndroid Build Coastguard Worker.. code-block::
327*61c4878aSAndroid Build Coastguard Worker   :caption: Example of a typical Python venv definition in a top level
328*61c4878aSAndroid Build Coastguard Worker             :octicon:`file;1em` ``BUILD.gn``
329*61c4878aSAndroid Build Coastguard Worker
330*61c4878aSAndroid Build Coastguard Worker   pw_python_pip_install("pip_install_my_product_packages") {
331*61c4878aSAndroid Build Coastguard Worker     packages = [
332*61c4878aSAndroid Build Coastguard Worker       "//product_dev_tools/py",
333*61c4878aSAndroid Build Coastguard Worker       "//product_release_tools/py",
334*61c4878aSAndroid Build Coastguard Worker     ]
335*61c4878aSAndroid Build Coastguard Worker   }
336*61c4878aSAndroid Build Coastguard Worker
337*61c4878aSAndroid Build Coastguard WorkerArguments
338*61c4878aSAndroid Build Coastguard Worker---------
339*61c4878aSAndroid Build Coastguard Worker
340*61c4878aSAndroid Build Coastguard Worker- ``packages``: A list of :ref:`module-pw_build-pw_python_package` targets to be
341*61c4878aSAndroid Build Coastguard Worker  pip installed.  All packages specified will be installed using a single ``pip
342*61c4878aSAndroid Build Coastguard Worker  install`` command with a ``--constraint`` argument for each constraint file in
343*61c4878aSAndroid Build Coastguard Worker  the ``pw_build_PIP_CONSTRAINTS`` GN arg.
344*61c4878aSAndroid Build Coastguard Worker
345*61c4878aSAndroid Build Coastguard Worker- ``editable``: If true, --editable is passed to the pip install command.
346*61c4878aSAndroid Build Coastguard Worker
347*61c4878aSAndroid Build Coastguard Worker- ``force_reinstall``: If true, ``--force-reinstall`` is passed to the pip
348*61c4878aSAndroid Build Coastguard Worker  install command.
349*61c4878aSAndroid Build Coastguard Worker
350*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-python-dist:
351*61c4878aSAndroid Build Coastguard Worker
352*61c4878aSAndroid Build Coastguard Worker------------------------------
353*61c4878aSAndroid Build Coastguard WorkerPython Distributable Templates
354*61c4878aSAndroid Build Coastguard Worker------------------------------
355*61c4878aSAndroid Build Coastguard WorkerPigweed also provides some templates to make it easier to bundle Python packages
356*61c4878aSAndroid Build Coastguard Workerfor deployment. These templates are found in ``pw_build/python_dist.gni``.
357*61c4878aSAndroid Build Coastguard Worker
358*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_wheels`
359*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_zip_with_setup`
360*61c4878aSAndroid Build Coastguard Worker- :ref:`module-pw_build-pw_python_distribution`
361*61c4878aSAndroid Build Coastguard Worker
362*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_wheels:
363*61c4878aSAndroid Build Coastguard Worker
364*61c4878aSAndroid Build Coastguard Workerpw_python_wheels
365*61c4878aSAndroid Build Coastguard Worker================
366*61c4878aSAndroid Build Coastguard WorkerCollects Python wheels for one or more ``pw_python_package`` targets, plus any
367*61c4878aSAndroid Build Coastguard Workeradditional ``pw_python_package`` targets they depend on, directly or indirectly.
368*61c4878aSAndroid Build Coastguard WorkerNote that this does not include Python dependencies that come from outside the
369*61c4878aSAndroid Build Coastguard WorkerGN build, like packages from PyPI, for example. Those should still be declared
370*61c4878aSAndroid Build Coastguard Workerin the package's ``setup.cfg`` file as usual.
371*61c4878aSAndroid Build Coastguard Worker
372*61c4878aSAndroid Build Coastguard WorkerArguments
373*61c4878aSAndroid Build Coastguard Worker---------
374*61c4878aSAndroid Build Coastguard Worker- ``packages`` - List of ``pw_python_package`` targets whose wheels should be
375*61c4878aSAndroid Build Coastguard Worker  included; their dependencies will be pulled in as wheels also.
376*61c4878aSAndroid Build Coastguard Worker- ``directory`` - Output directory for the collected wheels. Defaults to
377*61c4878aSAndroid Build Coastguard Worker  ``$target_out_dir/$target_name``.
378*61c4878aSAndroid Build Coastguard Worker
379*61c4878aSAndroid Build Coastguard WorkerWheel collection under the hood
380*61c4878aSAndroid Build Coastguard Worker-------------------------------
381*61c4878aSAndroid Build Coastguard WorkerThe ``.wheel`` subtarget of every ``pw_python_package`` generates a wheel
382*61c4878aSAndroid Build Coastguard Worker(``.whl``) for the Python package. The ``pw_python_wheels`` template figures
383*61c4878aSAndroid Build Coastguard Workerout which wheels to collect by traversing the ``pw_python_package_wheels``
384*61c4878aSAndroid Build Coastguard Worker`GN metadata
385*61c4878aSAndroid Build Coastguard Worker<https://gn.googlesource.com/gn/+/HEAD/docs/reference.md#var_metadata>`_ key,
386*61c4878aSAndroid Build Coastguard Workerwhich lists the output directory for each wheel.
387*61c4878aSAndroid Build Coastguard Worker
388*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_zip_with_setup:
389*61c4878aSAndroid Build Coastguard Worker
390*61c4878aSAndroid Build Coastguard Workerpw_python_zip_with_setup
391*61c4878aSAndroid Build Coastguard Worker========================
392*61c4878aSAndroid Build Coastguard WorkerGenerates a ``.zip`` archive suitable for deployment outside of the project's
393*61c4878aSAndroid Build Coastguard Workerdeveloper environment. The generated ``.zip`` contains Python wheels
394*61c4878aSAndroid Build Coastguard Worker(``.whl`` files) for one or more ``pw_python_package`` targets, plus wheels for
395*61c4878aSAndroid Build Coastguard Workerany additional ``pw_python_package`` targets in the GN build they depend on,
396*61c4878aSAndroid Build Coastguard Workerdirectly or indirectly. Dependencies from outside the GN build, such as packages
397*61c4878aSAndroid Build Coastguard Workerfrom PyPI, must be listed in packages' ``setup.cfg`` file as usual.
398*61c4878aSAndroid Build Coastguard Worker
399*61c4878aSAndroid Build Coastguard WorkerThe ``.zip`` also includes simple setup scripts for Linux,
400*61c4878aSAndroid Build Coastguard WorkerMacOS, and Windows. The setup scripts automatically create a Python virtual
401*61c4878aSAndroid Build Coastguard Workerenvironment and install the whole collection of wheels into it using ``pip``.
402*61c4878aSAndroid Build Coastguard Worker
403*61c4878aSAndroid Build Coastguard WorkerOptionally, additional files and directories can be included in the archive.
404*61c4878aSAndroid Build Coastguard WorkerOne common example of an additional file to include is a README file with setup
405*61c4878aSAndroid Build Coastguard Workerand usage instructions for the distributable. A simple ready-to-use README file
406*61c4878aSAndroid Build Coastguard Workeris available at ``pw_build/py_dist/README.md``.
407*61c4878aSAndroid Build Coastguard Worker
408*61c4878aSAndroid Build Coastguard WorkerArguments
409*61c4878aSAndroid Build Coastguard Worker---------
410*61c4878aSAndroid Build Coastguard Worker- ``packages`` - A list of `pw_python_package` targets whose wheels should be
411*61c4878aSAndroid Build Coastguard Worker  included; their dependencies will be pulled in as wheels also.
412*61c4878aSAndroid Build Coastguard Worker- ``inputs`` - An optional list of extra files to include in the generated
413*61c4878aSAndroid Build Coastguard Worker  ``.zip``, formatted the same way as the ``inputs`` argument to ``pw_zip``
414*61c4878aSAndroid Build Coastguard Worker  targets.
415*61c4878aSAndroid Build Coastguard Worker- ``dirs`` - An optional list of directories to include in the generated
416*61c4878aSAndroid Build Coastguard Worker  ``.zip``, formatted the same was as the ``dirs`` argument to ``pw_zip``
417*61c4878aSAndroid Build Coastguard Worker  targets.
418*61c4878aSAndroid Build Coastguard Worker
419*61c4878aSAndroid Build Coastguard WorkerExample
420*61c4878aSAndroid Build Coastguard Worker-------
421*61c4878aSAndroid Build Coastguard Worker
422*61c4878aSAndroid Build Coastguard Worker.. code-block::
423*61c4878aSAndroid Build Coastguard Worker
424*61c4878aSAndroid Build Coastguard Worker   import("//build_overrides/pigweed.gni")
425*61c4878aSAndroid Build Coastguard Worker
426*61c4878aSAndroid Build Coastguard Worker   import("$dir_pw_build/python_dist.gni")
427*61c4878aSAndroid Build Coastguard Worker
428*61c4878aSAndroid Build Coastguard Worker   pw_python_zip_with_setup("my_tools") {
429*61c4878aSAndroid Build Coastguard Worker     packages = [ ":some_python_package" ]
430*61c4878aSAndroid Build Coastguard Worker     inputs = [ "$dir_pw_build/python_dist/README.md > /${target_name}/" ]
431*61c4878aSAndroid Build Coastguard Worker   }
432*61c4878aSAndroid Build Coastguard Worker
433*61c4878aSAndroid Build Coastguard Worker.. _module-pw_build-pw_python_distribution:
434*61c4878aSAndroid Build Coastguard Worker
435*61c4878aSAndroid Build Coastguard Workerpw_python_distribution
436*61c4878aSAndroid Build Coastguard Worker======================
437*61c4878aSAndroid Build Coastguard WorkerGenerates a directory of Python packages from source files suitable for
438*61c4878aSAndroid Build Coastguard Workerdeployment outside of the project developer environment. The resulting directory
439*61c4878aSAndroid Build Coastguard Workercontains only files mentioned in each package's ``setup.cfg`` file. This is
440*61c4878aSAndroid Build Coastguard Workeruseful for bundling multiple Python packages up into a single package for
441*61c4878aSAndroid Build Coastguard Workerdistribution to other locations like `<http://pypi.org>`_.
442*61c4878aSAndroid Build Coastguard Worker
443*61c4878aSAndroid Build Coastguard WorkerArguments
444*61c4878aSAndroid Build Coastguard Worker---------
445*61c4878aSAndroid Build Coastguard Worker
446*61c4878aSAndroid Build Coastguard Worker- ``packages`` - A list of :ref:`module-pw_build-pw_python_package` targets to be installed into
447*61c4878aSAndroid Build Coastguard Worker  the build directory. Their dependencies will be pulled in as wheels also.
448*61c4878aSAndroid Build Coastguard Worker
449*61c4878aSAndroid Build Coastguard Worker- ``include_tests`` - If true, copy Python package tests to a ``tests`` subdir.
450*61c4878aSAndroid Build Coastguard Worker
451*61c4878aSAndroid Build Coastguard Worker- ``extra_files`` - A list of extra files that should be included in the output.
452*61c4878aSAndroid Build Coastguard Worker  The format of each item in this list follows this convention:
453*61c4878aSAndroid Build Coastguard Worker
454*61c4878aSAndroid Build Coastguard Worker  .. code-block:: text
455*61c4878aSAndroid Build Coastguard Worker
456*61c4878aSAndroid Build Coastguard Worker     //some/nested/source_file > nested/destination_file
457*61c4878aSAndroid Build Coastguard Worker
458*61c4878aSAndroid Build Coastguard Worker  - Source and destination file should be separated by ``>``.
459*61c4878aSAndroid Build Coastguard Worker
460*61c4878aSAndroid Build Coastguard Worker  - The source file should be a GN target label (starting with ``//``).
461*61c4878aSAndroid Build Coastguard Worker
462*61c4878aSAndroid Build Coastguard Worker  - The destination file will be relative to the generated output
463*61c4878aSAndroid Build Coastguard Worker    directory. Parent directories are automatically created for each file. If a
464*61c4878aSAndroid Build Coastguard Worker    file would be overwritten an error is raised.
465*61c4878aSAndroid Build Coastguard Worker
466*61c4878aSAndroid Build Coastguard Worker- ``generate_setup_cfg`` - If included, create a merged ``setup.cfg`` for all
467*61c4878aSAndroid Build Coastguard Worker  python Packages using either a ``common_config_file`` as a base or ``name``
468*61c4878aSAndroid Build Coastguard Worker  and ``version`` strings. The ``common_config_file`` should contain the
469*61c4878aSAndroid Build Coastguard Worker  required fields in the ``metadata`` and ``options`` sections as shown in
470*61c4878aSAndroid Build Coastguard Worker  `Configuring setup() using setup.cfg files <https://setuptools.pypa.io/en/latest/userguide/declarative_config.html>`_.
471*61c4878aSAndroid Build Coastguard Worker
472*61c4878aSAndroid Build Coastguard Worker  This scope can optionally include:
473*61c4878aSAndroid Build Coastguard Worker
474*61c4878aSAndroid Build Coastguard Worker  - ``append_git_sha_to_version = true``: Append the current git SHA to the
475*61c4878aSAndroid Build Coastguard Worker    package version string after a ``+`` sign.
476*61c4878aSAndroid Build Coastguard Worker
477*61c4878aSAndroid Build Coastguard Worker  - ``append_date_to_version = true``: Append the current date to the package
478*61c4878aSAndroid Build Coastguard Worker    version string after a ``+`` sign.
479*61c4878aSAndroid Build Coastguard Worker
480*61c4878aSAndroid Build Coastguard Worker  - ``include_default_pyproject_file = true``: Include a standard
481*61c4878aSAndroid Build Coastguard Worker    ``pyproject.toml`` file in the output.
482*61c4878aSAndroid Build Coastguard Worker
483*61c4878aSAndroid Build Coastguard Worker  - ``include_extra_files_in_package_data = true``: Add any ``extra_files``
484*61c4878aSAndroid Build Coastguard Worker    entries to the generated ``setup.cfg`` file under the
485*61c4878aSAndroid Build Coastguard Worker    ``[options.package_data]`` section.
486*61c4878aSAndroid Build Coastguard Worker
487*61c4878aSAndroid Build Coastguard Worker  - ``auto_create_package_data_init_py_files = true``: (Default: true) Create
488*61c4878aSAndroid Build Coastguard Worker    ``__init__.py`` files as needed in all subdirs of ``extra_files`` when
489*61c4878aSAndroid Build Coastguard Worker    including in ``[options.package_data]``.
490*61c4878aSAndroid Build Coastguard Worker
491*61c4878aSAndroid Build Coastguard Worker  .. code-block::
492*61c4878aSAndroid Build Coastguard Worker     :caption: :octicon:`file;1em` Example using a common setup.cfg and
493*61c4878aSAndroid Build Coastguard Worker               pyproject.toml files.
494*61c4878aSAndroid Build Coastguard Worker
495*61c4878aSAndroid Build Coastguard Worker     generate_setup_cfg = {
496*61c4878aSAndroid Build Coastguard Worker       common_config_file = "pypi_common_setup.cfg"
497*61c4878aSAndroid Build Coastguard Worker       append_date_to_version = true
498*61c4878aSAndroid Build Coastguard Worker     }
499*61c4878aSAndroid Build Coastguard Worker     extra_files = [
500*61c4878aSAndroid Build Coastguard Worker       "//source/pyproject.toml > pyproject.toml"
501*61c4878aSAndroid Build Coastguard Worker     ]
502*61c4878aSAndroid Build Coastguard Worker
503*61c4878aSAndroid Build Coastguard Worker  .. code-block::
504*61c4878aSAndroid Build Coastguard Worker     :caption: :octicon:`file;1em` Example using name and version strings and a
505*61c4878aSAndroid Build Coastguard Worker               default pyproject.toml file.
506*61c4878aSAndroid Build Coastguard Worker
507*61c4878aSAndroid Build Coastguard Worker     generate_setup_cfg = {
508*61c4878aSAndroid Build Coastguard Worker       name = "awesome"
509*61c4878aSAndroid Build Coastguard Worker       version = "1.0.0"
510*61c4878aSAndroid Build Coastguard Worker       include_default_pyproject_file = true
511*61c4878aSAndroid Build Coastguard Worker       append_date_to_version = true
512*61c4878aSAndroid Build Coastguard Worker     }
513*61c4878aSAndroid Build Coastguard Worker
514*61c4878aSAndroid Build Coastguard WorkerUsing this template will create an additional target for and building a Python
515*61c4878aSAndroid Build Coastguard Workerwheel. For example if you define ``pw_python_distribution("awesome")`` the
516*61c4878aSAndroid Build Coastguard Workerresulting targets that get created will be:
517*61c4878aSAndroid Build Coastguard Worker
518*61c4878aSAndroid Build Coastguard Worker- ``awesome`` - This will create the merged package with all source files in
519*61c4878aSAndroid Build Coastguard Worker  place in the out directory under ``out/obj/awesome/``.
520*61c4878aSAndroid Build Coastguard Worker- ``awesome.wheel`` - This builds a Python wheel from the above source files
521*61c4878aSAndroid Build Coastguard Worker  under ``out/obj/awesome._build_wheel/awesome*.whl``.
522*61c4878aSAndroid Build Coastguard Worker
523*61c4878aSAndroid Build Coastguard WorkerExample
524*61c4878aSAndroid Build Coastguard Worker-------
525*61c4878aSAndroid Build Coastguard Worker
526*61c4878aSAndroid Build Coastguard Worker.. code-block::
527*61c4878aSAndroid Build Coastguard Worker   :caption: :octicon:`file;1em` ./pw_env_setup/BUILD.gn
528*61c4878aSAndroid Build Coastguard Worker
529*61c4878aSAndroid Build Coastguard Worker   import("//build_overrides/pigweed.gni")
530*61c4878aSAndroid Build Coastguard Worker
531*61c4878aSAndroid Build Coastguard Worker   import("$dir_pw_build/python_dist.gni")
532*61c4878aSAndroid Build Coastguard Worker
533*61c4878aSAndroid Build Coastguard Worker   pw_python_distribution("build_python_source_tree") {
534*61c4878aSAndroid Build Coastguard Worker     packages = [
535*61c4878aSAndroid Build Coastguard Worker       ":some_python_package",
536*61c4878aSAndroid Build Coastguard Worker       ":another_python_package",
537*61c4878aSAndroid Build Coastguard Worker     ]
538*61c4878aSAndroid Build Coastguard Worker     include_tests = true
539*61c4878aSAndroid Build Coastguard Worker     extra_files = [
540*61c4878aSAndroid Build Coastguard Worker       "//README.md > ./README.md",
541*61c4878aSAndroid Build Coastguard Worker       "//some_python_package/py/BUILD.bazel > some_python_package/BUILD.bazel",
542*61c4878aSAndroid Build Coastguard Worker       "//another_python_package/py/BUILD.bazel > another_python_package/BUILD.bazel",
543*61c4878aSAndroid Build Coastguard Worker     ]
544*61c4878aSAndroid Build Coastguard Worker     generate_setup_cfg = {
545*61c4878aSAndroid Build Coastguard Worker       common_config_file = "pypi_common_setup.cfg"
546*61c4878aSAndroid Build Coastguard Worker       append_git_sha_to_version = true
547*61c4878aSAndroid Build Coastguard Worker       append_date_to_version = true
548*61c4878aSAndroid Build Coastguard Worker     }
549*61c4878aSAndroid Build Coastguard Worker   }
550*61c4878aSAndroid Build Coastguard Worker
551*61c4878aSAndroid Build Coastguard Worker
552*61c4878aSAndroid Build Coastguard Worker.. code-block:: text
553*61c4878aSAndroid Build Coastguard Worker   :caption: :octicon:`file-directory;1em`
554*61c4878aSAndroid Build Coastguard Worker             ./out/obj/pw_env_setup/build_python_source_tree/
555*61c4878aSAndroid Build Coastguard Worker
556*61c4878aSAndroid Build Coastguard Worker   $ tree ./out/obj/pw_env_setup/build_python_source_tree/
557*61c4878aSAndroid Build Coastguard Worker   ├── README.md
558*61c4878aSAndroid Build Coastguard Worker   ├── setup.cfg
559*61c4878aSAndroid Build Coastguard Worker   ├── some_python_package
560*61c4878aSAndroid Build Coastguard Worker   │   ├── BUILD.bazel
561*61c4878aSAndroid Build Coastguard Worker   │   ├── __init__.py
562*61c4878aSAndroid Build Coastguard Worker   │   ├── py.typed
563*61c4878aSAndroid Build Coastguard Worker   │   ├── some_source_file.py
564*61c4878aSAndroid Build Coastguard Worker   │   └── tests
565*61c4878aSAndroid Build Coastguard Worker   │       └── some_source_test.py
566*61c4878aSAndroid Build Coastguard Worker   └── another_python_package
567*61c4878aSAndroid Build Coastguard Worker       ├── BUILD.bazel
568*61c4878aSAndroid Build Coastguard Worker       ├── __init__.py
569*61c4878aSAndroid Build Coastguard Worker       ├── another_source_file.py
570*61c4878aSAndroid Build Coastguard Worker       ├── py.typed
571*61c4878aSAndroid Build Coastguard Worker       └── tests
572*61c4878aSAndroid Build Coastguard Worker           └── another_source_test.py
573