| # 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() |