xref: /aosp_15_r20/external/bazelbuild-rules_python/python/private/common/providers.bzl (revision 60517a1edbc8ecf509223e9af94a7adec7d736b8)
1*60517a1eSAndroid Build Coastguard Worker# Copyright 2022 The Bazel Authors. All rights reserved.
2*60517a1eSAndroid Build Coastguard Worker#
3*60517a1eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*60517a1eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*60517a1eSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*60517a1eSAndroid Build Coastguard Worker#
7*60517a1eSAndroid Build Coastguard Worker#    http://www.apache.org/licenses/LICENSE-2.0
8*60517a1eSAndroid Build Coastguard Worker#
9*60517a1eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*60517a1eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*60517a1eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*60517a1eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*60517a1eSAndroid Build Coastguard Worker# limitations under the License.
14*60517a1eSAndroid Build Coastguard Worker"""Providers for Python rules."""
15*60517a1eSAndroid Build Coastguard Worker
16*60517a1eSAndroid Build Coastguard Workerload("@rules_cc//cc:defs.bzl", "CcInfo")
17*60517a1eSAndroid Build Coastguard Workerload("//python/private:util.bzl", "IS_BAZEL_6_OR_HIGHER")
18*60517a1eSAndroid Build Coastguard Worker
19*60517a1eSAndroid Build Coastguard WorkerDEFAULT_STUB_SHEBANG = "#!/usr/bin/env python3"
20*60517a1eSAndroid Build Coastguard Worker
21*60517a1eSAndroid Build Coastguard WorkerDEFAULT_BOOTSTRAP_TEMPLATE = Label("//python/private:bootstrap_template")
22*60517a1eSAndroid Build Coastguard Worker
23*60517a1eSAndroid Build Coastguard Worker_PYTHON_VERSION_VALUES = ["PY2", "PY3"]
24*60517a1eSAndroid Build Coastguard Worker
25*60517a1eSAndroid Build Coastguard Worker# Helper to make the provider definitions not crash under Bazel 5.4:
26*60517a1eSAndroid Build Coastguard Worker# Bazel 5.4 doesn't support the `init` arg of `provider()`, so we have to
27*60517a1eSAndroid Build Coastguard Worker# not pass that when using Bazel 5.4. But, not passing the `init` arg
28*60517a1eSAndroid Build Coastguard Worker# changes the return value from a two-tuple to a single value, which then
29*60517a1eSAndroid Build Coastguard Worker# breaks Bazel 6+ code.
30*60517a1eSAndroid Build Coastguard Worker# This isn't actually used under Bazel 5.4, so just stub out the values
31*60517a1eSAndroid Build Coastguard Worker# to get past the loading phase.
32*60517a1eSAndroid Build Coastguard Workerdef _define_provider(doc, fields, **kwargs):
33*60517a1eSAndroid Build Coastguard Worker    if not IS_BAZEL_6_OR_HIGHER:
34*60517a1eSAndroid Build Coastguard Worker        return provider("Stub, not used", fields = []), None
35*60517a1eSAndroid Build Coastguard Worker    return provider(doc = doc, fields = fields, **kwargs)
36*60517a1eSAndroid Build Coastguard Worker
37*60517a1eSAndroid Build Coastguard Workerdef _optional_int(value):
38*60517a1eSAndroid Build Coastguard Worker    return int(value) if value != None else None
39*60517a1eSAndroid Build Coastguard Worker
40*60517a1eSAndroid Build Coastguard Workerdef interpreter_version_info_struct_from_dict(info_dict):
41*60517a1eSAndroid Build Coastguard Worker    """Create a struct of interpreter version info from a dict from an attribute.
42*60517a1eSAndroid Build Coastguard Worker
43*60517a1eSAndroid Build Coastguard Worker    Args:
44*60517a1eSAndroid Build Coastguard Worker        info_dict: (dict | None) of version info fields. See interpreter_version_info
45*60517a1eSAndroid Build Coastguard Worker            provider field docs.
46*60517a1eSAndroid Build Coastguard Worker
47*60517a1eSAndroid Build Coastguard Worker    Returns:
48*60517a1eSAndroid Build Coastguard Worker        struct of version info; see interpreter_version_info provider field docs.
49*60517a1eSAndroid Build Coastguard Worker    """
50*60517a1eSAndroid Build Coastguard Worker    info_dict = dict(info_dict or {})  # Copy in case the original is frozen
51*60517a1eSAndroid Build Coastguard Worker    if info_dict:
52*60517a1eSAndroid Build Coastguard Worker        if not ("major" in info_dict and "minor" in info_dict):
53*60517a1eSAndroid Build Coastguard Worker            fail("interpreter_version_info must have at least two keys, 'major' and 'minor'")
54*60517a1eSAndroid Build Coastguard Worker    version_info_struct = struct(
55*60517a1eSAndroid Build Coastguard Worker        major = _optional_int(info_dict.pop("major", None)),
56*60517a1eSAndroid Build Coastguard Worker        minor = _optional_int(info_dict.pop("minor", None)),
57*60517a1eSAndroid Build Coastguard Worker        micro = _optional_int(info_dict.pop("micro", None)),
58*60517a1eSAndroid Build Coastguard Worker        releaselevel = str(info_dict.pop("releaselevel")) if "releaselevel" in info_dict else None,
59*60517a1eSAndroid Build Coastguard Worker        serial = _optional_int(info_dict.pop("serial", None)),
60*60517a1eSAndroid Build Coastguard Worker    )
61*60517a1eSAndroid Build Coastguard Worker
62*60517a1eSAndroid Build Coastguard Worker    if len(info_dict.keys()) > 0:
63*60517a1eSAndroid Build Coastguard Worker        fail("unexpected keys {} in interpreter_version_info".format(
64*60517a1eSAndroid Build Coastguard Worker            str(info_dict.keys()),
65*60517a1eSAndroid Build Coastguard Worker        ))
66*60517a1eSAndroid Build Coastguard Worker
67*60517a1eSAndroid Build Coastguard Worker    return version_info_struct
68*60517a1eSAndroid Build Coastguard Worker
69*60517a1eSAndroid Build Coastguard Workerdef _PyRuntimeInfo_init(
70*60517a1eSAndroid Build Coastguard Worker        *,
71*60517a1eSAndroid Build Coastguard Worker        implementation_name = None,
72*60517a1eSAndroid Build Coastguard Worker        interpreter_path = None,
73*60517a1eSAndroid Build Coastguard Worker        interpreter = None,
74*60517a1eSAndroid Build Coastguard Worker        files = None,
75*60517a1eSAndroid Build Coastguard Worker        coverage_tool = None,
76*60517a1eSAndroid Build Coastguard Worker        coverage_files = None,
77*60517a1eSAndroid Build Coastguard Worker        pyc_tag = None,
78*60517a1eSAndroid Build Coastguard Worker        python_version,
79*60517a1eSAndroid Build Coastguard Worker        stub_shebang = None,
80*60517a1eSAndroid Build Coastguard Worker        bootstrap_template = None,
81*60517a1eSAndroid Build Coastguard Worker        interpreter_version_info = None,
82*60517a1eSAndroid Build Coastguard Worker        stage2_bootstrap_template = None,
83*60517a1eSAndroid Build Coastguard Worker        zip_main_template = None):
84*60517a1eSAndroid Build Coastguard Worker    if (interpreter_path and interpreter) or (not interpreter_path and not interpreter):
85*60517a1eSAndroid Build Coastguard Worker        fail("exactly one of interpreter or interpreter_path must be specified")
86*60517a1eSAndroid Build Coastguard Worker
87*60517a1eSAndroid Build Coastguard Worker    if interpreter_path and files != None:
88*60517a1eSAndroid Build Coastguard Worker        fail("cannot specify 'files' if 'interpreter_path' is given")
89*60517a1eSAndroid Build Coastguard Worker
90*60517a1eSAndroid Build Coastguard Worker    if (coverage_tool and not coverage_files) or (not coverage_tool and coverage_files):
91*60517a1eSAndroid Build Coastguard Worker        fail(
92*60517a1eSAndroid Build Coastguard Worker            "coverage_tool and coverage_files must both be set or neither must be set, " +
93*60517a1eSAndroid Build Coastguard Worker            "got coverage_tool={}, coverage_files={}".format(
94*60517a1eSAndroid Build Coastguard Worker                coverage_tool,
95*60517a1eSAndroid Build Coastguard Worker                coverage_files,
96*60517a1eSAndroid Build Coastguard Worker            ),
97*60517a1eSAndroid Build Coastguard Worker        )
98*60517a1eSAndroid Build Coastguard Worker
99*60517a1eSAndroid Build Coastguard Worker    if python_version not in _PYTHON_VERSION_VALUES:
100*60517a1eSAndroid Build Coastguard Worker        fail("invalid python_version: '{}'; must be one of {}".format(
101*60517a1eSAndroid Build Coastguard Worker            python_version,
102*60517a1eSAndroid Build Coastguard Worker            _PYTHON_VERSION_VALUES,
103*60517a1eSAndroid Build Coastguard Worker        ))
104*60517a1eSAndroid Build Coastguard Worker
105*60517a1eSAndroid Build Coastguard Worker    if files != None and type(files) != type(depset()):
106*60517a1eSAndroid Build Coastguard Worker        fail("invalid files: got value of type {}, want depset".format(type(files)))
107*60517a1eSAndroid Build Coastguard Worker
108*60517a1eSAndroid Build Coastguard Worker    if interpreter:
109*60517a1eSAndroid Build Coastguard Worker        if files == None:
110*60517a1eSAndroid Build Coastguard Worker            files = depset()
111*60517a1eSAndroid Build Coastguard Worker    else:
112*60517a1eSAndroid Build Coastguard Worker        files = None
113*60517a1eSAndroid Build Coastguard Worker
114*60517a1eSAndroid Build Coastguard Worker    if coverage_files == None:
115*60517a1eSAndroid Build Coastguard Worker        coverage_files = depset()
116*60517a1eSAndroid Build Coastguard Worker
117*60517a1eSAndroid Build Coastguard Worker    if not stub_shebang:
118*60517a1eSAndroid Build Coastguard Worker        stub_shebang = DEFAULT_STUB_SHEBANG
119*60517a1eSAndroid Build Coastguard Worker
120*60517a1eSAndroid Build Coastguard Worker    return {
121*60517a1eSAndroid Build Coastguard Worker        "bootstrap_template": bootstrap_template,
122*60517a1eSAndroid Build Coastguard Worker        "coverage_files": coverage_files,
123*60517a1eSAndroid Build Coastguard Worker        "coverage_tool": coverage_tool,
124*60517a1eSAndroid Build Coastguard Worker        "files": files,
125*60517a1eSAndroid Build Coastguard Worker        "implementation_name": implementation_name,
126*60517a1eSAndroid Build Coastguard Worker        "interpreter": interpreter,
127*60517a1eSAndroid Build Coastguard Worker        "interpreter_path": interpreter_path,
128*60517a1eSAndroid Build Coastguard Worker        "interpreter_version_info": interpreter_version_info_struct_from_dict(interpreter_version_info),
129*60517a1eSAndroid Build Coastguard Worker        "pyc_tag": pyc_tag,
130*60517a1eSAndroid Build Coastguard Worker        "python_version": python_version,
131*60517a1eSAndroid Build Coastguard Worker        "stage2_bootstrap_template": stage2_bootstrap_template,
132*60517a1eSAndroid Build Coastguard Worker        "stub_shebang": stub_shebang,
133*60517a1eSAndroid Build Coastguard Worker        "zip_main_template": zip_main_template,
134*60517a1eSAndroid Build Coastguard Worker    }
135*60517a1eSAndroid Build Coastguard Worker
136*60517a1eSAndroid Build Coastguard Worker# TODO(#15897): Rename this to PyRuntimeInfo when we're ready to replace the Java
137*60517a1eSAndroid Build Coastguard Worker# implemented provider with the Starlark one.
138*60517a1eSAndroid Build Coastguard WorkerPyRuntimeInfo, _unused_raw_py_runtime_info_ctor = _define_provider(
139*60517a1eSAndroid Build Coastguard Worker    doc = """Contains information about a Python runtime, as returned by the `py_runtime`
140*60517a1eSAndroid Build Coastguard Workerrule.
141*60517a1eSAndroid Build Coastguard Worker
142*60517a1eSAndroid Build Coastguard WorkerA Python runtime describes either a *platform runtime* or an *in-build runtime*.
143*60517a1eSAndroid Build Coastguard WorkerA platform runtime accesses a system-installed interpreter at a known path,
144*60517a1eSAndroid Build Coastguard Workerwhereas an in-build runtime points to a `File` that acts as the interpreter. In
145*60517a1eSAndroid Build Coastguard Workerboth cases, an "interpreter" is really any executable binary or wrapper script
146*60517a1eSAndroid Build Coastguard Workerthat is capable of running a Python script passed on the command line, following
147*60517a1eSAndroid Build Coastguard Workerthe same conventions as the standard CPython interpreter.
148*60517a1eSAndroid Build Coastguard Worker""",
149*60517a1eSAndroid Build Coastguard Worker    init = _PyRuntimeInfo_init,
150*60517a1eSAndroid Build Coastguard Worker    fields = {
151*60517a1eSAndroid Build Coastguard Worker        "bootstrap_template": """
152*60517a1eSAndroid Build Coastguard Worker:type: File
153*60517a1eSAndroid Build Coastguard Worker
154*60517a1eSAndroid Build Coastguard WorkerA template of code responsible for the initial startup of a program.
155*60517a1eSAndroid Build Coastguard Worker
156*60517a1eSAndroid Build Coastguard WorkerThis code is responsible for:
157*60517a1eSAndroid Build Coastguard Worker
158*60517a1eSAndroid Build Coastguard Worker* Locating the target interpreter. Typically it is in runfiles, but not always.
159*60517a1eSAndroid Build Coastguard Worker* Setting necessary environment variables, command line flags, or other
160*60517a1eSAndroid Build Coastguard Worker  configuration that can't be modified after the interpreter starts.
161*60517a1eSAndroid Build Coastguard Worker* Invoking the appropriate entry point. This is usually a second-stage bootstrap
162*60517a1eSAndroid Build Coastguard Worker  that performs additional setup prior to running a program's actual entry point.
163*60517a1eSAndroid Build Coastguard Worker
164*60517a1eSAndroid Build Coastguard WorkerThe {obj}`--bootstrap_impl` flag affects how this stage 1 bootstrap
165*60517a1eSAndroid Build Coastguard Workeris expected to behave and the substutitions performed.
166*60517a1eSAndroid Build Coastguard Worker
167*60517a1eSAndroid Build Coastguard Worker* `--bootstrap_impl=system_python` substitutions: `%is_zipfile%`, `%python_binary%`,
168*60517a1eSAndroid Build Coastguard Worker  `%target%`, `%workspace_name`, `%coverage_tool%`, `%import_all%`, `%imports%`,
169*60517a1eSAndroid Build Coastguard Worker  `%main%`, `%shebang%`
170*60517a1eSAndroid Build Coastguard Worker* `--bootstrap_impl=script` substititions: `%is_zipfile%`, `%python_binary%`,
171*60517a1eSAndroid Build Coastguard Worker  `%target%`, `%workspace_name`, `%shebang%, `%stage2_bootstrap%`
172*60517a1eSAndroid Build Coastguard Worker
173*60517a1eSAndroid Build Coastguard WorkerSubstitution definitions:
174*60517a1eSAndroid Build Coastguard Worker
175*60517a1eSAndroid Build Coastguard Worker* `%shebang%`: The shebang to use with the bootstrap; the bootstrap template
176*60517a1eSAndroid Build Coastguard Worker  may choose to ignore this.
177*60517a1eSAndroid Build Coastguard Worker* `%stage2_bootstrap%`: A runfiles-relative path to the stage 2 bootstrap.
178*60517a1eSAndroid Build Coastguard Worker* `%python_binary%`: The path to the target Python interpreter. There are three
179*60517a1eSAndroid Build Coastguard Worker  types of paths:
180*60517a1eSAndroid Build Coastguard Worker  * An absolute path to a system interpreter (e.g. begins with `/`).
181*60517a1eSAndroid Build Coastguard Worker  * A runfiles-relative path to an interpreter (e.g. `somerepo/bin/python3`)
182*60517a1eSAndroid Build Coastguard Worker  * A program to search for on PATH, i.e. a word without spaces, e.g. `python3`.
183*60517a1eSAndroid Build Coastguard Worker* `%workspace_name%`: The name of the workspace the target belongs to.
184*60517a1eSAndroid Build Coastguard Worker* `%is_zipfile%`: The string `1` if this template is prepended to a zipfile to
185*60517a1eSAndroid Build Coastguard Worker  create a self-executable zip file. The string `0` otherwise.
186*60517a1eSAndroid Build Coastguard Worker
187*60517a1eSAndroid Build Coastguard WorkerFor the other substitution definitions, see the {obj}`stage2_bootstrap_template`
188*60517a1eSAndroid Build Coastguard Workerdocs.
189*60517a1eSAndroid Build Coastguard Worker
190*60517a1eSAndroid Build Coastguard Worker:::{versionchanged} 0.33.0
191*60517a1eSAndroid Build Coastguard WorkerThe set of substitutions depends on {obj}`--bootstrap_impl`
192*60517a1eSAndroid Build Coastguard Worker:::
193*60517a1eSAndroid Build Coastguard Worker""",
194*60517a1eSAndroid Build Coastguard Worker        "coverage_files": """
195*60517a1eSAndroid Build Coastguard Worker:type: depset[File] | None
196*60517a1eSAndroid Build Coastguard Worker
197*60517a1eSAndroid Build Coastguard WorkerThe files required at runtime for using `coverage_tool`. Will be `None` if no
198*60517a1eSAndroid Build Coastguard Worker`coverage_tool` was provided.
199*60517a1eSAndroid Build Coastguard Worker""",
200*60517a1eSAndroid Build Coastguard Worker        "coverage_tool": """
201*60517a1eSAndroid Build Coastguard Worker:type: File | None
202*60517a1eSAndroid Build Coastguard Worker
203*60517a1eSAndroid Build Coastguard WorkerIf set, this field is a `File` representing tool used for collecting code
204*60517a1eSAndroid Build Coastguard Workercoverage information from python tests. Otherwise, this is `None`.
205*60517a1eSAndroid Build Coastguard Worker""",
206*60517a1eSAndroid Build Coastguard Worker        "files": """
207*60517a1eSAndroid Build Coastguard Worker:type: depset[File] | None
208*60517a1eSAndroid Build Coastguard Worker
209*60517a1eSAndroid Build Coastguard WorkerIf this is an in-build runtime, this field is a `depset` of `File`s that need to
210*60517a1eSAndroid Build Coastguard Workerbe added to the runfiles of an executable target that uses this runtime (in
211*60517a1eSAndroid Build Coastguard Workerparticular, files needed by `interpreter`). The value of `interpreter` need not
212*60517a1eSAndroid Build Coastguard Workerbe included in this field. If this is a platform runtime then this field is
213*60517a1eSAndroid Build Coastguard Worker`None`.
214*60517a1eSAndroid Build Coastguard Worker""",
215*60517a1eSAndroid Build Coastguard Worker        "implementation_name": """
216*60517a1eSAndroid Build Coastguard Worker:type: str | None
217*60517a1eSAndroid Build Coastguard Worker
218*60517a1eSAndroid Build Coastguard WorkerThe Python implementation name (`sys.implementation.name`)
219*60517a1eSAndroid Build Coastguard Worker""",
220*60517a1eSAndroid Build Coastguard Worker        "interpreter": """
221*60517a1eSAndroid Build Coastguard Worker:type: File | None
222*60517a1eSAndroid Build Coastguard Worker
223*60517a1eSAndroid Build Coastguard WorkerIf this is an in-build runtime, this field is a `File` representing the
224*60517a1eSAndroid Build Coastguard Workerinterpreter. Otherwise, this is `None`. Note that an in-build runtime can use
225*60517a1eSAndroid Build Coastguard Workereither a prebuilt, checked-in interpreter or an interpreter built from source.
226*60517a1eSAndroid Build Coastguard Worker""",
227*60517a1eSAndroid Build Coastguard Worker        "interpreter_path": """
228*60517a1eSAndroid Build Coastguard Worker:type: str | None
229*60517a1eSAndroid Build Coastguard Worker
230*60517a1eSAndroid Build Coastguard WorkerIf this is a platform runtime, this field is the absolute filesystem path to the
231*60517a1eSAndroid Build Coastguard Workerinterpreter on the target platform. Otherwise, this is `None`.
232*60517a1eSAndroid Build Coastguard Worker""",
233*60517a1eSAndroid Build Coastguard Worker        "interpreter_version_info": """
234*60517a1eSAndroid Build Coastguard Worker:type: struct
235*60517a1eSAndroid Build Coastguard Worker
236*60517a1eSAndroid Build Coastguard WorkerVersion information about the interpreter this runtime provides.
237*60517a1eSAndroid Build Coastguard WorkerIt should match the format given by `sys.version_info`, however
238*60517a1eSAndroid Build Coastguard Workerfor simplicity, the micro, releaselevel, and serial values are
239*60517a1eSAndroid Build Coastguard Workeroptional.
240*60517a1eSAndroid Build Coastguard WorkerA struct with the following fields:
241*60517a1eSAndroid Build Coastguard Worker* `major`: {type}`int`, the major version number
242*60517a1eSAndroid Build Coastguard Worker* `minor`: {type}`int`, the minor version number
243*60517a1eSAndroid Build Coastguard Worker* `micro`: {type}`int | None`, the micro version number
244*60517a1eSAndroid Build Coastguard Worker* `releaselevel`: {type}`str | None`, the release level
245*60517a1eSAndroid Build Coastguard Worker* `serial`: {type}`int | None`, the serial number of the release
246*60517a1eSAndroid Build Coastguard Worker""",
247*60517a1eSAndroid Build Coastguard Worker        "pyc_tag": """
248*60517a1eSAndroid Build Coastguard Worker:type: str | None
249*60517a1eSAndroid Build Coastguard Worker
250*60517a1eSAndroid Build Coastguard WorkerThe tag portion of a pyc filename, e.g. the `cpython-39` infix
251*60517a1eSAndroid Build Coastguard Workerof `foo.cpython-39.pyc`. See PEP 3147. If not specified, it will be computed
252*60517a1eSAndroid Build Coastguard Workerfrom {obj}`implementation_name` and {obj}`interpreter_version_info`. If no
253*60517a1eSAndroid Build Coastguard Workerpyc_tag is available, then only source-less pyc generation will function
254*60517a1eSAndroid Build Coastguard Workercorrectly.
255*60517a1eSAndroid Build Coastguard Worker""",
256*60517a1eSAndroid Build Coastguard Worker        "python_version": """
257*60517a1eSAndroid Build Coastguard Worker:type: str
258*60517a1eSAndroid Build Coastguard Worker
259*60517a1eSAndroid Build Coastguard WorkerIndicates whether this runtime uses Python major version 2 or 3. Valid values
260*60517a1eSAndroid Build Coastguard Workerare (only) `"PY2"` and `"PY3"`.
261*60517a1eSAndroid Build Coastguard Worker""",
262*60517a1eSAndroid Build Coastguard Worker        "stage2_bootstrap_template": """
263*60517a1eSAndroid Build Coastguard Worker:type: File
264*60517a1eSAndroid Build Coastguard Worker
265*60517a1eSAndroid Build Coastguard WorkerA template of Python code that runs under the desired interpreter and is
266*60517a1eSAndroid Build Coastguard Workerresponsible for orchestrating calling the program's actual main code. This
267*60517a1eSAndroid Build Coastguard Workerbootstrap is responsible for affecting the current runtime's state, such as
268*60517a1eSAndroid Build Coastguard Workerimport paths or enabling coverage, so that, when it runs the program's actual
269*60517a1eSAndroid Build Coastguard Workermain code, it works properly under Bazel.
270*60517a1eSAndroid Build Coastguard Worker
271*60517a1eSAndroid Build Coastguard WorkerThe following substitutions are made during template expansion:
272*60517a1eSAndroid Build Coastguard Worker* `%main%`: A runfiles-relative path to the program's actual main file. This
273*60517a1eSAndroid Build Coastguard Worker  can be a `.py` or `.pyc` file, depending on precompile settings.
274*60517a1eSAndroid Build Coastguard Worker* `%coverage_tool%`: Runfiles-relative path to the coverage library's entry point.
275*60517a1eSAndroid Build Coastguard Worker  If coverage is not enabled or available, an empty string.
276*60517a1eSAndroid Build Coastguard Worker* `%import_all%`: The string `True` if all repositories in the runfiles should
277*60517a1eSAndroid Build Coastguard Worker  be added to sys.path. The string `False` otherwise.
278*60517a1eSAndroid Build Coastguard Worker* `%imports%`: A colon-delimited string of runfiles-relative paths to add to
279*60517a1eSAndroid Build Coastguard Worker  sys.path.
280*60517a1eSAndroid Build Coastguard Worker* `%target%`: The name of the target this is for.
281*60517a1eSAndroid Build Coastguard Worker* `%workspace_name%`: The name of the workspace the target belongs to.
282*60517a1eSAndroid Build Coastguard Worker
283*60517a1eSAndroid Build Coastguard Worker:::{versionadded} 0.33.0
284*60517a1eSAndroid Build Coastguard Worker:::
285*60517a1eSAndroid Build Coastguard Worker""",
286*60517a1eSAndroid Build Coastguard Worker        "stub_shebang": """
287*60517a1eSAndroid Build Coastguard Worker:type: str
288*60517a1eSAndroid Build Coastguard Worker
289*60517a1eSAndroid Build Coastguard Worker"Shebang" expression prepended to the bootstrapping Python stub
290*60517a1eSAndroid Build Coastguard Workerscript used when executing {obj}`py_binary` targets.  Does not
291*60517a1eSAndroid Build Coastguard Workerapply to Windows.
292*60517a1eSAndroid Build Coastguard Worker""",
293*60517a1eSAndroid Build Coastguard Worker        "zip_main_template": """
294*60517a1eSAndroid Build Coastguard Worker:type: File
295*60517a1eSAndroid Build Coastguard Worker
296*60517a1eSAndroid Build Coastguard WorkerA template of Python code that becomes a zip file's top-level `__main__.py`
297*60517a1eSAndroid Build Coastguard Workerfile. The top-level `__main__.py` file is used when the zip file is explicitly
298*60517a1eSAndroid Build Coastguard Workerpassed to a Python interpreter. See PEP 441 for more information about zipapp
299*60517a1eSAndroid Build Coastguard Workersupport. Note that py_binary-generated zip files are self-executing and
300*60517a1eSAndroid Build Coastguard Workerskip calling `__main__.py`.
301*60517a1eSAndroid Build Coastguard Worker
302*60517a1eSAndroid Build Coastguard WorkerThe following substitutions are made during template expansion:
303*60517a1eSAndroid Build Coastguard Worker* `%stage2_bootstrap%`: A runfiles-relative string to the stage 2 bootstrap file.
304*60517a1eSAndroid Build Coastguard Worker* `%python_binary%`: The path to the target Python interpreter. There are three
305*60517a1eSAndroid Build Coastguard Worker  types of paths:
306*60517a1eSAndroid Build Coastguard Worker  * An absolute path to a system interpreter (e.g. begins with `/`).
307*60517a1eSAndroid Build Coastguard Worker  * A runfiles-relative path to an interpreter (e.g. `somerepo/bin/python3`)
308*60517a1eSAndroid Build Coastguard Worker  * A program to search for on PATH, i.e. a word without spaces, e.g. `python3`.
309*60517a1eSAndroid Build Coastguard Worker* `%workspace_name%`: The name of the workspace for the built target.
310*60517a1eSAndroid Build Coastguard Worker
311*60517a1eSAndroid Build Coastguard Worker:::{versionadded} 0.33.0
312*60517a1eSAndroid Build Coastguard Worker:::
313*60517a1eSAndroid Build Coastguard Worker""",
314*60517a1eSAndroid Build Coastguard Worker    },
315*60517a1eSAndroid Build Coastguard Worker)
316*60517a1eSAndroid Build Coastguard Worker
317*60517a1eSAndroid Build Coastguard Workerdef _check_arg_type(name, required_type, value):
318*60517a1eSAndroid Build Coastguard Worker    value_type = type(value)
319*60517a1eSAndroid Build Coastguard Worker    if value_type != required_type:
320*60517a1eSAndroid Build Coastguard Worker        fail("parameter '{}' got value of type '{}', want '{}'".format(
321*60517a1eSAndroid Build Coastguard Worker            name,
322*60517a1eSAndroid Build Coastguard Worker            value_type,
323*60517a1eSAndroid Build Coastguard Worker            required_type,
324*60517a1eSAndroid Build Coastguard Worker        ))
325*60517a1eSAndroid Build Coastguard Worker
326*60517a1eSAndroid Build Coastguard Workerdef _PyInfo_init(
327*60517a1eSAndroid Build Coastguard Worker        *,
328*60517a1eSAndroid Build Coastguard Worker        transitive_sources,
329*60517a1eSAndroid Build Coastguard Worker        uses_shared_libraries = False,
330*60517a1eSAndroid Build Coastguard Worker        imports = depset(),
331*60517a1eSAndroid Build Coastguard Worker        has_py2_only_sources = False,
332*60517a1eSAndroid Build Coastguard Worker        has_py3_only_sources = False,
333*60517a1eSAndroid Build Coastguard Worker        direct_pyc_files = depset(),
334*60517a1eSAndroid Build Coastguard Worker        transitive_pyc_files = depset()):
335*60517a1eSAndroid Build Coastguard Worker    _check_arg_type("transitive_sources", "depset", transitive_sources)
336*60517a1eSAndroid Build Coastguard Worker
337*60517a1eSAndroid Build Coastguard Worker    # Verify it's postorder compatible, but retain is original ordering.
338*60517a1eSAndroid Build Coastguard Worker    depset(transitive = [transitive_sources], order = "postorder")
339*60517a1eSAndroid Build Coastguard Worker
340*60517a1eSAndroid Build Coastguard Worker    _check_arg_type("uses_shared_libraries", "bool", uses_shared_libraries)
341*60517a1eSAndroid Build Coastguard Worker    _check_arg_type("imports", "depset", imports)
342*60517a1eSAndroid Build Coastguard Worker    _check_arg_type("has_py2_only_sources", "bool", has_py2_only_sources)
343*60517a1eSAndroid Build Coastguard Worker    _check_arg_type("has_py3_only_sources", "bool", has_py3_only_sources)
344*60517a1eSAndroid Build Coastguard Worker    _check_arg_type("direct_pyc_files", "depset", direct_pyc_files)
345*60517a1eSAndroid Build Coastguard Worker    _check_arg_type("transitive_pyc_files", "depset", transitive_pyc_files)
346*60517a1eSAndroid Build Coastguard Worker    return {
347*60517a1eSAndroid Build Coastguard Worker        "direct_pyc_files": direct_pyc_files,
348*60517a1eSAndroid Build Coastguard Worker        "has_py2_only_sources": has_py2_only_sources,
349*60517a1eSAndroid Build Coastguard Worker        "has_py3_only_sources": has_py2_only_sources,
350*60517a1eSAndroid Build Coastguard Worker        "imports": imports,
351*60517a1eSAndroid Build Coastguard Worker        "transitive_pyc_files": transitive_pyc_files,
352*60517a1eSAndroid Build Coastguard Worker        "transitive_sources": transitive_sources,
353*60517a1eSAndroid Build Coastguard Worker        "uses_shared_libraries": uses_shared_libraries,
354*60517a1eSAndroid Build Coastguard Worker    }
355*60517a1eSAndroid Build Coastguard Worker
356*60517a1eSAndroid Build Coastguard WorkerPyInfo, _unused_raw_py_info_ctor = _define_provider(
357*60517a1eSAndroid Build Coastguard Worker    doc = "Encapsulates information provided by the Python rules.",
358*60517a1eSAndroid Build Coastguard Worker    init = _PyInfo_init,
359*60517a1eSAndroid Build Coastguard Worker    fields = {
360*60517a1eSAndroid Build Coastguard Worker        "direct_pyc_files": """
361*60517a1eSAndroid Build Coastguard Worker:type: depset[File]
362*60517a1eSAndroid Build Coastguard Worker
363*60517a1eSAndroid Build Coastguard WorkerPrecompiled Python files that are considered directly provided
364*60517a1eSAndroid Build Coastguard Workerby the target.
365*60517a1eSAndroid Build Coastguard Worker""",
366*60517a1eSAndroid Build Coastguard Worker        "has_py2_only_sources": """
367*60517a1eSAndroid Build Coastguard Worker:type: bool
368*60517a1eSAndroid Build Coastguard Worker
369*60517a1eSAndroid Build Coastguard WorkerWhether any of this target's transitive sources requires a Python 2 runtime.
370*60517a1eSAndroid Build Coastguard Worker""",
371*60517a1eSAndroid Build Coastguard Worker        "has_py3_only_sources": """
372*60517a1eSAndroid Build Coastguard Worker:type: bool
373*60517a1eSAndroid Build Coastguard Worker
374*60517a1eSAndroid Build Coastguard WorkerWhether any of this target's transitive sources requires a Python 3 runtime.
375*60517a1eSAndroid Build Coastguard Worker""",
376*60517a1eSAndroid Build Coastguard Worker        "imports": """\
377*60517a1eSAndroid Build Coastguard Worker:type: depset[str]
378*60517a1eSAndroid Build Coastguard Worker
379*60517a1eSAndroid Build Coastguard WorkerA depset of import path strings to be added to the `PYTHONPATH` of executable
380*60517a1eSAndroid Build Coastguard WorkerPython targets. These are accumulated from the transitive `deps`.
381*60517a1eSAndroid Build Coastguard WorkerThe order of the depset is not guaranteed and may be changed in the future. It
382*60517a1eSAndroid Build Coastguard Workeris recommended to use `default` order (the default).
383*60517a1eSAndroid Build Coastguard Worker""",
384*60517a1eSAndroid Build Coastguard Worker        "transitive_pyc_files": """
385*60517a1eSAndroid Build Coastguard Worker:type: depset[File]
386*60517a1eSAndroid Build Coastguard Worker
387*60517a1eSAndroid Build Coastguard WorkerDirect and transitive precompiled Python files that are provided by the target.
388*60517a1eSAndroid Build Coastguard Worker""",
389*60517a1eSAndroid Build Coastguard Worker        "transitive_sources": """\
390*60517a1eSAndroid Build Coastguard Worker:type: depset[File]
391*60517a1eSAndroid Build Coastguard Worker
392*60517a1eSAndroid Build Coastguard WorkerA (`postorder`-compatible) depset of `.py` files appearing in the target's
393*60517a1eSAndroid Build Coastguard Worker`srcs` and the `srcs` of the target's transitive `deps`.
394*60517a1eSAndroid Build Coastguard Worker""",
395*60517a1eSAndroid Build Coastguard Worker        "uses_shared_libraries": """
396*60517a1eSAndroid Build Coastguard Worker:type: bool
397*60517a1eSAndroid Build Coastguard Worker
398*60517a1eSAndroid Build Coastguard WorkerWhether any of this target's transitive `deps` has a shared library file (such
399*60517a1eSAndroid Build Coastguard Workeras a `.so` file).
400*60517a1eSAndroid Build Coastguard Worker
401*60517a1eSAndroid Build Coastguard WorkerThis field is currently unused in Bazel and may go away in the future.
402*60517a1eSAndroid Build Coastguard Worker""",
403*60517a1eSAndroid Build Coastguard Worker    },
404*60517a1eSAndroid Build Coastguard Worker)
405*60517a1eSAndroid Build Coastguard Worker
406*60517a1eSAndroid Build Coastguard Workerdef _PyCcLinkParamsProvider_init(cc_info):
407*60517a1eSAndroid Build Coastguard Worker    return {
408*60517a1eSAndroid Build Coastguard Worker        "cc_info": CcInfo(linking_context = cc_info.linking_context),
409*60517a1eSAndroid Build Coastguard Worker    }
410*60517a1eSAndroid Build Coastguard Worker
411*60517a1eSAndroid Build Coastguard Worker# buildifier: disable=name-conventions
412*60517a1eSAndroid Build Coastguard WorkerPyCcLinkParamsProvider, _unused_raw_py_cc_link_params_provider_ctor = _define_provider(
413*60517a1eSAndroid Build Coastguard Worker    doc = ("Python-wrapper to forward {obj}`CcInfo.linking_context`. This is to " +
414*60517a1eSAndroid Build Coastguard Worker           "allow Python targets to propagate C++ linking information, but " +
415*60517a1eSAndroid Build Coastguard Worker           "without the Python target appearing to be a valid C++ rule dependency"),
416*60517a1eSAndroid Build Coastguard Worker    init = _PyCcLinkParamsProvider_init,
417*60517a1eSAndroid Build Coastguard Worker    fields = {
418*60517a1eSAndroid Build Coastguard Worker        "cc_info": """
419*60517a1eSAndroid Build Coastguard Worker:type: CcInfo
420*60517a1eSAndroid Build Coastguard Worker
421*60517a1eSAndroid Build Coastguard WorkerLinking information; it has only {obj}`CcInfo.linking_context` set.
422*60517a1eSAndroid Build Coastguard Worker""",
423*60517a1eSAndroid Build Coastguard Worker    },
424*60517a1eSAndroid Build Coastguard Worker)
425