xref: /aosp_15_r20/external/bazelbuild-rules_python/python/private/common/attributes.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"""Attributes for Python rules."""
15*60517a1eSAndroid Build Coastguard Worker
16*60517a1eSAndroid Build Coastguard Workerload("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
17*60517a1eSAndroid Build Coastguard Workerload("@rules_cc//cc:defs.bzl", "CcInfo")
18*60517a1eSAndroid Build Coastguard Workerload("//python/private:enum.bzl", "enum")
19*60517a1eSAndroid Build Coastguard Workerload("//python/private:flags.bzl", "PrecompileFlag", "PrecompileSourceRetentionFlag")
20*60517a1eSAndroid Build Coastguard Workerload("//python/private:reexports.bzl", "BuiltinPyInfo")
21*60517a1eSAndroid Build Coastguard Workerload(":common.bzl", "union_attrs")
22*60517a1eSAndroid Build Coastguard Workerload(":providers.bzl", "PyInfo")
23*60517a1eSAndroid Build Coastguard Workerload(":py_internal.bzl", "py_internal")
24*60517a1eSAndroid Build Coastguard Workerload(
25*60517a1eSAndroid Build Coastguard Worker    ":semantics.bzl",
26*60517a1eSAndroid Build Coastguard Worker    "DEPS_ATTR_ALLOW_RULES",
27*60517a1eSAndroid Build Coastguard Worker    "SRCS_ATTR_ALLOW_FILES",
28*60517a1eSAndroid Build Coastguard Worker)
29*60517a1eSAndroid Build Coastguard Worker
30*60517a1eSAndroid Build Coastguard Worker_PackageSpecificationInfo = getattr(py_internal, "PackageSpecificationInfo", None)
31*60517a1eSAndroid Build Coastguard Worker
32*60517a1eSAndroid Build Coastguard Worker_STAMP_VALUES = [-1, 0, 1]
33*60517a1eSAndroid Build Coastguard Worker
34*60517a1eSAndroid Build Coastguard Workerdef _precompile_attr_get_effective_value(ctx):
35*60517a1eSAndroid Build Coastguard Worker    precompile_flag = PrecompileFlag.get_effective_value(ctx)
36*60517a1eSAndroid Build Coastguard Worker
37*60517a1eSAndroid Build Coastguard Worker    if precompile_flag == PrecompileFlag.FORCE_ENABLED:
38*60517a1eSAndroid Build Coastguard Worker        return PrecompileAttr.ENABLED
39*60517a1eSAndroid Build Coastguard Worker    if precompile_flag == PrecompileFlag.FORCE_DISABLED:
40*60517a1eSAndroid Build Coastguard Worker        return PrecompileAttr.DISABLED
41*60517a1eSAndroid Build Coastguard Worker
42*60517a1eSAndroid Build Coastguard Worker    precompile_attr = ctx.attr.precompile
43*60517a1eSAndroid Build Coastguard Worker    if precompile_attr == PrecompileAttr.INHERIT:
44*60517a1eSAndroid Build Coastguard Worker        precompile = precompile_flag
45*60517a1eSAndroid Build Coastguard Worker    else:
46*60517a1eSAndroid Build Coastguard Worker        precompile = precompile_attr
47*60517a1eSAndroid Build Coastguard Worker
48*60517a1eSAndroid Build Coastguard Worker    # Guard against bad final states because the two enums are similar with
49*60517a1eSAndroid Build Coastguard Worker    # magic values.
50*60517a1eSAndroid Build Coastguard Worker    if precompile not in (
51*60517a1eSAndroid Build Coastguard Worker        PrecompileAttr.ENABLED,
52*60517a1eSAndroid Build Coastguard Worker        PrecompileAttr.DISABLED,
53*60517a1eSAndroid Build Coastguard Worker        PrecompileAttr.IF_GENERATED_SOURCE,
54*60517a1eSAndroid Build Coastguard Worker    ):
55*60517a1eSAndroid Build Coastguard Worker        fail("Unexpected final precompile value: {}".format(repr(precompile)))
56*60517a1eSAndroid Build Coastguard Worker
57*60517a1eSAndroid Build Coastguard Worker    return precompile
58*60517a1eSAndroid Build Coastguard Worker
59*60517a1eSAndroid Build Coastguard Worker# buildifier: disable=name-conventions
60*60517a1eSAndroid Build Coastguard WorkerPrecompileAttr = enum(
61*60517a1eSAndroid Build Coastguard Worker    # Determine the effective value from --precompile
62*60517a1eSAndroid Build Coastguard Worker    INHERIT = "inherit",
63*60517a1eSAndroid Build Coastguard Worker    # Compile Python source files at build time. Note that
64*60517a1eSAndroid Build Coastguard Worker    # --precompile_add_to_runfiles affects how the compiled files are included
65*60517a1eSAndroid Build Coastguard Worker    # into a downstream binary.
66*60517a1eSAndroid Build Coastguard Worker    ENABLED = "enabled",
67*60517a1eSAndroid Build Coastguard Worker    # Don't compile Python source files at build time.
68*60517a1eSAndroid Build Coastguard Worker    DISABLED = "disabled",
69*60517a1eSAndroid Build Coastguard Worker    # Compile Python source files, but only if they're a generated file.
70*60517a1eSAndroid Build Coastguard Worker    IF_GENERATED_SOURCE = "if_generated_source",
71*60517a1eSAndroid Build Coastguard Worker    get_effective_value = _precompile_attr_get_effective_value,
72*60517a1eSAndroid Build Coastguard Worker)
73*60517a1eSAndroid Build Coastguard Worker
74*60517a1eSAndroid Build Coastguard Worker# buildifier: disable=name-conventions
75*60517a1eSAndroid Build Coastguard WorkerPrecompileInvalidationModeAttr = enum(
76*60517a1eSAndroid Build Coastguard Worker    # Automatically pick a value based on build settings.
77*60517a1eSAndroid Build Coastguard Worker    AUTO = "auto",
78*60517a1eSAndroid Build Coastguard Worker    # Use the pyc file if the hash of the originating source file matches the
79*60517a1eSAndroid Build Coastguard Worker    # hash recorded in the pyc file.
80*60517a1eSAndroid Build Coastguard Worker    CHECKED_HASH = "checked_hash",
81*60517a1eSAndroid Build Coastguard Worker    # Always use the pyc file, even if the originating source has changed.
82*60517a1eSAndroid Build Coastguard Worker    UNCHECKED_HASH = "unchecked_hash",
83*60517a1eSAndroid Build Coastguard Worker)
84*60517a1eSAndroid Build Coastguard Worker
85*60517a1eSAndroid Build Coastguard Workerdef _precompile_source_retention_get_effective_value(ctx):
86*60517a1eSAndroid Build Coastguard Worker    attr_value = ctx.attr.precompile_source_retention
87*60517a1eSAndroid Build Coastguard Worker    if attr_value == PrecompileSourceRetentionAttr.INHERIT:
88*60517a1eSAndroid Build Coastguard Worker        attr_value = PrecompileSourceRetentionFlag.get_effective_value(ctx)
89*60517a1eSAndroid Build Coastguard Worker
90*60517a1eSAndroid Build Coastguard Worker    if attr_value not in (
91*60517a1eSAndroid Build Coastguard Worker        PrecompileSourceRetentionAttr.KEEP_SOURCE,
92*60517a1eSAndroid Build Coastguard Worker        PrecompileSourceRetentionAttr.OMIT_SOURCE,
93*60517a1eSAndroid Build Coastguard Worker        PrecompileSourceRetentionAttr.OMIT_IF_GENERATED_SOURCE,
94*60517a1eSAndroid Build Coastguard Worker    ):
95*60517a1eSAndroid Build Coastguard Worker        fail("Unexpected final precompile_source_retention value: {}".format(repr(attr_value)))
96*60517a1eSAndroid Build Coastguard Worker    return attr_value
97*60517a1eSAndroid Build Coastguard Worker
98*60517a1eSAndroid Build Coastguard Worker# buildifier: disable=name-conventions
99*60517a1eSAndroid Build Coastguard WorkerPrecompileSourceRetentionAttr = enum(
100*60517a1eSAndroid Build Coastguard Worker    INHERIT = "inherit",
101*60517a1eSAndroid Build Coastguard Worker    KEEP_SOURCE = "keep_source",
102*60517a1eSAndroid Build Coastguard Worker    OMIT_SOURCE = "omit_source",
103*60517a1eSAndroid Build Coastguard Worker    OMIT_IF_GENERATED_SOURCE = "omit_if_generated_source",
104*60517a1eSAndroid Build Coastguard Worker    get_effective_value = _precompile_source_retention_get_effective_value,
105*60517a1eSAndroid Build Coastguard Worker)
106*60517a1eSAndroid Build Coastguard Worker
107*60517a1eSAndroid Build Coastguard Workerdef _pyc_collection_attr_is_pyc_collection_enabled(ctx):
108*60517a1eSAndroid Build Coastguard Worker    pyc_collection = ctx.attr.pyc_collection
109*60517a1eSAndroid Build Coastguard Worker    if pyc_collection == PycCollectionAttr.INHERIT:
110*60517a1eSAndroid Build Coastguard Worker        pyc_collection = ctx.attr._pyc_collection_flag[BuildSettingInfo].value
111*60517a1eSAndroid Build Coastguard Worker
112*60517a1eSAndroid Build Coastguard Worker    if pyc_collection not in (PycCollectionAttr.INCLUDE_PYC, PycCollectionAttr.DISABLED):
113*60517a1eSAndroid Build Coastguard Worker        fail("Unexpected final pyc_collection value: {}".format(repr(pyc_collection)))
114*60517a1eSAndroid Build Coastguard Worker
115*60517a1eSAndroid Build Coastguard Worker    return pyc_collection == PycCollectionAttr.INCLUDE_PYC
116*60517a1eSAndroid Build Coastguard Worker
117*60517a1eSAndroid Build Coastguard Worker# buildifier: disable=name-conventions
118*60517a1eSAndroid Build Coastguard WorkerPycCollectionAttr = enum(
119*60517a1eSAndroid Build Coastguard Worker    INHERIT = "inherit",
120*60517a1eSAndroid Build Coastguard Worker    INCLUDE_PYC = "include_pyc",
121*60517a1eSAndroid Build Coastguard Worker    DISABLED = "disabled",
122*60517a1eSAndroid Build Coastguard Worker    is_pyc_collection_enabled = _pyc_collection_attr_is_pyc_collection_enabled,
123*60517a1eSAndroid Build Coastguard Worker)
124*60517a1eSAndroid Build Coastguard Worker
125*60517a1eSAndroid Build Coastguard Workerdef create_stamp_attr(**kwargs):
126*60517a1eSAndroid Build Coastguard Worker    return {
127*60517a1eSAndroid Build Coastguard Worker        "stamp": attr.int(
128*60517a1eSAndroid Build Coastguard Worker            values = _STAMP_VALUES,
129*60517a1eSAndroid Build Coastguard Worker            doc = """
130*60517a1eSAndroid Build Coastguard WorkerWhether to encode build information into the binary. Possible values:
131*60517a1eSAndroid Build Coastguard Worker
132*60517a1eSAndroid Build Coastguard Worker* `stamp = 1`: Always stamp the build information into the binary, even in
133*60517a1eSAndroid Build Coastguard Worker  `--nostamp` builds. **This setting should be avoided**, since it potentially kills
134*60517a1eSAndroid Build Coastguard Worker  remote caching for the binary and any downstream actions that depend on it.
135*60517a1eSAndroid Build Coastguard Worker* `stamp = 0`: Always replace build information by constant values. This gives
136*60517a1eSAndroid Build Coastguard Worker  good build result caching.
137*60517a1eSAndroid Build Coastguard Worker* `stamp = -1`: Embedding of build information is controlled by the
138*60517a1eSAndroid Build Coastguard Worker  `--[no]stamp` flag.
139*60517a1eSAndroid Build Coastguard Worker
140*60517a1eSAndroid Build Coastguard WorkerStamped binaries are not rebuilt unless their dependencies change.
141*60517a1eSAndroid Build Coastguard Worker
142*60517a1eSAndroid Build Coastguard WorkerWARNING: Stamping can harm build performance by reducing cache hits and should
143*60517a1eSAndroid Build Coastguard Workerbe avoided if possible.
144*60517a1eSAndroid Build Coastguard Worker""",
145*60517a1eSAndroid Build Coastguard Worker            **kwargs
146*60517a1eSAndroid Build Coastguard Worker        ),
147*60517a1eSAndroid Build Coastguard Worker    }
148*60517a1eSAndroid Build Coastguard Worker
149*60517a1eSAndroid Build Coastguard Workerdef create_srcs_attr(*, mandatory):
150*60517a1eSAndroid Build Coastguard Worker    return {
151*60517a1eSAndroid Build Coastguard Worker        "srcs": attr.label_list(
152*60517a1eSAndroid Build Coastguard Worker            # Google builds change the set of allowed files.
153*60517a1eSAndroid Build Coastguard Worker            allow_files = SRCS_ATTR_ALLOW_FILES,
154*60517a1eSAndroid Build Coastguard Worker            mandatory = mandatory,
155*60517a1eSAndroid Build Coastguard Worker            # Necessary for --compile_one_dependency to work.
156*60517a1eSAndroid Build Coastguard Worker            flags = ["DIRECT_COMPILE_TIME_INPUT"],
157*60517a1eSAndroid Build Coastguard Worker            doc = """
158*60517a1eSAndroid Build Coastguard WorkerThe list of Python source files that are processed to create the target. This
159*60517a1eSAndroid Build Coastguard Workerincludes all your checked-in code and may include generated source files.  The
160*60517a1eSAndroid Build Coastguard Worker`.py` files belong in `srcs` and library targets belong in `deps`. Other binary
161*60517a1eSAndroid Build Coastguard Workerfiles that may be needed at run time belong in `data`.
162*60517a1eSAndroid Build Coastguard Worker""",
163*60517a1eSAndroid Build Coastguard Worker        ),
164*60517a1eSAndroid Build Coastguard Worker    }
165*60517a1eSAndroid Build Coastguard Worker
166*60517a1eSAndroid Build Coastguard WorkerSRCS_VERSION_ALL_VALUES = ["PY2", "PY2ONLY", "PY2AND3", "PY3", "PY3ONLY"]
167*60517a1eSAndroid Build Coastguard WorkerSRCS_VERSION_NON_CONVERSION_VALUES = ["PY2AND3", "PY2ONLY", "PY3ONLY"]
168*60517a1eSAndroid Build Coastguard Worker
169*60517a1eSAndroid Build Coastguard Workerdef create_srcs_version_attr(values):
170*60517a1eSAndroid Build Coastguard Worker    return {
171*60517a1eSAndroid Build Coastguard Worker        "srcs_version": attr.string(
172*60517a1eSAndroid Build Coastguard Worker            default = "PY2AND3",
173*60517a1eSAndroid Build Coastguard Worker            values = values,
174*60517a1eSAndroid Build Coastguard Worker            doc = "Defunct, unused, does nothing.",
175*60517a1eSAndroid Build Coastguard Worker        ),
176*60517a1eSAndroid Build Coastguard Worker    }
177*60517a1eSAndroid Build Coastguard Worker
178*60517a1eSAndroid Build Coastguard Workerdef copy_common_binary_kwargs(kwargs):
179*60517a1eSAndroid Build Coastguard Worker    return {
180*60517a1eSAndroid Build Coastguard Worker        key: kwargs[key]
181*60517a1eSAndroid Build Coastguard Worker        for key in BINARY_ATTR_NAMES
182*60517a1eSAndroid Build Coastguard Worker        if key in kwargs
183*60517a1eSAndroid Build Coastguard Worker    }
184*60517a1eSAndroid Build Coastguard Worker
185*60517a1eSAndroid Build Coastguard Workerdef copy_common_test_kwargs(kwargs):
186*60517a1eSAndroid Build Coastguard Worker    return {
187*60517a1eSAndroid Build Coastguard Worker        key: kwargs[key]
188*60517a1eSAndroid Build Coastguard Worker        for key in TEST_ATTR_NAMES
189*60517a1eSAndroid Build Coastguard Worker        if key in kwargs
190*60517a1eSAndroid Build Coastguard Worker    }
191*60517a1eSAndroid Build Coastguard Worker
192*60517a1eSAndroid Build Coastguard WorkerCC_TOOLCHAIN = {
193*60517a1eSAndroid Build Coastguard Worker    # NOTE: The `cc_helper.find_cpp_toolchain()` function expects the attribute
194*60517a1eSAndroid Build Coastguard Worker    # name to be this name.
195*60517a1eSAndroid Build Coastguard Worker    "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
196*60517a1eSAndroid Build Coastguard Worker}
197*60517a1eSAndroid Build Coastguard Worker
198*60517a1eSAndroid Build Coastguard Worker# The common "data" attribute definition.
199*60517a1eSAndroid Build Coastguard WorkerDATA_ATTRS = {
200*60517a1eSAndroid Build Coastguard Worker    # NOTE: The "flags" attribute is deprecated, but there isn't an alternative
201*60517a1eSAndroid Build Coastguard Worker    # way to specify that constraints should be ignored.
202*60517a1eSAndroid Build Coastguard Worker    "data": attr.label_list(
203*60517a1eSAndroid Build Coastguard Worker        allow_files = True,
204*60517a1eSAndroid Build Coastguard Worker        flags = ["SKIP_CONSTRAINTS_OVERRIDE"],
205*60517a1eSAndroid Build Coastguard Worker        doc = """
206*60517a1eSAndroid Build Coastguard WorkerThe list of files need by this library at runtime. See comments about
207*60517a1eSAndroid Build Coastguard Workerthe [`data` attribute typically defined by rules](https://bazel.build/reference/be/common-definitions#typical-attributes).
208*60517a1eSAndroid Build Coastguard Worker
209*60517a1eSAndroid Build Coastguard WorkerThere is no `py_embed_data` like there is `cc_embed_data` and `go_embed_data`.
210*60517a1eSAndroid Build Coastguard WorkerThis is because Python has a concept of runtime resources.
211*60517a1eSAndroid Build Coastguard Worker""",
212*60517a1eSAndroid Build Coastguard Worker    ),
213*60517a1eSAndroid Build Coastguard Worker}
214*60517a1eSAndroid Build Coastguard Worker
215*60517a1eSAndroid Build Coastguard Workerdef _create_native_rules_allowlist_attrs():
216*60517a1eSAndroid Build Coastguard Worker    if py_internal:
217*60517a1eSAndroid Build Coastguard Worker        # The fragment and name are validated when configuration_field is called
218*60517a1eSAndroid Build Coastguard Worker        default = configuration_field(
219*60517a1eSAndroid Build Coastguard Worker            fragment = "py",
220*60517a1eSAndroid Build Coastguard Worker            name = "native_rules_allowlist",
221*60517a1eSAndroid Build Coastguard Worker        )
222*60517a1eSAndroid Build Coastguard Worker
223*60517a1eSAndroid Build Coastguard Worker        # A None provider isn't allowed
224*60517a1eSAndroid Build Coastguard Worker        providers = [_PackageSpecificationInfo]
225*60517a1eSAndroid Build Coastguard Worker    else:
226*60517a1eSAndroid Build Coastguard Worker        default = None
227*60517a1eSAndroid Build Coastguard Worker        providers = []
228*60517a1eSAndroid Build Coastguard Worker
229*60517a1eSAndroid Build Coastguard Worker    return {
230*60517a1eSAndroid Build Coastguard Worker        "_native_rules_allowlist": attr.label(
231*60517a1eSAndroid Build Coastguard Worker            default = default,
232*60517a1eSAndroid Build Coastguard Worker            providers = providers,
233*60517a1eSAndroid Build Coastguard Worker        ),
234*60517a1eSAndroid Build Coastguard Worker    }
235*60517a1eSAndroid Build Coastguard Worker
236*60517a1eSAndroid Build Coastguard WorkerNATIVE_RULES_ALLOWLIST_ATTRS = _create_native_rules_allowlist_attrs()
237*60517a1eSAndroid Build Coastguard Worker
238*60517a1eSAndroid Build Coastguard Worker# Attributes common to all rules.
239*60517a1eSAndroid Build Coastguard WorkerCOMMON_ATTRS = union_attrs(
240*60517a1eSAndroid Build Coastguard Worker    DATA_ATTRS,
241*60517a1eSAndroid Build Coastguard Worker    NATIVE_RULES_ALLOWLIST_ATTRS,
242*60517a1eSAndroid Build Coastguard Worker    # buildifier: disable=attr-licenses
243*60517a1eSAndroid Build Coastguard Worker    {
244*60517a1eSAndroid Build Coastguard Worker        # NOTE: This attribute is deprecated and slated for removal.
245*60517a1eSAndroid Build Coastguard Worker        "distribs": attr.string_list(),
246*60517a1eSAndroid Build Coastguard Worker        # TODO(b/148103851): This attribute is deprecated and slated for
247*60517a1eSAndroid Build Coastguard Worker        # removal.
248*60517a1eSAndroid Build Coastguard Worker        # NOTE: The license attribute is missing in some Java integration tests,
249*60517a1eSAndroid Build Coastguard Worker        # so fallback to a regular string_list for that case.
250*60517a1eSAndroid Build Coastguard Worker        # buildifier: disable=attr-license
251*60517a1eSAndroid Build Coastguard Worker        "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(),
252*60517a1eSAndroid Build Coastguard Worker    },
253*60517a1eSAndroid Build Coastguard Worker    allow_none = True,
254*60517a1eSAndroid Build Coastguard Worker)
255*60517a1eSAndroid Build Coastguard Worker
256*60517a1eSAndroid Build Coastguard Worker# Attributes common to rules accepting Python sources and deps.
257*60517a1eSAndroid Build Coastguard WorkerPY_SRCS_ATTRS = union_attrs(
258*60517a1eSAndroid Build Coastguard Worker    {
259*60517a1eSAndroid Build Coastguard Worker        "deps": attr.label_list(
260*60517a1eSAndroid Build Coastguard Worker            providers = [
261*60517a1eSAndroid Build Coastguard Worker                [PyInfo],
262*60517a1eSAndroid Build Coastguard Worker                [CcInfo],
263*60517a1eSAndroid Build Coastguard Worker                [BuiltinPyInfo],
264*60517a1eSAndroid Build Coastguard Worker            ],
265*60517a1eSAndroid Build Coastguard Worker            # TODO(b/228692666): Google-specific; remove these allowances once
266*60517a1eSAndroid Build Coastguard Worker            # the depot is cleaned up.
267*60517a1eSAndroid Build Coastguard Worker            allow_rules = DEPS_ATTR_ALLOW_RULES,
268*60517a1eSAndroid Build Coastguard Worker            doc = """
269*60517a1eSAndroid Build Coastguard WorkerList of additional libraries to be linked in to the target.
270*60517a1eSAndroid Build Coastguard WorkerSee comments about
271*60517a1eSAndroid Build Coastguard Workerthe [`deps` attribute typically defined by
272*60517a1eSAndroid Build Coastguard Workerrules](https://bazel.build/reference/be/common-definitions#typical-attributes).
273*60517a1eSAndroid Build Coastguard WorkerThese are typically `py_library` rules.
274*60517a1eSAndroid Build Coastguard Worker
275*60517a1eSAndroid Build Coastguard WorkerTargets that only provide data files used at runtime belong in the `data`
276*60517a1eSAndroid Build Coastguard Workerattribute.
277*60517a1eSAndroid Build Coastguard Worker""",
278*60517a1eSAndroid Build Coastguard Worker        ),
279*60517a1eSAndroid Build Coastguard Worker        "precompile": attr.string(
280*60517a1eSAndroid Build Coastguard Worker            doc = """
281*60517a1eSAndroid Build Coastguard WorkerWhether py source files **for this target** should be precompiled.
282*60517a1eSAndroid Build Coastguard Worker
283*60517a1eSAndroid Build Coastguard WorkerValues:
284*60517a1eSAndroid Build Coastguard Worker
285*60517a1eSAndroid Build Coastguard Worker* `inherit`: Determine the value from the {flag}`--precompile` flag.
286*60517a1eSAndroid Build Coastguard Worker* `enabled`: Compile Python source files at build time. Note that
287*60517a1eSAndroid Build Coastguard Worker  --precompile_add_to_runfiles affects how the compiled files are included into
288*60517a1eSAndroid Build Coastguard Worker  a downstream binary.
289*60517a1eSAndroid Build Coastguard Worker* `disabled`: Don't compile Python source files at build time.
290*60517a1eSAndroid Build Coastguard Worker* `if_generated_source`: Compile Python source files, but only if they're a
291*60517a1eSAndroid Build Coastguard Worker  generated file.
292*60517a1eSAndroid Build Coastguard Worker
293*60517a1eSAndroid Build Coastguard Worker:::{seealso}
294*60517a1eSAndroid Build Coastguard Worker
295*60517a1eSAndroid Build Coastguard Worker* The {flag}`--precompile` flag, which can override this attribute in some cases
296*60517a1eSAndroid Build Coastguard Worker  and will affect all targets when building.
297*60517a1eSAndroid Build Coastguard Worker* The {obj}`pyc_collection` attribute for transitively enabling precompiling on
298*60517a1eSAndroid Build Coastguard Worker  a per-target basis.
299*60517a1eSAndroid Build Coastguard Worker* The [Precompiling](precompiling) docs for a guide about using precompiling.
300*60517a1eSAndroid Build Coastguard Worker:::
301*60517a1eSAndroid Build Coastguard Worker""",
302*60517a1eSAndroid Build Coastguard Worker            default = PrecompileAttr.INHERIT,
303*60517a1eSAndroid Build Coastguard Worker            values = sorted(PrecompileAttr.__members__.values()),
304*60517a1eSAndroid Build Coastguard Worker        ),
305*60517a1eSAndroid Build Coastguard Worker        "precompile_invalidation_mode": attr.string(
306*60517a1eSAndroid Build Coastguard Worker            doc = """
307*60517a1eSAndroid Build Coastguard WorkerHow precompiled files should be verified to be up-to-date with their associated
308*60517a1eSAndroid Build Coastguard Workersource files. Possible values are:
309*60517a1eSAndroid Build Coastguard Worker* `auto`: The effective value will be automatically determined by other build
310*60517a1eSAndroid Build Coastguard Worker  settings.
311*60517a1eSAndroid Build Coastguard Worker* `checked_hash`: Use the pyc file if the hash of the source file matches the hash
312*60517a1eSAndroid Build Coastguard Worker  recorded in the pyc file. This is most useful when working with code that
313*60517a1eSAndroid Build Coastguard Worker  you may modify.
314*60517a1eSAndroid Build Coastguard Worker* `unchecked_hash`: Always use the pyc file; don't check the pyc's hash against
315*60517a1eSAndroid Build Coastguard Worker  the source file. This is most useful when the code won't be modified.
316*60517a1eSAndroid Build Coastguard Worker
317*60517a1eSAndroid Build Coastguard WorkerFor more information on pyc invalidation modes, see
318*60517a1eSAndroid Build Coastguard Workerhttps://docs.python.org/3/library/py_compile.html#py_compile.PycInvalidationMode
319*60517a1eSAndroid Build Coastguard Worker""",
320*60517a1eSAndroid Build Coastguard Worker            default = PrecompileInvalidationModeAttr.AUTO,
321*60517a1eSAndroid Build Coastguard Worker            values = sorted(PrecompileInvalidationModeAttr.__members__.values()),
322*60517a1eSAndroid Build Coastguard Worker        ),
323*60517a1eSAndroid Build Coastguard Worker        "precompile_optimize_level": attr.int(
324*60517a1eSAndroid Build Coastguard Worker            doc = """
325*60517a1eSAndroid Build Coastguard WorkerThe optimization level for precompiled files.
326*60517a1eSAndroid Build Coastguard Worker
327*60517a1eSAndroid Build Coastguard WorkerFor more information about optimization levels, see the `compile()` function's
328*60517a1eSAndroid Build Coastguard Worker`optimize` arg docs at https://docs.python.org/3/library/functions.html#compile
329*60517a1eSAndroid Build Coastguard Worker
330*60517a1eSAndroid Build Coastguard WorkerNOTE: The value `-1` means "current interpreter", which will be the interpreter
331*60517a1eSAndroid Build Coastguard Workerused _at build time when pycs are generated_, not the interpreter used at
332*60517a1eSAndroid Build Coastguard Workerruntime when the code actually runs.
333*60517a1eSAndroid Build Coastguard Worker""",
334*60517a1eSAndroid Build Coastguard Worker            default = 0,
335*60517a1eSAndroid Build Coastguard Worker        ),
336*60517a1eSAndroid Build Coastguard Worker        "precompile_source_retention": attr.string(
337*60517a1eSAndroid Build Coastguard Worker            default = PrecompileSourceRetentionAttr.INHERIT,
338*60517a1eSAndroid Build Coastguard Worker            values = sorted(PrecompileSourceRetentionAttr.__members__.values()),
339*60517a1eSAndroid Build Coastguard Worker            doc = """
340*60517a1eSAndroid Build Coastguard WorkerDetermines, when a source file is compiled, if the source file is kept
341*60517a1eSAndroid Build Coastguard Workerin the resulting output or not. Valid values are:
342*60517a1eSAndroid Build Coastguard Worker
343*60517a1eSAndroid Build Coastguard Worker* `inherit`: Inherit the value from the {flag}`--precompile_source_retention` flag.
344*60517a1eSAndroid Build Coastguard Worker* `keep_source`: Include the original Python source.
345*60517a1eSAndroid Build Coastguard Worker* `omit_source`: Don't include the original py source.
346*60517a1eSAndroid Build Coastguard Worker* `omit_if_generated_source`: Keep the original source if it's a regular source
347*60517a1eSAndroid Build Coastguard Worker  file, but omit it if it's a generated file.
348*60517a1eSAndroid Build Coastguard Worker""",
349*60517a1eSAndroid Build Coastguard Worker        ),
350*60517a1eSAndroid Build Coastguard Worker        # Required attribute, but details vary by rule.
351*60517a1eSAndroid Build Coastguard Worker        # Use create_srcs_attr to create one.
352*60517a1eSAndroid Build Coastguard Worker        "srcs": None,
353*60517a1eSAndroid Build Coastguard Worker        # NOTE: In Google, this attribute is deprecated, and can only
354*60517a1eSAndroid Build Coastguard Worker        # effectively be PY3 or PY3ONLY. Externally, with Bazel, this attribute
355*60517a1eSAndroid Build Coastguard Worker        # has a separate story.
356*60517a1eSAndroid Build Coastguard Worker        # Required attribute, but the details vary by rule.
357*60517a1eSAndroid Build Coastguard Worker        # Use create_srcs_version_attr to create one.
358*60517a1eSAndroid Build Coastguard Worker        "srcs_version": None,
359*60517a1eSAndroid Build Coastguard Worker        "_precompile_add_to_runfiles_flag": attr.label(
360*60517a1eSAndroid Build Coastguard Worker            default = "//python/config_settings:precompile_add_to_runfiles",
361*60517a1eSAndroid Build Coastguard Worker            providers = [BuildSettingInfo],
362*60517a1eSAndroid Build Coastguard Worker        ),
363*60517a1eSAndroid Build Coastguard Worker        "_precompile_flag": attr.label(
364*60517a1eSAndroid Build Coastguard Worker            default = "//python/config_settings:precompile",
365*60517a1eSAndroid Build Coastguard Worker            providers = [BuildSettingInfo],
366*60517a1eSAndroid Build Coastguard Worker        ),
367*60517a1eSAndroid Build Coastguard Worker        "_precompile_source_retention_flag": attr.label(
368*60517a1eSAndroid Build Coastguard Worker            default = "//python/config_settings:precompile_source_retention",
369*60517a1eSAndroid Build Coastguard Worker            providers = [BuildSettingInfo],
370*60517a1eSAndroid Build Coastguard Worker        ),
371*60517a1eSAndroid Build Coastguard Worker        # Force enabling auto exec groups, see
372*60517a1eSAndroid Build Coastguard Worker        # https://bazel.build/extending/auto-exec-groups#how-enable-particular-rule
373*60517a1eSAndroid Build Coastguard Worker        "_use_auto_exec_groups": attr.bool(default = True),
374*60517a1eSAndroid Build Coastguard Worker    },
375*60517a1eSAndroid Build Coastguard Worker    allow_none = True,
376*60517a1eSAndroid Build Coastguard Worker)
377*60517a1eSAndroid Build Coastguard Worker
378*60517a1eSAndroid Build Coastguard Worker# Attributes specific to Python executable-equivalent rules. Such rules may not
379*60517a1eSAndroid Build Coastguard Worker# accept Python sources (e.g. some packaged-version of a py_test/py_binary), but
380*60517a1eSAndroid Build Coastguard Worker# still accept Python source-agnostic settings.
381*60517a1eSAndroid Build Coastguard WorkerAGNOSTIC_EXECUTABLE_ATTRS = union_attrs(
382*60517a1eSAndroid Build Coastguard Worker    DATA_ATTRS,
383*60517a1eSAndroid Build Coastguard Worker    {
384*60517a1eSAndroid Build Coastguard Worker        "env": attr.string_dict(
385*60517a1eSAndroid Build Coastguard Worker            doc = """\
386*60517a1eSAndroid Build Coastguard WorkerDictionary of strings; optional; values are subject to `$(location)` and "Make
387*60517a1eSAndroid Build Coastguard Workervariable" substitution.
388*60517a1eSAndroid Build Coastguard Worker
389*60517a1eSAndroid Build Coastguard WorkerSpecifies additional environment variables to set when the target is executed by
390*60517a1eSAndroid Build Coastguard Worker`test` or `run`.
391*60517a1eSAndroid Build Coastguard Worker""",
392*60517a1eSAndroid Build Coastguard Worker        ),
393*60517a1eSAndroid Build Coastguard Worker        # The value is required, but varies by rule and/or rule type. Use
394*60517a1eSAndroid Build Coastguard Worker        # create_stamp_attr to create one.
395*60517a1eSAndroid Build Coastguard Worker        "stamp": None,
396*60517a1eSAndroid Build Coastguard Worker    },
397*60517a1eSAndroid Build Coastguard Worker    allow_none = True,
398*60517a1eSAndroid Build Coastguard Worker)
399*60517a1eSAndroid Build Coastguard Worker
400*60517a1eSAndroid Build Coastguard Worker# Attributes specific to Python test-equivalent executable rules. Such rules may
401*60517a1eSAndroid Build Coastguard Worker# not accept Python sources (e.g. some packaged-version of a py_test/py_binary),
402*60517a1eSAndroid Build Coastguard Worker# but still accept Python source-agnostic settings.
403*60517a1eSAndroid Build Coastguard WorkerAGNOSTIC_TEST_ATTRS = union_attrs(
404*60517a1eSAndroid Build Coastguard Worker    AGNOSTIC_EXECUTABLE_ATTRS,
405*60517a1eSAndroid Build Coastguard Worker    # Tests have stamping disabled by default.
406*60517a1eSAndroid Build Coastguard Worker    create_stamp_attr(default = 0),
407*60517a1eSAndroid Build Coastguard Worker    {
408*60517a1eSAndroid Build Coastguard Worker        "env_inherit": attr.string_list(
409*60517a1eSAndroid Build Coastguard Worker            doc = """\
410*60517a1eSAndroid Build Coastguard WorkerList of strings; optional
411*60517a1eSAndroid Build Coastguard Worker
412*60517a1eSAndroid Build Coastguard WorkerSpecifies additional environment variables to inherit from the external
413*60517a1eSAndroid Build Coastguard Workerenvironment when the test is executed by bazel test.
414*60517a1eSAndroid Build Coastguard Worker""",
415*60517a1eSAndroid Build Coastguard Worker        ),
416*60517a1eSAndroid Build Coastguard Worker        # TODO(b/176993122): Remove when Bazel automatically knows to run on darwin.
417*60517a1eSAndroid Build Coastguard Worker        "_apple_constraints": attr.label_list(
418*60517a1eSAndroid Build Coastguard Worker            default = [
419*60517a1eSAndroid Build Coastguard Worker                "@platforms//os:ios",
420*60517a1eSAndroid Build Coastguard Worker                "@platforms//os:macos",
421*60517a1eSAndroid Build Coastguard Worker                "@platforms//os:tvos",
422*60517a1eSAndroid Build Coastguard Worker                "@platforms//os:visionos",
423*60517a1eSAndroid Build Coastguard Worker                "@platforms//os:watchos",
424*60517a1eSAndroid Build Coastguard Worker            ],
425*60517a1eSAndroid Build Coastguard Worker        ),
426*60517a1eSAndroid Build Coastguard Worker    },
427*60517a1eSAndroid Build Coastguard Worker)
428*60517a1eSAndroid Build Coastguard Worker
429*60517a1eSAndroid Build Coastguard Worker# Attributes specific to Python binary-equivalent executable rules. Such rules may
430*60517a1eSAndroid Build Coastguard Worker# not accept Python sources (e.g. some packaged-version of a py_test/py_binary),
431*60517a1eSAndroid Build Coastguard Worker# but still accept Python source-agnostic settings.
432*60517a1eSAndroid Build Coastguard WorkerAGNOSTIC_BINARY_ATTRS = union_attrs(
433*60517a1eSAndroid Build Coastguard Worker    AGNOSTIC_EXECUTABLE_ATTRS,
434*60517a1eSAndroid Build Coastguard Worker    create_stamp_attr(default = -1),
435*60517a1eSAndroid Build Coastguard Worker)
436*60517a1eSAndroid Build Coastguard Worker
437*60517a1eSAndroid Build Coastguard Worker# Attribute names common to all Python rules
438*60517a1eSAndroid Build Coastguard WorkerCOMMON_ATTR_NAMES = [
439*60517a1eSAndroid Build Coastguard Worker    "compatible_with",
440*60517a1eSAndroid Build Coastguard Worker    "deprecation",
441*60517a1eSAndroid Build Coastguard Worker    "distribs",  # NOTE: Currently common to all rules, but slated for removal
442*60517a1eSAndroid Build Coastguard Worker    "exec_compatible_with",
443*60517a1eSAndroid Build Coastguard Worker    "exec_properties",
444*60517a1eSAndroid Build Coastguard Worker    "features",
445*60517a1eSAndroid Build Coastguard Worker    "restricted_to",
446*60517a1eSAndroid Build Coastguard Worker    "tags",
447*60517a1eSAndroid Build Coastguard Worker    "target_compatible_with",
448*60517a1eSAndroid Build Coastguard Worker    # NOTE: The testonly attribute requires careful handling: None/unset means
449*60517a1eSAndroid Build Coastguard Worker    # to use the `package(default_testonly`) value, which isn't observable
450*60517a1eSAndroid Build Coastguard Worker    # during the loading phase.
451*60517a1eSAndroid Build Coastguard Worker    "testonly",
452*60517a1eSAndroid Build Coastguard Worker    "toolchains",
453*60517a1eSAndroid Build Coastguard Worker    "visibility",
454*60517a1eSAndroid Build Coastguard Worker] + list(COMMON_ATTRS)  # Use list() instead .keys() so it's valid Python
455*60517a1eSAndroid Build Coastguard Worker
456*60517a1eSAndroid Build Coastguard Worker# Attribute names common to all test=True rules
457*60517a1eSAndroid Build Coastguard WorkerTEST_ATTR_NAMES = COMMON_ATTR_NAMES + [
458*60517a1eSAndroid Build Coastguard Worker    "args",
459*60517a1eSAndroid Build Coastguard Worker    "size",
460*60517a1eSAndroid Build Coastguard Worker    "timeout",
461*60517a1eSAndroid Build Coastguard Worker    "flaky",
462*60517a1eSAndroid Build Coastguard Worker    "shard_count",
463*60517a1eSAndroid Build Coastguard Worker    "local",
464*60517a1eSAndroid Build Coastguard Worker] + list(AGNOSTIC_TEST_ATTRS)  # Use list() instead .keys() so it's valid Python
465*60517a1eSAndroid Build Coastguard Worker
466*60517a1eSAndroid Build Coastguard Worker# Attribute names common to all executable=True rules
467*60517a1eSAndroid Build Coastguard WorkerBINARY_ATTR_NAMES = COMMON_ATTR_NAMES + [
468*60517a1eSAndroid Build Coastguard Worker    "args",
469*60517a1eSAndroid Build Coastguard Worker    "output_licenses",  # NOTE: Common to all rules, but slated for removal
470*60517a1eSAndroid Build Coastguard Worker] + list(AGNOSTIC_BINARY_ATTRS)  # Use list() instead .keys() so it's valid Python
471