blob: 5268260237533e6b33c6f2e49195071eee4d275a [file] [log] [blame]
# Copyright 2022 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Attributes for Python rules."""
load(":common/python/common.bzl", "union_attrs")
load(":common/python/providers.bzl", "PyInfo")
load(
":common/python/semantics.bzl",
"DEPS_ATTR_ALLOW_RULES",
"PLATFORMS_LOCATION",
"SRCS_ATTR_ALLOW_FILES",
"TOOLS_REPO",
)
load(":common/cc/cc_info.bzl", _CcInfo = "CcInfo")
PackageSpecificationInfo = _builtins.toplevel.PackageSpecificationInfo
_STAMP_VALUES = [-1, 0, 1]
def create_stamp_attr(**kwargs):
return {"stamp": attr.int(values = _STAMP_VALUES, **kwargs)}
def create_srcs_attr(*, mandatory):
return {
"srcs": attr.label_list(
# Google builds change the set of allowed files.
allow_files = SRCS_ATTR_ALLOW_FILES,
mandatory = mandatory,
# Necessary for --compile_one_dependency to work.
flags = ["DIRECT_COMPILE_TIME_INPUT"],
),
}
SRCS_VERSION_ALL_VALUES = ["PY2", "PY2ONLY", "PY2AND3", "PY3", "PY3ONLY"]
SRCS_VERSION_NON_CONVERSION_VALUES = ["PY2AND3", "PY2ONLY", "PY3ONLY"]
def create_srcs_version_attr(values):
return {
"srcs_version": attr.string(
default = "PY2AND3",
values = values,
),
}
def copy_common_binary_kwargs(kwargs):
return {
key: kwargs[key]
for key in BINARY_ATTR_NAMES
if key in kwargs
}
def copy_common_test_kwargs(kwargs):
return {
key: kwargs[key]
for key in TEST_ATTR_NAMES
if key in kwargs
}
CC_TOOLCHAIN = {
# NOTE: The `cc_helper.find_cpp_toolchain()` function expects the attribute
# name to be this name.
"_cc_toolchain": attr.label(default = "@" + TOOLS_REPO + "//tools/cpp:current_cc_toolchain"),
}
# The common "data" attribute definition.
DATA_ATTRS = {
# NOTE: The "flags" attribute is deprecated, but there isn't an alternative
# way to specify that constraints should be ignored.
"data": attr.label_list(
allow_files = True,
flags = ["SKIP_CONSTRAINTS_OVERRIDE"],
),
}
NATIVE_RULES_ALLOWLIST_ATTRS = {
"_native_rules_allowlist": attr.label(
default = configuration_field(
fragment = "py",
name = "native_rules_allowlist",
),
providers = [PackageSpecificationInfo],
),
}
# Attributes common to all rules.
COMMON_ATTRS = union_attrs(
DATA_ATTRS,
NATIVE_RULES_ALLOWLIST_ATTRS,
{
# TODO(b/148103851): This attribute is deprecated and slated for
# removal.
# NOTE: The license attribute is missing in some Java integration tests,
# so fallback to a regular string_list for that case.
# buildifier: disable=attr-license
"licenses": attr.license() if hasattr(attr, "license") else attr.string_list(),
# NOTE: This attribute is deprecated and slated for removal.
"distribs": attr.string_list(),
},
allow_none = True,
)
# Attributes common to rules accepting Python sources and deps.
PY_SRCS_ATTRS = union_attrs(
{
# Required attribute, but details vary by rule.
# Use create_srcs_attr to create one.
"srcs": None,
"deps": attr.label_list(
providers = [[PyInfo], [_CcInfo]],
# TODO(b/228692666): Google-specific; remove these allowances once
# the depot is cleaned up.
allow_rules = DEPS_ATTR_ALLOW_RULES,
),
# NOTE: In Google, this attribute is deprecated, and can only
# effectively be PY3 or PY3ONLY. Externally, with Bazel, this attribute
# has a separate story.
# Required attribute, but the details vary by rule.
# Use create_srcs_version_attr to create one.
"srcs_version": None,
},
allow_none = True,
)
# Attributes specific to Python executable-equivalent rules. Such rules may not
# accept Python sources (e.g. some packaged-version of a py_test/py_binary), but
# still accept Python source-agnostic settings.
AGNOSTIC_EXECUTABLE_ATTRS = union_attrs(
DATA_ATTRS,
{
"env": attr.string_dict(
doc = """\
Dictionary of strings; optional; values are subject to `$(location)` and "Make
variable" substitution.
Specifies additional environment variables to set when the target is executed by
`test` or `run`.
""",
),
# The value is required, but varies by rule and/or rule type. Use
# create_stamp_attr to create one.
"stamp": None,
},
allow_none = True,
)
# Attributes specific to Python test-equivalent executable rules. Such rules may
# not accept Python sources (e.g. some packaged-version of a py_test/py_binary),
# but still accept Python source-agnostic settings.
AGNOSTIC_TEST_ATTRS = union_attrs(
AGNOSTIC_EXECUTABLE_ATTRS,
# Tests have stamping disabled by default.
create_stamp_attr(default = 0),
{
"env_inherit": attr.string_list(
doc = """\
List of strings; optional
Specifies additional environment variables to inherit from the external
environment when the test is executed by bazel test.
""",
),
# TODO(b/176993122): Remove when Bazel automatically knows to run on darwin.
"_apple_constraints": attr.label_list(
default = [
PLATFORMS_LOCATION + "/os:ios",
PLATFORMS_LOCATION + "/os:macos",
PLATFORMS_LOCATION + "/os:tvos",
PLATFORMS_LOCATION + "/os:visionos",
PLATFORMS_LOCATION + "/os:watchos",
],
),
},
)
# Attributes specific to Python binary-equivalent executable rules. Such rules may
# not accept Python sources (e.g. some packaged-version of a py_test/py_binary),
# but still accept Python source-agnostic settings.
AGNOSTIC_BINARY_ATTRS = union_attrs(
AGNOSTIC_EXECUTABLE_ATTRS,
create_stamp_attr(default = -1),
)
# Attribute names common to all Python rules
COMMON_ATTR_NAMES = [
"compatible_with",
"deprecation",
"distribs", # NOTE: Currently common to all rules, but slated for removal
"exec_compatible_with",
"exec_properties",
"features",
"restricted_to",
"tags",
"target_compatible_with",
# NOTE: The testonly attribute requires careful handling: None/unset means
# to use the `package(default_testonly`) value, which isn't observable
# during the loading phase.
"testonly",
"toolchains",
"visibility",
] + COMMON_ATTRS.keys()
# Attribute names common to all test=True rules
TEST_ATTR_NAMES = COMMON_ATTR_NAMES + [
"args",
"size",
"timeout",
"flaky",
"shard_count",
"local",
] + AGNOSTIC_TEST_ATTRS.keys()
# Attribute names common to all executable=True rules
BINARY_ATTR_NAMES = COMMON_ATTR_NAMES + [
"args",
"output_licenses", # NOTE: Common to all rules, but slated for removal
] + AGNOSTIC_BINARY_ATTRS.keys()