xref: /aosp_15_r20/external/bazelbuild-rules_python/python/private/util.bzl (revision 60517a1edbc8ecf509223e9af94a7adec7d736b8)
1*60517a1eSAndroid Build Coastguard Worker# Copyright 2023 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
15*60517a1eSAndroid Build Coastguard Worker"""Functionality shared by multiple pieces of code."""
16*60517a1eSAndroid Build Coastguard Worker
17*60517a1eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:types.bzl", "types")
18*60517a1eSAndroid Build Coastguard Worker
19*60517a1eSAndroid Build Coastguard Workerdef copy_propagating_kwargs(from_kwargs, into_kwargs = None):
20*60517a1eSAndroid Build Coastguard Worker    """Copies args that must be compatible between two targets with a dependency relationship.
21*60517a1eSAndroid Build Coastguard Worker
22*60517a1eSAndroid Build Coastguard Worker    This is intended for when one target depends on another, so they must have
23*60517a1eSAndroid Build Coastguard Worker    compatible settings such as `testonly` and `compatible_with`. This usually
24*60517a1eSAndroid Build Coastguard Worker    happens when a macro generates multiple targets, some of which depend
25*60517a1eSAndroid Build Coastguard Worker    on one another, so their settings must be compatible.
26*60517a1eSAndroid Build Coastguard Worker
27*60517a1eSAndroid Build Coastguard Worker    Args:
28*60517a1eSAndroid Build Coastguard Worker        from_kwargs: keyword args dict whose common kwarg will be copied.
29*60517a1eSAndroid Build Coastguard Worker        into_kwargs: optional keyword args dict that the values from `from_kwargs`
30*60517a1eSAndroid Build Coastguard Worker            will be copied into. The values in this dict will take precedence
31*60517a1eSAndroid Build Coastguard Worker            over the ones in `from_kwargs` (i.e., if this has `testonly` already
32*60517a1eSAndroid Build Coastguard Worker            set, then it won't be overwritten).
33*60517a1eSAndroid Build Coastguard Worker            NOTE: THIS WILL BE MODIFIED IN-PLACE.
34*60517a1eSAndroid Build Coastguard Worker
35*60517a1eSAndroid Build Coastguard Worker    Returns:
36*60517a1eSAndroid Build Coastguard Worker        Keyword args to use for the depender target derived from the dependency
37*60517a1eSAndroid Build Coastguard Worker        target. If `into_kwargs` was passed in, then that same object is
38*60517a1eSAndroid Build Coastguard Worker        returned; this is to facilitate easy `**` expansion.
39*60517a1eSAndroid Build Coastguard Worker    """
40*60517a1eSAndroid Build Coastguard Worker    if into_kwargs == None:
41*60517a1eSAndroid Build Coastguard Worker        into_kwargs = {}
42*60517a1eSAndroid Build Coastguard Worker
43*60517a1eSAndroid Build Coastguard Worker    # Include tags because people generally expect tags to propagate.
44*60517a1eSAndroid Build Coastguard Worker    for attr in ("testonly", "tags", "compatible_with", "restricted_to"):
45*60517a1eSAndroid Build Coastguard Worker        if attr in from_kwargs and attr not in into_kwargs:
46*60517a1eSAndroid Build Coastguard Worker            into_kwargs[attr] = from_kwargs[attr]
47*60517a1eSAndroid Build Coastguard Worker    return into_kwargs
48*60517a1eSAndroid Build Coastguard Worker
49*60517a1eSAndroid Build Coastguard Worker# The implementation of the macros and tagging mechanism follows the example
50*60517a1eSAndroid Build Coastguard Worker# set by rules_cc and rules_java.
51*60517a1eSAndroid Build Coastguard Worker
52*60517a1eSAndroid Build Coastguard Worker_MIGRATION_TAG = "__PYTHON_RULES_MIGRATION_DO_NOT_USE_WILL_BREAK__"
53*60517a1eSAndroid Build Coastguard Worker
54*60517a1eSAndroid Build Coastguard Workerdef add_migration_tag(attrs):
55*60517a1eSAndroid Build Coastguard Worker    """Add a special tag to `attrs` to aid migration off native rles.
56*60517a1eSAndroid Build Coastguard Worker
57*60517a1eSAndroid Build Coastguard Worker    Args:
58*60517a1eSAndroid Build Coastguard Worker        attrs: dict of keyword args. The `tags` key will be modified in-place.
59*60517a1eSAndroid Build Coastguard Worker
60*60517a1eSAndroid Build Coastguard Worker    Returns:
61*60517a1eSAndroid Build Coastguard Worker        The same `attrs` object, but modified.
62*60517a1eSAndroid Build Coastguard Worker    """
63*60517a1eSAndroid Build Coastguard Worker    add_tag(attrs, _MIGRATION_TAG)
64*60517a1eSAndroid Build Coastguard Worker    return attrs
65*60517a1eSAndroid Build Coastguard Worker
66*60517a1eSAndroid Build Coastguard Workerdef add_tag(attrs, tag):
67*60517a1eSAndroid Build Coastguard Worker    """Adds `tag` to `attrs["tags"]`.
68*60517a1eSAndroid Build Coastguard Worker
69*60517a1eSAndroid Build Coastguard Worker    Args:
70*60517a1eSAndroid Build Coastguard Worker        attrs: dict of keyword args. It is modified in place.
71*60517a1eSAndroid Build Coastguard Worker        tag: str, the tag to add.
72*60517a1eSAndroid Build Coastguard Worker    """
73*60517a1eSAndroid Build Coastguard Worker    if "tags" in attrs and attrs["tags"] != None:
74*60517a1eSAndroid Build Coastguard Worker        tags = attrs["tags"]
75*60517a1eSAndroid Build Coastguard Worker
76*60517a1eSAndroid Build Coastguard Worker        # Preserve the input type: this allows a test verifying the underlying
77*60517a1eSAndroid Build Coastguard Worker        # rule can accept the tuple for the tags argument.
78*60517a1eSAndroid Build Coastguard Worker        if types.is_tuple(tags):
79*60517a1eSAndroid Build Coastguard Worker            attrs["tags"] = tags + (tag,)
80*60517a1eSAndroid Build Coastguard Worker        else:
81*60517a1eSAndroid Build Coastguard Worker            # List concatenation is necessary because the original value
82*60517a1eSAndroid Build Coastguard Worker            # may be a frozen list.
83*60517a1eSAndroid Build Coastguard Worker            attrs["tags"] = tags + [tag]
84*60517a1eSAndroid Build Coastguard Worker    else:
85*60517a1eSAndroid Build Coastguard Worker        attrs["tags"] = [tag]
86*60517a1eSAndroid Build Coastguard Worker
87*60517a1eSAndroid Build Coastguard WorkerIS_BAZEL_7_OR_HIGHER = hasattr(native, "starlark_doc_extract")
88*60517a1eSAndroid Build Coastguard Worker
89*60517a1eSAndroid Build Coastguard Worker# Bazel 5.4 has a bug where every access of testing.ExecutionInfo is a
90*60517a1eSAndroid Build Coastguard Worker# different object that isn't equal to any other. This is fixed in bazel 6+.
91*60517a1eSAndroid Build Coastguard WorkerIS_BAZEL_6_OR_HIGHER = testing.ExecutionInfo == testing.ExecutionInfo
92*60517a1eSAndroid Build Coastguard Worker
93*60517a1eSAndroid Build Coastguard Worker_marker_rule_to_detect_bazel_6_4_or_higher = rule(implementation = lambda ctx: None)
94*60517a1eSAndroid Build Coastguard Worker
95*60517a1eSAndroid Build Coastguard Worker# Bazel 6.4 and higher have a bug fix where rule names show up in the str()
96*60517a1eSAndroid Build Coastguard Worker# of a rule. See
97*60517a1eSAndroid Build Coastguard Worker# https://github.com/bazelbuild/bazel/commit/002490b9a2376f0b2ea4a37102c5e94fc50a65ba
98*60517a1eSAndroid Build Coastguard Worker# https://github.com/bazelbuild/bazel/commit/443cbcb641e17f7337ccfdecdfa5e69bc16cae55
99*60517a1eSAndroid Build Coastguard Worker# This technique is done instead of using native.bazel_version because,
100*60517a1eSAndroid Build Coastguard Worker# under stardoc, the native.bazel_version attribute is entirely missing, which
101*60517a1eSAndroid Build Coastguard Worker# prevents doc generation from being able to correctly generate docs.
102*60517a1eSAndroid Build Coastguard WorkerIS_BAZEL_6_4_OR_HIGHER = "_marker_rule_to_detect_bazel_6_4_or_higher" in str(
103*60517a1eSAndroid Build Coastguard Worker    _marker_rule_to_detect_bazel_6_4_or_higher,
104*60517a1eSAndroid Build Coastguard Worker)
105