xref: /aosp_15_r20/external/bazelbuild-rules_python/gazelle/README.md (revision 60517a1edbc8ecf509223e9af94a7adec7d736b8)
1*60517a1eSAndroid Build Coastguard Worker# Python Gazelle plugin
2*60517a1eSAndroid Build Coastguard Worker
3*60517a1eSAndroid Build Coastguard Worker[Gazelle](https://github.com/bazelbuild/bazel-gazelle)
4*60517a1eSAndroid Build Coastguard Workeris a build file generator for Bazel projects. It can create new BUILD.bazel files for a project that follows language conventions, and it can update existing build files to include new sources, dependencies, and options.
5*60517a1eSAndroid Build Coastguard Worker
6*60517a1eSAndroid Build Coastguard WorkerGazelle may be run by Bazel using the gazelle rule, or it may be installed and run as a command line tool.
7*60517a1eSAndroid Build Coastguard Worker
8*60517a1eSAndroid Build Coastguard WorkerThis directory contains a plugin for
9*60517a1eSAndroid Build Coastguard Worker[Gazelle](https://github.com/bazelbuild/bazel-gazelle)
10*60517a1eSAndroid Build Coastguard Workerthat generates BUILD files content for Python code. When Gazelle is run as a command line tool with this plugin, it embeds a Python interpreter resolved during the plugin build.
11*60517a1eSAndroid Build Coastguard WorkerThe behavior of the plugin is slightly different with different version of the interpreter as the Python `stdlib` changes with every minor version release.
12*60517a1eSAndroid Build Coastguard WorkerDistributors of Gazelle binaries should, therefore, build a Gazelle binary for each OS+CPU architecture+Minor Python version combination they are targeting.
13*60517a1eSAndroid Build Coastguard Worker
14*60517a1eSAndroid Build Coastguard WorkerThe following instructions are for when you use [bzlmod](https://docs.bazel.build/versions/5.0.0/bzlmod.html).
15*60517a1eSAndroid Build Coastguard WorkerPlease refer to older documentation that includes instructions on how to use Gazelle
16*60517a1eSAndroid Build Coastguard Workerwithout using bzlmod as your dependency manager.
17*60517a1eSAndroid Build Coastguard Worker
18*60517a1eSAndroid Build Coastguard Worker## Example
19*60517a1eSAndroid Build Coastguard Worker
20*60517a1eSAndroid Build Coastguard WorkerWe have an example of using Gazelle with Python located [here](https://github.com/bazelbuild/rules_python/tree/main/examples/bzlmod).
21*60517a1eSAndroid Build Coastguard WorkerA fully-working example without using bzlmod is in [`examples/build_file_generation`](../examples/build_file_generation).
22*60517a1eSAndroid Build Coastguard Worker
23*60517a1eSAndroid Build Coastguard WorkerThe following documentation covers using bzlmod.
24*60517a1eSAndroid Build Coastguard Worker
25*60517a1eSAndroid Build Coastguard Worker## Adding Gazelle to your project
26*60517a1eSAndroid Build Coastguard Worker
27*60517a1eSAndroid Build Coastguard WorkerFirst, you'll need to add Gazelle to your `MODULES.bazel` file.
28*60517a1eSAndroid Build Coastguard WorkerGet the current version of Gazelle from there releases here:  https://github.com/bazelbuild/bazel-gazelle/releases/.
29*60517a1eSAndroid Build Coastguard Worker
30*60517a1eSAndroid Build Coastguard Worker
31*60517a1eSAndroid Build Coastguard WorkerSee the installation `MODULE.bazel` snippet on the Releases page:
32*60517a1eSAndroid Build Coastguard Workerhttps://github.com/bazelbuild/rules_python/releases in order to configure rules_python.
33*60517a1eSAndroid Build Coastguard Worker
34*60517a1eSAndroid Build Coastguard WorkerYou will also need to add the `bazel_dep` for configuration for `rules_python_gazelle_plugin`.
35*60517a1eSAndroid Build Coastguard Worker
36*60517a1eSAndroid Build Coastguard WorkerHere is a snippet of a `MODULE.bazel` file.
37*60517a1eSAndroid Build Coastguard Worker
38*60517a1eSAndroid Build Coastguard Worker```starlark
39*60517a1eSAndroid Build Coastguard Worker# The following stanza defines the dependency rules_python.
40*60517a1eSAndroid Build Coastguard Workerbazel_dep(name = "rules_python", version = "0.22.0")
41*60517a1eSAndroid Build Coastguard Worker
42*60517a1eSAndroid Build Coastguard Worker# The following stanza defines the dependency rules_python_gazelle_plugin.
43*60517a1eSAndroid Build Coastguard Worker# For typical setups you set the version.
44*60517a1eSAndroid Build Coastguard Workerbazel_dep(name = "rules_python_gazelle_plugin", version = "0.22.0")
45*60517a1eSAndroid Build Coastguard Worker
46*60517a1eSAndroid Build Coastguard Worker# The following stanza defines the dependency gazelle.
47*60517a1eSAndroid Build Coastguard Workerbazel_dep(name = "gazelle", version = "0.31.0", repo_name = "bazel_gazelle")
48*60517a1eSAndroid Build Coastguard Worker
49*60517a1eSAndroid Build Coastguard Worker# Import the python repositories generated by the given module extension into the scope of the current module.
50*60517a1eSAndroid Build Coastguard Workeruse_repo(python, "python3_9")
51*60517a1eSAndroid Build Coastguard Workeruse_repo(python, "python3_9_toolchains")
52*60517a1eSAndroid Build Coastguard Worker
53*60517a1eSAndroid Build Coastguard Worker# Register an already-defined toolchain so that Bazel can use it during toolchain resolution.
54*60517a1eSAndroid Build Coastguard Workerregister_toolchains(
55*60517a1eSAndroid Build Coastguard Worker    "@python3_9_toolchains//:all",
56*60517a1eSAndroid Build Coastguard Worker)
57*60517a1eSAndroid Build Coastguard Worker
58*60517a1eSAndroid Build Coastguard Worker# Use the pip extension
59*60517a1eSAndroid Build Coastguard Workerpip = use_extension("@rules_python//python:extensions.bzl", "pip")
60*60517a1eSAndroid Build Coastguard Worker
61*60517a1eSAndroid Build Coastguard Worker# Use the extension to call the `pip_repository` rule that invokes `pip`, with `incremental` set.
62*60517a1eSAndroid Build Coastguard Worker# Accepts a locked/compiled requirements file and installs the dependencies listed within.
63*60517a1eSAndroid Build Coastguard Worker# Those dependencies become available in a generated `requirements.bzl` file.
64*60517a1eSAndroid Build Coastguard Worker# You can instead check this `requirements.bzl` file into your repo.
65*60517a1eSAndroid Build Coastguard Worker# Because this project has different requirements for windows vs other
66*60517a1eSAndroid Build Coastguard Worker# operating systems, we have requirements for each.
67*60517a1eSAndroid Build Coastguard Workerpip.parse(
68*60517a1eSAndroid Build Coastguard Worker    name = "pip",
69*60517a1eSAndroid Build Coastguard Worker    requirements_lock = "//:requirements_lock.txt",
70*60517a1eSAndroid Build Coastguard Worker    requirements_windows = "//:requirements_windows.txt",
71*60517a1eSAndroid Build Coastguard Worker)
72*60517a1eSAndroid Build Coastguard Worker
73*60517a1eSAndroid Build Coastguard Worker# Imports the pip toolchain generated by the given module extension into the scope of the current module.
74*60517a1eSAndroid Build Coastguard Workeruse_repo(pip, "pip")
75*60517a1eSAndroid Build Coastguard Worker```
76*60517a1eSAndroid Build Coastguard WorkerNext, we'll fetch metadata about your Python dependencies, so that gazelle can
77*60517a1eSAndroid Build Coastguard Workerdetermine which package a given import statement comes from. This is provided
78*60517a1eSAndroid Build Coastguard Workerby the `modules_mapping` rule. We'll make a target for consuming this
79*60517a1eSAndroid Build Coastguard Worker`modules_mapping`, and writing it as a manifest file for Gazelle to read.
80*60517a1eSAndroid Build Coastguard WorkerThis is checked into the repo for speed, as it takes some time to calculate
81*60517a1eSAndroid Build Coastguard Workerin a large monorepo.
82*60517a1eSAndroid Build Coastguard Worker
83*60517a1eSAndroid Build Coastguard WorkerGazelle will walk up the filesystem from a Python file to find this metadata,
84*60517a1eSAndroid Build Coastguard Workerlooking for a file called `gazelle_python.yaml` in an ancestor folder of the Python code.
85*60517a1eSAndroid Build Coastguard WorkerCreate an empty file with this name. It might be next to your `requirements.txt` file.
86*60517a1eSAndroid Build Coastguard Worker(You can just use `touch` at this point, it just needs to exist.)
87*60517a1eSAndroid Build Coastguard Worker
88*60517a1eSAndroid Build Coastguard WorkerTo keep the metadata updated, put this in your `BUILD.bazel` file next to `gazelle_python.yaml`:
89*60517a1eSAndroid Build Coastguard Worker
90*60517a1eSAndroid Build Coastguard Worker```starlark
91*60517a1eSAndroid Build Coastguard Workerload("@pip//:requirements.bzl", "all_whl_requirements")
92*60517a1eSAndroid Build Coastguard Workerload("@rules_python_gazelle_plugin//manifest:defs.bzl", "gazelle_python_manifest")
93*60517a1eSAndroid Build Coastguard Workerload("@rules_python_gazelle_plugin//modules_mapping:def.bzl", "modules_mapping")
94*60517a1eSAndroid Build Coastguard Worker
95*60517a1eSAndroid Build Coastguard Worker# This rule fetches the metadata for python packages we depend on. That data is
96*60517a1eSAndroid Build Coastguard Worker# required for the gazelle_python_manifest rule to update our manifest file.
97*60517a1eSAndroid Build Coastguard Workermodules_mapping(
98*60517a1eSAndroid Build Coastguard Worker    name = "modules_map",
99*60517a1eSAndroid Build Coastguard Worker    wheels = all_whl_requirements,
100*60517a1eSAndroid Build Coastguard Worker)
101*60517a1eSAndroid Build Coastguard Worker
102*60517a1eSAndroid Build Coastguard Worker# Gazelle python extension needs a manifest file mapping from
103*60517a1eSAndroid Build Coastguard Worker# an import to the installed package that provides it.
104*60517a1eSAndroid Build Coastguard Worker# This macro produces two targets:
105*60517a1eSAndroid Build Coastguard Worker# - //:gazelle_python_manifest.update can be used with `bazel run`
106*60517a1eSAndroid Build Coastguard Worker#   to recalculate the manifest
107*60517a1eSAndroid Build Coastguard Worker# - //:gazelle_python_manifest.test is a test target ensuring that
108*60517a1eSAndroid Build Coastguard Worker#   the manifest doesn't need to be updated
109*60517a1eSAndroid Build Coastguard Workergazelle_python_manifest(
110*60517a1eSAndroid Build Coastguard Worker    name = "gazelle_python_manifest",
111*60517a1eSAndroid Build Coastguard Worker    modules_mapping = ":modules_map",
112*60517a1eSAndroid Build Coastguard Worker    # This is what we called our `pip_parse` rule, where third-party
113*60517a1eSAndroid Build Coastguard Worker    # python libraries are loaded in BUILD files.
114*60517a1eSAndroid Build Coastguard Worker    pip_repository_name = "pip",
115*60517a1eSAndroid Build Coastguard Worker    # This should point to wherever we declare our python dependencies
116*60517a1eSAndroid Build Coastguard Worker    # (the same as what we passed to the modules_mapping rule in WORKSPACE)
117*60517a1eSAndroid Build Coastguard Worker    # This argument is optional. If provided, the `.test` target is very
118*60517a1eSAndroid Build Coastguard Worker    # fast because it just has to check an integrity field. If not provided,
119*60517a1eSAndroid Build Coastguard Worker    # the integrity field is not added to the manifest which can help avoid
120*60517a1eSAndroid Build Coastguard Worker    # merge conflicts in large repos.
121*60517a1eSAndroid Build Coastguard Worker    requirements = "//:requirements_lock.txt",
122*60517a1eSAndroid Build Coastguard Worker)
123*60517a1eSAndroid Build Coastguard Worker```
124*60517a1eSAndroid Build Coastguard Worker
125*60517a1eSAndroid Build Coastguard WorkerFinally, you create a target that you'll invoke to run the Gazelle tool
126*60517a1eSAndroid Build Coastguard Workerwith the rules_python extension included. This typically goes in your root
127*60517a1eSAndroid Build Coastguard Worker`/BUILD.bazel` file:
128*60517a1eSAndroid Build Coastguard Worker
129*60517a1eSAndroid Build Coastguard Worker```starlark
130*60517a1eSAndroid Build Coastguard Workerload("@bazel_gazelle//:def.bzl", "gazelle")
131*60517a1eSAndroid Build Coastguard Worker
132*60517a1eSAndroid Build Coastguard Worker# Our gazelle target points to the python gazelle binary.
133*60517a1eSAndroid Build Coastguard Worker# This is the simple case where we only need one language supported.
134*60517a1eSAndroid Build Coastguard Worker# If you also had proto, go, or other gazelle-supported languages,
135*60517a1eSAndroid Build Coastguard Worker# you would also need a gazelle_binary rule.
136*60517a1eSAndroid Build Coastguard Worker# See https://github.com/bazelbuild/bazel-gazelle/blob/master/extend.rst#example
137*60517a1eSAndroid Build Coastguard Workergazelle(
138*60517a1eSAndroid Build Coastguard Worker    name = "gazelle",
139*60517a1eSAndroid Build Coastguard Worker    gazelle = "@rules_python_gazelle_plugin//python:gazelle_binary",
140*60517a1eSAndroid Build Coastguard Worker)
141*60517a1eSAndroid Build Coastguard Worker```
142*60517a1eSAndroid Build Coastguard Worker
143*60517a1eSAndroid Build Coastguard WorkerThat's it, now you can finally run `bazel run //:gazelle` anytime
144*60517a1eSAndroid Build Coastguard Workeryou edit Python code, and it should update your `BUILD` files correctly.
145*60517a1eSAndroid Build Coastguard Worker
146*60517a1eSAndroid Build Coastguard Worker## Usage
147*60517a1eSAndroid Build Coastguard Worker
148*60517a1eSAndroid Build Coastguard WorkerGazelle is non-destructive.
149*60517a1eSAndroid Build Coastguard WorkerIt will try to leave your edits to BUILD files alone, only making updates to `py_*` targets.
150*60517a1eSAndroid Build Coastguard WorkerHowever it will remove dependencies that appear to be unused, so it's a
151*60517a1eSAndroid Build Coastguard Workergood idea to check in your work before running Gazelle so you can easily
152*60517a1eSAndroid Build Coastguard Workerrevert any changes it made.
153*60517a1eSAndroid Build Coastguard Worker
154*60517a1eSAndroid Build Coastguard WorkerThe rules_python extension assumes some conventions about your Python code.
155*60517a1eSAndroid Build Coastguard WorkerThese are noted below, and might require changes to your existing code.
156*60517a1eSAndroid Build Coastguard Worker
157*60517a1eSAndroid Build Coastguard WorkerNote that the `gazelle` program has multiple commands. At present, only the `update` command (the default) does anything for Python code.
158*60517a1eSAndroid Build Coastguard Worker
159*60517a1eSAndroid Build Coastguard Worker### Directives
160*60517a1eSAndroid Build Coastguard Worker
161*60517a1eSAndroid Build Coastguard WorkerYou can configure the extension using directives, just like for other
162*60517a1eSAndroid Build Coastguard Workerlanguages. These are just comments in the `BUILD.bazel` file which
163*60517a1eSAndroid Build Coastguard Workergovern behavior of the extension when processing files under that
164*60517a1eSAndroid Build Coastguard Workerfolder.
165*60517a1eSAndroid Build Coastguard Worker
166*60517a1eSAndroid Build Coastguard WorkerSee https://github.com/bazelbuild/bazel-gazelle#directives
167*60517a1eSAndroid Build Coastguard Workerfor some general directives that may be useful.
168*60517a1eSAndroid Build Coastguard WorkerIn particular, the `resolve` directive is language-specific
169*60517a1eSAndroid Build Coastguard Workerand can be used with Python.
170*60517a1eSAndroid Build Coastguard WorkerExamples of these directives in use can be found in the
171*60517a1eSAndroid Build Coastguard Worker/gazelle/testdata folder in the rules_python repo.
172*60517a1eSAndroid Build Coastguard Worker
173*60517a1eSAndroid Build Coastguard WorkerPython-specific directives are as follows:
174*60517a1eSAndroid Build Coastguard Worker
175*60517a1eSAndroid Build Coastguard Worker| **Directive**                                                                                                                                                                                                                                                                                   | **Default value** |
176*60517a1eSAndroid Build Coastguard Worker|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
177*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_extension`                                                                                                                                                                                                                                                                    |   `enabled`       |
178*60517a1eSAndroid Build Coastguard Worker| Controls whether the Python extension is enabled or not. Sub-packages inherit this value. Can be either "enabled" or "disabled".                                                                                                                                                                | |
179*60517a1eSAndroid Build Coastguard Worker| [`# gazelle:python_root`](#directive-python_root)                                                                                                                                                                                                                                               |    n/a            |
180*60517a1eSAndroid Build Coastguard Worker| Sets a Bazel package as a Python root. This is used on monorepos with multiple Python projects that don't share the top-level of the workspace as the root. See [Directive: `python_root`](#directive-python_root) below.                                                                       | |
181*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_manifest_file_name`                                                                                                                                                                                                                                                           | `gazelle_python.yaml` |
182*60517a1eSAndroid Build Coastguard Worker| Overrides the default manifest file name.                                                                                                                                                                                                                                                       | |
183*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_ignore_files`                                                                                                                                                                                                                                                                 |     n/a           |
184*60517a1eSAndroid Build Coastguard Worker| Controls the files which are ignored from the generated targets.                                                                                                                                                                                                                                | |
185*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_ignore_dependencies`                                                                                                                                                                                                                                                          |    n/a           |
186*60517a1eSAndroid Build Coastguard Worker| Controls the ignored dependencies from the generated targets.                                                                                                                                                                                                                                   | |
187*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_validate_import_statements`                                                                                                                                                                                                                                                   | `true` |
188*60517a1eSAndroid Build Coastguard Worker| Controls whether the Python import statements should be validated. Can be "true" or "false"                                                                                                                                                                                                     | |
189*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_generation_mode`                                                                                                                                                                                                                                                              | `package` |
190*60517a1eSAndroid Build Coastguard Worker| Controls the target generation mode. Can be "file", "package", or "project"                                                                                                                                                                                                                     | |
191*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_generation_mode_per_file_include_init`                                                                                                                                                                                                                                        | `false` |
192*60517a1eSAndroid Build Coastguard Worker| Controls whether `__init__.py` files are included as srcs in each generated target when target generation mode is "file". Can be "true", or "false"                                                                                                                                             | |
193*60517a1eSAndroid Build Coastguard Worker| [`# gazelle:python_generation_mode_per_package_require_test_entry_point`](#directive-python_generation_mode_per_package_require_test_entry_point)                                                                                                                                               | `true` |
194*60517a1eSAndroid Build Coastguard Worker| Controls whether a file called `__test__.py` or a target called `__test__` is required to generate one test target per package in package mode.                                                                                                                                                 ||
195*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_library_naming_convention`                                                                                                                                                                                                                                                    | `$package_name$` |
196*60517a1eSAndroid Build Coastguard Worker| Controls the `py_library` naming convention. It interpolates `$package_name$` with the Bazel package name. E.g. if the Bazel package name is `foo`, setting this to `$package_name$_my_lib` would result in a generated target named `foo_my_lib`.                                              | |
197*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_binary_naming_convention`                                                                                                                                                                                                                                                     | `$package_name$_bin` |
198*60517a1eSAndroid Build Coastguard Worker| Controls the `py_binary` naming convention. Follows the same interpolation rules as `python_library_naming_convention`.                                                                                                                                                                         | |
199*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_test_naming_convention`                                                                                                                                                                                                                                                       | `$package_name$_test` |
200*60517a1eSAndroid Build Coastguard Worker| Controls the `py_test` naming convention. Follows the same interpolation rules as `python_library_naming_convention`.                                                                                                                                                                           | |
201*60517a1eSAndroid Build Coastguard Worker| `# gazelle:resolve py ...`                                                                                                                                                                                                                                                                      | n/a |
202*60517a1eSAndroid Build Coastguard Worker| Instructs the plugin what target to add as a dependency to satisfy a given import statement. The syntax is `# gazelle:resolve py import-string label` where `import-string` is the symbol in the python `import` statement, and `label` is the Bazel label that Gazelle should write in `deps`. | |
203*60517a1eSAndroid Build Coastguard Worker| [`# gazelle:python_default_visibility labels`](#directive-python_default_visibility)                                                                                                                                                                                                            | |
204*60517a1eSAndroid Build Coastguard Worker| Instructs gazelle to use these visibility labels on all python targets. `labels` is a comma-separated list of labels (without spaces).                                                                                                                                                          | `//$python_root$:__subpackages__` |
205*60517a1eSAndroid Build Coastguard Worker| [`# gazelle:python_visibility label`](#directive-python_visibility)                                                                                                                                                                                                                             | |
206*60517a1eSAndroid Build Coastguard Worker| Appends additional visibility labels to each generated target. This directive can be set multiple times.                                                                                                                                                                                        | |
207*60517a1eSAndroid Build Coastguard Worker| [`# gazelle:python_test_file_pattern`](#directive-python_test_file_pattern)                                                                                                                                                                                                                     | `*_test.py,test_*.py` |
208*60517a1eSAndroid Build Coastguard Worker| Filenames matching these comma-separated `glob`s will be mapped to `py_test` targets.                                                                                                                                                                                                           |
209*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_label_convention`                                                                                                                                                                                                                                                             | `$distribution_name$` |
210*60517a1eSAndroid Build Coastguard Worker| Defines the format of the distribution name in labels to third-party deps. Useful for using Gazelle plugin with other rules with different repository conventions (e.g. `rules_pycross`). Full label is always prepended with (pip) repository name, e.g. `@pip//numpy`.                        |
211*60517a1eSAndroid Build Coastguard Worker| `# gazelle:python_label_normalization`                                                                                                                                                                                                                                                          | `snake_case` |
212*60517a1eSAndroid Build Coastguard Worker| Controls how distribution names in labels to third-party deps are normalized. Useful for using Gazelle plugin with other rules with different label conventions (e.g. `rules_pycross` uses PEP-503). Can be "snake_case", "none", or "pep503".                                                  |
213*60517a1eSAndroid Build Coastguard Worker
214*60517a1eSAndroid Build Coastguard Worker#### Directive: `python_root`:
215*60517a1eSAndroid Build Coastguard Worker
216*60517a1eSAndroid Build Coastguard WorkerSet this directive within the Bazel package that you want to use as the Python root.
217*60517a1eSAndroid Build Coastguard WorkerFor example, if using a `src` dir (as recommended by the [Python Packaging User
218*60517a1eSAndroid Build Coastguard WorkerGuide][python-packaging-user-guide]), then set this directive in `src/BUILD.bazel`:
219*60517a1eSAndroid Build Coastguard Worker
220*60517a1eSAndroid Build Coastguard Worker```starlark
221*60517a1eSAndroid Build Coastguard Worker# ./src/BUILD.bazel
222*60517a1eSAndroid Build Coastguard Worker# Tell gazelle that are python root is the same dir as this Bazel package.
223*60517a1eSAndroid Build Coastguard Worker# gazelle:python_root
224*60517a1eSAndroid Build Coastguard Worker```
225*60517a1eSAndroid Build Coastguard Worker
226*60517a1eSAndroid Build Coastguard WorkerNote that the directive does not have any arguments.
227*60517a1eSAndroid Build Coastguard Worker
228*60517a1eSAndroid Build Coastguard WorkerGazelle will then add the necessary `imports` attribute to all targets that it
229*60517a1eSAndroid Build Coastguard Workergenerates:
230*60517a1eSAndroid Build Coastguard Worker
231*60517a1eSAndroid Build Coastguard Worker```starlark
232*60517a1eSAndroid Build Coastguard Worker# in ./src/foo/BUILD.bazel
233*60517a1eSAndroid Build Coastguard Workerpy_libary(
234*60517a1eSAndroid Build Coastguard Worker    ...
235*60517a1eSAndroid Build Coastguard Worker    imports = [".."],  # Gazelle adds this
236*60517a1eSAndroid Build Coastguard Worker    ...
237*60517a1eSAndroid Build Coastguard Worker)
238*60517a1eSAndroid Build Coastguard Worker
239*60517a1eSAndroid Build Coastguard Worker# in ./src/foo/bar/BUILD.bazel
240*60517a1eSAndroid Build Coastguard Workerpy_libary(
241*60517a1eSAndroid Build Coastguard Worker    ...
242*60517a1eSAndroid Build Coastguard Worker    imports = ["../.."],  # Gazelle adds this
243*60517a1eSAndroid Build Coastguard Worker    ...
244*60517a1eSAndroid Build Coastguard Worker)
245*60517a1eSAndroid Build Coastguard Worker```
246*60517a1eSAndroid Build Coastguard Worker
247*60517a1eSAndroid Build Coastguard Worker[python-packaging-user-guide]: https://github.com/pypa/packaging.python.org/blob/4c86169a/source/tutorials/packaging-projects.rst
248*60517a1eSAndroid Build Coastguard Worker
249*60517a1eSAndroid Build Coastguard Worker
250*60517a1eSAndroid Build Coastguard Worker#### Directive: `python_default_visibility`:
251*60517a1eSAndroid Build Coastguard Worker
252*60517a1eSAndroid Build Coastguard WorkerInstructs gazelle to use these visibility labels on all _python_ targets
253*60517a1eSAndroid Build Coastguard Worker(typically `py_*`, but can be modified via the `map_kind` directive). The arg
254*60517a1eSAndroid Build Coastguard Workerto this directive is a a comma-separated list (without spaces) of labels.
255*60517a1eSAndroid Build Coastguard Worker
256*60517a1eSAndroid Build Coastguard WorkerFor example:
257*60517a1eSAndroid Build Coastguard Worker
258*60517a1eSAndroid Build Coastguard Worker```starlark
259*60517a1eSAndroid Build Coastguard Worker# gazelle:python_default_visibility //:__subpackages__,//tests:__subpackages__
260*60517a1eSAndroid Build Coastguard Worker```
261*60517a1eSAndroid Build Coastguard Worker
262*60517a1eSAndroid Build Coastguard Workerproduces the following visibility attribute:
263*60517a1eSAndroid Build Coastguard Worker
264*60517a1eSAndroid Build Coastguard Worker```starlark
265*60517a1eSAndroid Build Coastguard Workerpy_library(
266*60517a1eSAndroid Build Coastguard Worker    ...,
267*60517a1eSAndroid Build Coastguard Worker    visibility = [
268*60517a1eSAndroid Build Coastguard Worker        "//:__subpackages__",
269*60517a1eSAndroid Build Coastguard Worker        "//tests:__subpackages__",
270*60517a1eSAndroid Build Coastguard Worker    ],
271*60517a1eSAndroid Build Coastguard Worker    ...,
272*60517a1eSAndroid Build Coastguard Worker)
273*60517a1eSAndroid Build Coastguard Worker```
274*60517a1eSAndroid Build Coastguard Worker
275*60517a1eSAndroid Build Coastguard WorkerYou can also inject the `python_root` value by using the exact string
276*60517a1eSAndroid Build Coastguard Worker`$python_root$`. All instances of this string will be replaced by the `python_root`
277*60517a1eSAndroid Build Coastguard Workervalue.
278*60517a1eSAndroid Build Coastguard Worker
279*60517a1eSAndroid Build Coastguard Worker```starlark
280*60517a1eSAndroid Build Coastguard Worker# gazelle:python_default_visibility //$python_root$:__pkg__,//foo/$python_root$/tests:__subpackages__
281*60517a1eSAndroid Build Coastguard Worker
282*60517a1eSAndroid Build Coastguard Worker# Assuming the "# gazelle:python_root" directive is set in ./py/src/BUILD.bazel,
283*60517a1eSAndroid Build Coastguard Worker# the results will be:
284*60517a1eSAndroid Build Coastguard Workerpy_library(
285*60517a1eSAndroid Build Coastguard Worker    ...,
286*60517a1eSAndroid Build Coastguard Worker    visibility = [
287*60517a1eSAndroid Build Coastguard Worker        "//foo/py/src/tests:__subpackages__",  # sorted alphabetically
288*60517a1eSAndroid Build Coastguard Worker        "//py/src:__pkg__",
289*60517a1eSAndroid Build Coastguard Worker    ],
290*60517a1eSAndroid Build Coastguard Worker    ...,
291*60517a1eSAndroid Build Coastguard Worker)
292*60517a1eSAndroid Build Coastguard Worker```
293*60517a1eSAndroid Build Coastguard Worker
294*60517a1eSAndroid Build Coastguard WorkerTwo special values are also accepted as an argument to the directive:
295*60517a1eSAndroid Build Coastguard Worker
296*60517a1eSAndroid Build Coastguard Worker+   `NONE`: This removes all default visibility. Labels added by the
297*60517a1eSAndroid Build Coastguard Worker    `python_visibility` directive are still included.
298*60517a1eSAndroid Build Coastguard Worker+   `DEFAULT`: This resets the default visibility.
299*60517a1eSAndroid Build Coastguard Worker
300*60517a1eSAndroid Build Coastguard WorkerFor example:
301*60517a1eSAndroid Build Coastguard Worker
302*60517a1eSAndroid Build Coastguard Worker```starlark
303*60517a1eSAndroid Build Coastguard Worker# gazelle:python_default_visibility NONE
304*60517a1eSAndroid Build Coastguard Worker
305*60517a1eSAndroid Build Coastguard Workerpy_library(
306*60517a1eSAndroid Build Coastguard Worker    name = "...",
307*60517a1eSAndroid Build Coastguard Worker    srcs = [...],
308*60517a1eSAndroid Build Coastguard Worker)
309*60517a1eSAndroid Build Coastguard Worker```
310*60517a1eSAndroid Build Coastguard Worker
311*60517a1eSAndroid Build Coastguard Worker```starlark
312*60517a1eSAndroid Build Coastguard Worker# gazelle:python_default_visibility //foo:bar
313*60517a1eSAndroid Build Coastguard Worker# gazelle:python_default_visibility DEFAULT
314*60517a1eSAndroid Build Coastguard Worker
315*60517a1eSAndroid Build Coastguard Workerpy_library(
316*60517a1eSAndroid Build Coastguard Worker    ...,
317*60517a1eSAndroid Build Coastguard Worker    visibility = ["//:__subpackages__"],
318*60517a1eSAndroid Build Coastguard Worker    ...,
319*60517a1eSAndroid Build Coastguard Worker)
320*60517a1eSAndroid Build Coastguard Worker```
321*60517a1eSAndroid Build Coastguard Worker
322*60517a1eSAndroid Build Coastguard WorkerThese special values can be useful for sub-packages.
323*60517a1eSAndroid Build Coastguard Worker
324*60517a1eSAndroid Build Coastguard Worker
325*60517a1eSAndroid Build Coastguard Worker#### Directive: `python_visibility`:
326*60517a1eSAndroid Build Coastguard Worker
327*60517a1eSAndroid Build Coastguard WorkerAppends additional `visibility` labels to each generated target.
328*60517a1eSAndroid Build Coastguard Worker
329*60517a1eSAndroid Build Coastguard WorkerThis directive can be set multiple times. The generated `visibility` attribute
330*60517a1eSAndroid Build Coastguard Workerwill include the default visibility and all labels defined by this directive.
331*60517a1eSAndroid Build Coastguard WorkerAll labels will be ordered alphabetically.
332*60517a1eSAndroid Build Coastguard Worker
333*60517a1eSAndroid Build Coastguard Worker```starlark
334*60517a1eSAndroid Build Coastguard Worker# ./BUILD.bazel
335*60517a1eSAndroid Build Coastguard Worker# gazelle:python_visibility //tests:__pkg__
336*60517a1eSAndroid Build Coastguard Worker# gazelle:python_visibility //bar:baz
337*60517a1eSAndroid Build Coastguard Worker
338*60517a1eSAndroid Build Coastguard Workerpy_library(
339*60517a1eSAndroid Build Coastguard Worker   ...
340*60517a1eSAndroid Build Coastguard Worker   visibility = [
341*60517a1eSAndroid Build Coastguard Worker       "//:__subpackages__",  # default visibility
342*60517a1eSAndroid Build Coastguard Worker       "//bar:baz",
343*60517a1eSAndroid Build Coastguard Worker       "//tests:__pkg__",
344*60517a1eSAndroid Build Coastguard Worker   ],
345*60517a1eSAndroid Build Coastguard Worker   ...
346*60517a1eSAndroid Build Coastguard Worker)
347*60517a1eSAndroid Build Coastguard Worker```
348*60517a1eSAndroid Build Coastguard Worker
349*60517a1eSAndroid Build Coastguard WorkerChild Bazel packages inherit values from parents:
350*60517a1eSAndroid Build Coastguard Worker
351*60517a1eSAndroid Build Coastguard Worker```starlark
352*60517a1eSAndroid Build Coastguard Worker# ./bar/BUILD.bazel
353*60517a1eSAndroid Build Coastguard Worker# gazelle:python_visibility //tests:__subpackages__
354*60517a1eSAndroid Build Coastguard Worker
355*60517a1eSAndroid Build Coastguard Workerpy_library(
356*60517a1eSAndroid Build Coastguard Worker   ...
357*60517a1eSAndroid Build Coastguard Worker   visibility = [
358*60517a1eSAndroid Build Coastguard Worker       "//:__subpackages__",       # default visibility
359*60517a1eSAndroid Build Coastguard Worker       "//bar:baz",                # defined in ../BUILD.bazel
360*60517a1eSAndroid Build Coastguard Worker       "//tests:__pkg__",          # defined in ../BUILD.bazel
361*60517a1eSAndroid Build Coastguard Worker       "//tests:__subpackages__",  # defined in this ./BUILD.bazel
362*60517a1eSAndroid Build Coastguard Worker   ],
363*60517a1eSAndroid Build Coastguard Worker   ...
364*60517a1eSAndroid Build Coastguard Worker)
365*60517a1eSAndroid Build Coastguard Worker
366*60517a1eSAndroid Build Coastguard Worker```
367*60517a1eSAndroid Build Coastguard Worker
368*60517a1eSAndroid Build Coastguard WorkerThis directive also supports the `$python_root$` placeholder that
369*60517a1eSAndroid Build Coastguard Worker`# gazelle:python_default_visibility` supports.
370*60517a1eSAndroid Build Coastguard Worker
371*60517a1eSAndroid Build Coastguard Worker```starlark
372*60517a1eSAndroid Build Coastguard Worker# gazlle:python_visibility //$python_root$/foo:bar
373*60517a1eSAndroid Build Coastguard Worker
374*60517a1eSAndroid Build Coastguard Workerpy_library(
375*60517a1eSAndroid Build Coastguard Worker    ...
376*60517a1eSAndroid Build Coastguard Worker    visibility = ["//this_is_my_python_root/foo:bar"],
377*60517a1eSAndroid Build Coastguard Worker    ...
378*60517a1eSAndroid Build Coastguard Worker)
379*60517a1eSAndroid Build Coastguard Worker```
380*60517a1eSAndroid Build Coastguard Worker
381*60517a1eSAndroid Build Coastguard Worker
382*60517a1eSAndroid Build Coastguard Worker#### Directive: `python_test_file_pattern`:
383*60517a1eSAndroid Build Coastguard Worker
384*60517a1eSAndroid Build Coastguard WorkerThis directive adjusts which python files will be mapped to the `py_test` rule.
385*60517a1eSAndroid Build Coastguard Worker
386*60517a1eSAndroid Build Coastguard Worker+ The default is `*_test.py,test_*.py`: both `test_*.py` and `*_test.py` files
387*60517a1eSAndroid Build Coastguard Worker  will generate `py_test` targets.
388*60517a1eSAndroid Build Coastguard Worker+ This directive must have a value. If no value is given, an error will be raised.
389*60517a1eSAndroid Build Coastguard Worker+ It is recommended, though not necessary, to include the `.py` extension in
390*60517a1eSAndroid Build Coastguard Worker  the `glob`s: `foo*.py,?at.py`.
391*60517a1eSAndroid Build Coastguard Worker+ Like most directives, it applies to the current Bazel package and all subpackages
392*60517a1eSAndroid Build Coastguard Worker  until the directive is set again.
393*60517a1eSAndroid Build Coastguard Worker+ This directive accepts multiple `glob` patterns, separated by commas without spaces:
394*60517a1eSAndroid Build Coastguard Worker
395*60517a1eSAndroid Build Coastguard Worker```starlark
396*60517a1eSAndroid Build Coastguard Worker# gazelle:python_test_file_pattern foo*.py,?at
397*60517a1eSAndroid Build Coastguard Worker
398*60517a1eSAndroid Build Coastguard Workerpy_library(
399*60517a1eSAndroid Build Coastguard Worker    name = "mylib",
400*60517a1eSAndroid Build Coastguard Worker    srcs = ["mylib.py"],
401*60517a1eSAndroid Build Coastguard Worker)
402*60517a1eSAndroid Build Coastguard Worker
403*60517a1eSAndroid Build Coastguard Workerpy_test(
404*60517a1eSAndroid Build Coastguard Worker    name = "foo_bar",
405*60517a1eSAndroid Build Coastguard Worker    srcs = ["foo_bar.py"],
406*60517a1eSAndroid Build Coastguard Worker)
407*60517a1eSAndroid Build Coastguard Worker
408*60517a1eSAndroid Build Coastguard Workerpy_test(
409*60517a1eSAndroid Build Coastguard Worker    name = "cat",
410*60517a1eSAndroid Build Coastguard Worker    srcs = ["cat.py"],
411*60517a1eSAndroid Build Coastguard Worker)
412*60517a1eSAndroid Build Coastguard Worker
413*60517a1eSAndroid Build Coastguard Workerpy_test(
414*60517a1eSAndroid Build Coastguard Worker    name = "hat",
415*60517a1eSAndroid Build Coastguard Worker    srcs = ["hat.py"],
416*60517a1eSAndroid Build Coastguard Worker)
417*60517a1eSAndroid Build Coastguard Worker```
418*60517a1eSAndroid Build Coastguard Worker
419*60517a1eSAndroid Build Coastguard Worker
420*60517a1eSAndroid Build Coastguard Worker##### Notes
421*60517a1eSAndroid Build Coastguard Worker
422*60517a1eSAndroid Build Coastguard WorkerResetting to the default value (such as in a subpackage) is manual. Set:
423*60517a1eSAndroid Build Coastguard Worker
424*60517a1eSAndroid Build Coastguard Worker```starlark
425*60517a1eSAndroid Build Coastguard Worker# gazelle:python_test_file_pattern *_test.py,test_*.py
426*60517a1eSAndroid Build Coastguard Worker```
427*60517a1eSAndroid Build Coastguard Worker
428*60517a1eSAndroid Build Coastguard WorkerThere currently is no way to tell gazelle that _no_ files in a package should
429*60517a1eSAndroid Build Coastguard Workerbe mapped to `py_test` targets (see [Issue #1826][issue-1826]). The workaround
430*60517a1eSAndroid Build Coastguard Workeris to set this directive to a pattern that will never match a `.py` file, such
431*60517a1eSAndroid Build Coastguard Workeras `foo.bar`:
432*60517a1eSAndroid Build Coastguard Worker
433*60517a1eSAndroid Build Coastguard Worker```starlark
434*60517a1eSAndroid Build Coastguard Worker# No files in this package should be mapped to py_test targets.
435*60517a1eSAndroid Build Coastguard Worker# gazelle:python_test_file_pattern foo.bar
436*60517a1eSAndroid Build Coastguard Worker
437*60517a1eSAndroid Build Coastguard Workerpy_library(
438*60517a1eSAndroid Build Coastguard Worker    name = "my_test",
439*60517a1eSAndroid Build Coastguard Worker    srcs = ["my_test.py"],
440*60517a1eSAndroid Build Coastguard Worker)
441*60517a1eSAndroid Build Coastguard Worker```
442*60517a1eSAndroid Build Coastguard Worker
443*60517a1eSAndroid Build Coastguard Worker[issue-1826]: https://github.com/bazelbuild/rules_python/issues/1826
444*60517a1eSAndroid Build Coastguard Worker
445*60517a1eSAndroid Build Coastguard Worker#### Directive: `python_generation_mode_per_package_require_test_entry_point`:
446*60517a1eSAndroid Build Coastguard WorkerWhen `# gazelle:python_generation_mode package`, whether a file called `__test__.py` or a target called `__test__`, a.k.a., entry point, is required to generate one test target per package. If this is set to true but no entry point is found, Gazelle will fall back to file mode and generate one test target per file. Setting this directive to false forces Gazelle to generate one test target per package even without entry point. However, this means the `main` attribute of the `py_test` will not be set and the target will not be runnable unless either:
447*60517a1eSAndroid Build Coastguard Worker1. there happen to be a file in the `srcs` with the same name as the `py_test` target, or
448*60517a1eSAndroid Build Coastguard Worker2. a macro populating the `main` attribute of `py_test` is configured with `gazelle:map_kind` to replace `py_test` when Gazelle is generating Python test targets. For example, user can provide such a macro to Gazelle:
449*60517a1eSAndroid Build Coastguard Worker
450*60517a1eSAndroid Build Coastguard Worker```starlark
451*60517a1eSAndroid Build Coastguard Workerload("@rules_python//python:defs.bzl", _py_test="py_test")
452*60517a1eSAndroid Build Coastguard Workerload("@aspect_rules_py//py:defs.bzl", "py_pytest_main")
453*60517a1eSAndroid Build Coastguard Worker
454*60517a1eSAndroid Build Coastguard Workerdef py_test(name, main=None, **kwargs):
455*60517a1eSAndroid Build Coastguard Worker    deps = kwargs.pop("deps", [])
456*60517a1eSAndroid Build Coastguard Worker    if not main:
457*60517a1eSAndroid Build Coastguard Worker        py_pytest_main(
458*60517a1eSAndroid Build Coastguard Worker            name = "__test__",
459*60517a1eSAndroid Build Coastguard Worker            deps = ["@pip_pytest//:pkg"],  # change this to the pytest target in your repo.
460*60517a1eSAndroid Build Coastguard Worker        )
461*60517a1eSAndroid Build Coastguard Worker
462*60517a1eSAndroid Build Coastguard Worker        deps.append(":__test__")
463*60517a1eSAndroid Build Coastguard Worker        main = ":__test__.py"
464*60517a1eSAndroid Build Coastguard Worker
465*60517a1eSAndroid Build Coastguard Worker    _py_test(
466*60517a1eSAndroid Build Coastguard Worker        name = name,
467*60517a1eSAndroid Build Coastguard Worker        main = main,
468*60517a1eSAndroid Build Coastguard Worker        deps = deps,
469*60517a1eSAndroid Build Coastguard Worker        **kwargs,
470*60517a1eSAndroid Build Coastguard Worker)
471*60517a1eSAndroid Build Coastguard Worker```
472*60517a1eSAndroid Build Coastguard Worker
473*60517a1eSAndroid Build Coastguard Worker### Annotations
474*60517a1eSAndroid Build Coastguard Worker
475*60517a1eSAndroid Build Coastguard Worker*Annotations* refer to comments found _within Python files_ that configure how
476*60517a1eSAndroid Build Coastguard WorkerGazelle acts for that particular file.
477*60517a1eSAndroid Build Coastguard Worker
478*60517a1eSAndroid Build Coastguard WorkerAnnotations have the form:
479*60517a1eSAndroid Build Coastguard Worker
480*60517a1eSAndroid Build Coastguard Worker```python
481*60517a1eSAndroid Build Coastguard Worker# gazelle:annotation_name value
482*60517a1eSAndroid Build Coastguard Worker```
483*60517a1eSAndroid Build Coastguard Worker
484*60517a1eSAndroid Build Coastguard Workerand can reside anywhere within a Python file where comments are valid. For example:
485*60517a1eSAndroid Build Coastguard Worker
486*60517a1eSAndroid Build Coastguard Worker```python
487*60517a1eSAndroid Build Coastguard Workerimport foo
488*60517a1eSAndroid Build Coastguard Worker# gazelle:annotation_name value
489*60517a1eSAndroid Build Coastguard Worker
490*60517a1eSAndroid Build Coastguard Workerdef bar():  # gazelle:annotation_name value
491*60517a1eSAndroid Build Coastguard Worker    pass
492*60517a1eSAndroid Build Coastguard Worker```
493*60517a1eSAndroid Build Coastguard Worker
494*60517a1eSAndroid Build Coastguard WorkerThe annotations are:
495*60517a1eSAndroid Build Coastguard Worker
496*60517a1eSAndroid Build Coastguard Worker| **Annotation**                                                | **Default value** |
497*60517a1eSAndroid Build Coastguard Worker|---------------------------------------------------------------|-------------------|
498*60517a1eSAndroid Build Coastguard Worker| [`# gazelle:ignore imports`](#annotation-ignore)              | N/A               |
499*60517a1eSAndroid Build Coastguard Worker| Tells Gazelle to ignore import statements. `imports` is a comma-separated list of imports to ignore. | |
500*60517a1eSAndroid Build Coastguard Worker| [`# gazelle:include_dep targets`](#annotation-include_dep)    | N/A               |
501*60517a1eSAndroid Build Coastguard Worker| Tells Gazelle to include a set of dependencies, even if they are not imported in a Python module. `targets` is a comma-separated list of target names to include as dependencies. | |
502*60517a1eSAndroid Build Coastguard Worker
503*60517a1eSAndroid Build Coastguard Worker
504*60517a1eSAndroid Build Coastguard Worker#### Annotation: `ignore`
505*60517a1eSAndroid Build Coastguard Worker
506*60517a1eSAndroid Build Coastguard WorkerThis annotation accepts a comma-separated string of values. Values are names of Python
507*60517a1eSAndroid Build Coastguard Workerimports that Gazelle should _not_ include in target dependencies.
508*60517a1eSAndroid Build Coastguard Worker
509*60517a1eSAndroid Build Coastguard WorkerThe annotation can be added multiple times, and all values are combined and
510*60517a1eSAndroid Build Coastguard Workerde-duplicated.
511*60517a1eSAndroid Build Coastguard Worker
512*60517a1eSAndroid Build Coastguard WorkerFor `python_generation_mode = "package"`, the `ignore` annotations
513*60517a1eSAndroid Build Coastguard Workerfound across all files included in the generated target are removed from `deps`.
514*60517a1eSAndroid Build Coastguard Worker
515*60517a1eSAndroid Build Coastguard WorkerExample:
516*60517a1eSAndroid Build Coastguard Worker
517*60517a1eSAndroid Build Coastguard Worker```python
518*60517a1eSAndroid Build Coastguard Workerimport numpy  # a pypi package
519*60517a1eSAndroid Build Coastguard Worker
520*60517a1eSAndroid Build Coastguard Worker# gazelle:ignore bar.baz.hello,foo
521*60517a1eSAndroid Build Coastguard Workerimport bar.baz.hello
522*60517a1eSAndroid Build Coastguard Workerimport foo
523*60517a1eSAndroid Build Coastguard Worker
524*60517a1eSAndroid Build Coastguard Worker# Ignore this import because _reasons_
525*60517a1eSAndroid Build Coastguard Workerimport baz  # gazelle:ignore baz
526*60517a1eSAndroid Build Coastguard Worker```
527*60517a1eSAndroid Build Coastguard Worker
528*60517a1eSAndroid Build Coastguard Workerwill cause Gazelle to generate:
529*60517a1eSAndroid Build Coastguard Worker
530*60517a1eSAndroid Build Coastguard Worker```starlark
531*60517a1eSAndroid Build Coastguard Workerdeps = ["@pypi//numpy"],
532*60517a1eSAndroid Build Coastguard Worker```
533*60517a1eSAndroid Build Coastguard Worker
534*60517a1eSAndroid Build Coastguard Worker
535*60517a1eSAndroid Build Coastguard Worker#### Annotation: `include_dep`
536*60517a1eSAndroid Build Coastguard Worker
537*60517a1eSAndroid Build Coastguard WorkerThis annotation accepts a comma-separated string of values. Values _must_
538*60517a1eSAndroid Build Coastguard Workerbe Python targets, but _no validation is done_. If a value is not a Python
539*60517a1eSAndroid Build Coastguard Workertarget, building will result in an error saying:
540*60517a1eSAndroid Build Coastguard Worker
541*60517a1eSAndroid Build Coastguard Worker```
542*60517a1eSAndroid Build Coastguard Worker<target> does not have mandatory providers: 'PyInfo' or 'CcInfo' or 'PyInfo'.
543*60517a1eSAndroid Build Coastguard Worker```
544*60517a1eSAndroid Build Coastguard Worker
545*60517a1eSAndroid Build Coastguard WorkerAdding non-Python targets to the generated target is a feature request being
546*60517a1eSAndroid Build Coastguard Workertracked in [Issue #1865](https://github.com/bazelbuild/rules_python/issues/1865).
547*60517a1eSAndroid Build Coastguard Worker
548*60517a1eSAndroid Build Coastguard WorkerThe annotation can be added multiple times, and all values are combined
549*60517a1eSAndroid Build Coastguard Workerand de-duplicated.
550*60517a1eSAndroid Build Coastguard Worker
551*60517a1eSAndroid Build Coastguard WorkerFor `python_generation_mode = "package"`, the `include_dep` annotations
552*60517a1eSAndroid Build Coastguard Workerfound across all files included in the generated target are included in `deps`.
553*60517a1eSAndroid Build Coastguard Worker
554*60517a1eSAndroid Build Coastguard WorkerExample:
555*60517a1eSAndroid Build Coastguard Worker
556*60517a1eSAndroid Build Coastguard Worker```python
557*60517a1eSAndroid Build Coastguard Worker# gazelle:include_dep //foo:bar,:hello_world,//:abc
558*60517a1eSAndroid Build Coastguard Worker# gazelle:include_dep //:def,//foo:bar
559*60517a1eSAndroid Build Coastguard Workerimport numpy  # a pypi package
560*60517a1eSAndroid Build Coastguard Worker```
561*60517a1eSAndroid Build Coastguard Worker
562*60517a1eSAndroid Build Coastguard Workerwill cause Gazelle to generate:
563*60517a1eSAndroid Build Coastguard Worker
564*60517a1eSAndroid Build Coastguard Worker```starlark
565*60517a1eSAndroid Build Coastguard Workerdeps = [
566*60517a1eSAndroid Build Coastguard Worker    ":hello_world",
567*60517a1eSAndroid Build Coastguard Worker    "//:abc",
568*60517a1eSAndroid Build Coastguard Worker    "//:def",
569*60517a1eSAndroid Build Coastguard Worker    "//foo:bar",
570*60517a1eSAndroid Build Coastguard Worker    "@pypi//numpy",
571*60517a1eSAndroid Build Coastguard Worker]
572*60517a1eSAndroid Build Coastguard Worker```
573*60517a1eSAndroid Build Coastguard Worker
574*60517a1eSAndroid Build Coastguard Worker
575*60517a1eSAndroid Build Coastguard Worker### Libraries
576*60517a1eSAndroid Build Coastguard Worker
577*60517a1eSAndroid Build Coastguard WorkerPython source files are those ending in `.py` but not ending in `_test.py`.
578*60517a1eSAndroid Build Coastguard Worker
579*60517a1eSAndroid Build Coastguard WorkerFirst, we look for the nearest ancestor BUILD file starting from the folder
580*60517a1eSAndroid Build Coastguard Workercontaining the Python source file.
581*60517a1eSAndroid Build Coastguard Worker
582*60517a1eSAndroid Build Coastguard WorkerIn package generation mode, if there is no `py_library` in this BUILD file, one
583*60517a1eSAndroid Build Coastguard Workeris created using the package name as the target's name. This makes it the
584*60517a1eSAndroid Build Coastguard Workerdefault target in the package. Next, all source files are collected into the
585*60517a1eSAndroid Build Coastguard Worker`srcs` of the `py_library`.
586*60517a1eSAndroid Build Coastguard Worker
587*60517a1eSAndroid Build Coastguard WorkerIn project generation mode, all source files in subdirectories (that don't have
588*60517a1eSAndroid Build Coastguard WorkerBUILD files) are also collected.
589*60517a1eSAndroid Build Coastguard Worker
590*60517a1eSAndroid Build Coastguard WorkerIn file generation mode, each file is given its own target.
591*60517a1eSAndroid Build Coastguard Worker
592*60517a1eSAndroid Build Coastguard WorkerFinally, the `import` statements in the source files are parsed, and
593*60517a1eSAndroid Build Coastguard Workerdependencies are added to the `deps` attribute.
594*60517a1eSAndroid Build Coastguard Worker
595*60517a1eSAndroid Build Coastguard Worker### Unit Tests
596*60517a1eSAndroid Build Coastguard Worker
597*60517a1eSAndroid Build Coastguard WorkerA `py_test` target is added to the BUILD file when gazelle encounters
598*60517a1eSAndroid Build Coastguard Workera file named `__test__.py`.
599*60517a1eSAndroid Build Coastguard WorkerOften, Python unit test files are named with the suffix `_test`.
600*60517a1eSAndroid Build Coastguard WorkerFor example, if we had a folder that is a package named "foo" we could have a Python file named `foo_test.py`
601*60517a1eSAndroid Build Coastguard Workerand gazelle would create a `py_test` block for the file.
602*60517a1eSAndroid Build Coastguard Worker
603*60517a1eSAndroid Build Coastguard WorkerThe following is an example of a `py_test` target that gazelle would add when
604*60517a1eSAndroid Build Coastguard Workerit encounters a file named `__test__.py`.
605*60517a1eSAndroid Build Coastguard Worker
606*60517a1eSAndroid Build Coastguard Worker```starlark
607*60517a1eSAndroid Build Coastguard Workerpy_test(
608*60517a1eSAndroid Build Coastguard Worker    name = "build_file_generation_test",
609*60517a1eSAndroid Build Coastguard Worker    srcs = ["__test__.py"],
610*60517a1eSAndroid Build Coastguard Worker    main = "__test__.py",
611*60517a1eSAndroid Build Coastguard Worker    deps = [":build_file_generation"],
612*60517a1eSAndroid Build Coastguard Worker)
613*60517a1eSAndroid Build Coastguard Worker```
614*60517a1eSAndroid Build Coastguard Worker
615*60517a1eSAndroid Build Coastguard WorkerYou can control the naming convention for test targets by adding a gazelle directive named
616*60517a1eSAndroid Build Coastguard Worker`# gazelle:python_test_naming_convention`.  See the instructions in the section above that
617*60517a1eSAndroid Build Coastguard Workercovers directives.
618*60517a1eSAndroid Build Coastguard Worker
619*60517a1eSAndroid Build Coastguard Worker### Binaries
620*60517a1eSAndroid Build Coastguard Worker
621*60517a1eSAndroid Build Coastguard WorkerWhen a `__main__.py` file is encountered, this indicates the entry point
622*60517a1eSAndroid Build Coastguard Workerof a Python program. A `py_binary` target will be created, named `[package]_bin`.
623*60517a1eSAndroid Build Coastguard Worker
624*60517a1eSAndroid Build Coastguard WorkerWhen no such entry point exists, Gazelle will look for a line like this in the top level in every module:
625*60517a1eSAndroid Build Coastguard Worker
626*60517a1eSAndroid Build Coastguard Worker```python
627*60517a1eSAndroid Build Coastguard Workerif __name == "__main__":
628*60517a1eSAndroid Build Coastguard Worker```
629*60517a1eSAndroid Build Coastguard Worker
630*60517a1eSAndroid Build Coastguard WorkerGazelle will create a `py_binary` target for every module with such a line, with
631*60517a1eSAndroid Build Coastguard Workerthe target name the same as the module name.
632*60517a1eSAndroid Build Coastguard Worker
633*60517a1eSAndroid Build Coastguard WorkerIf `python_generation_mode` is set to `file`, then instead of one `py_binary`
634*60517a1eSAndroid Build Coastguard Workertarget per module, Gazelle will create one `py_binary` target for each file with
635*60517a1eSAndroid Build Coastguard Workersuch a line, and the name of the target will match the name of the script.
636*60517a1eSAndroid Build Coastguard Worker
637*60517a1eSAndroid Build Coastguard WorkerNote that it's possible for another script to depend on a `py_binary` target and
638*60517a1eSAndroid Build Coastguard Workerimport from the `py_binary`'s scripts. This can have possible negative effects on
639*60517a1eSAndroid Build Coastguard WorkerBazel analysis time and runfiles size compared to depending on a `py_library`
640*60517a1eSAndroid Build Coastguard Workertarget. The simplest way to avoid these negative effects is to extract library
641*60517a1eSAndroid Build Coastguard Workercode into a separate script without a `main` line. Gazelle will then create a
642*60517a1eSAndroid Build Coastguard Worker`py_library` target for that library code, and other scripts can depend on that
643*60517a1eSAndroid Build Coastguard Worker`py_library` target.
644*60517a1eSAndroid Build Coastguard Worker
645*60517a1eSAndroid Build Coastguard Worker## Developer Notes
646*60517a1eSAndroid Build Coastguard Worker
647*60517a1eSAndroid Build Coastguard WorkerGazelle extensions are written in Go. This gazelle plugin is a hybrid, as it uses Go to execute a
648*60517a1eSAndroid Build Coastguard WorkerPython interpreter as a subprocess to parse Python source files.
649*60517a1eSAndroid Build Coastguard WorkerSee the gazelle documentation https://github.com/bazelbuild/bazel-gazelle/blob/master/extend.md
650*60517a1eSAndroid Build Coastguard Workerfor more information on extending Gazelle.
651*60517a1eSAndroid Build Coastguard Worker
652*60517a1eSAndroid Build Coastguard WorkerIf you add new Go dependencies to the plugin source code, you need to "tidy" the go.mod file.
653*60517a1eSAndroid Build Coastguard WorkerAfter changing that file, run `go mod tidy` or `bazel run @go_sdk//:bin/go -- mod tidy`
654*60517a1eSAndroid Build Coastguard Workerto update the go.mod and go.sum files. Then run `bazel run //:gazelle_update_repos` to have gazelle
655*60517a1eSAndroid Build Coastguard Workeradd the new dependenies to the deps.bzl file. The deps.bzl file is used as defined in our /WORKSPACE
656*60517a1eSAndroid Build Coastguard Workerto include the external repos Bazel loads Go dependencies from.
657*60517a1eSAndroid Build Coastguard Worker
658*60517a1eSAndroid Build Coastguard WorkerThen after editing Go code, run `bazel run //:gazelle` to generate/update the rules in the
659*60517a1eSAndroid Build Coastguard WorkerBUILD.bazel files in our repo.
660