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"common attributes for whl_library and pip_repository" 16*60517a1eSAndroid Build Coastguard Worker 17*60517a1eSAndroid Build Coastguard WorkerATTRS = { 18*60517a1eSAndroid Build Coastguard Worker "download_only": attr.bool( 19*60517a1eSAndroid Build Coastguard Worker doc = """ 20*60517a1eSAndroid Build Coastguard WorkerWhether to use "pip download" instead of "pip wheel". Disables building wheels from source, but allows use of 21*60517a1eSAndroid Build Coastguard Worker--platform, --python-version, --implementation, and --abi in --extra_pip_args to download wheels for a different 22*60517a1eSAndroid Build Coastguard Workerplatform from the host platform. 23*60517a1eSAndroid Build Coastguard Worker """, 24*60517a1eSAndroid Build Coastguard Worker ), 25*60517a1eSAndroid Build Coastguard Worker "enable_implicit_namespace_pkgs": attr.bool( 26*60517a1eSAndroid Build Coastguard Worker default = False, 27*60517a1eSAndroid Build Coastguard Worker doc = """ 28*60517a1eSAndroid Build Coastguard WorkerIf true, disables conversion of native namespace packages into pkg-util style namespace packages. When set all py_binary 29*60517a1eSAndroid Build Coastguard Workerand py_test targets must specify either `legacy_create_init=False` or the global Bazel option 30*60517a1eSAndroid Build Coastguard Worker`--incompatible_default_to_explicit_init_py` to prevent `__init__.py` being automatically generated in every directory. 31*60517a1eSAndroid Build Coastguard Worker 32*60517a1eSAndroid Build Coastguard WorkerThis option is required to support some packages which cannot handle the conversion to pkg-util style. 33*60517a1eSAndroid Build Coastguard Worker """, 34*60517a1eSAndroid Build Coastguard Worker ), 35*60517a1eSAndroid Build Coastguard Worker "environment": attr.string_dict( 36*60517a1eSAndroid Build Coastguard Worker doc = """ 37*60517a1eSAndroid Build Coastguard WorkerEnvironment variables to set in the pip subprocess. 38*60517a1eSAndroid Build Coastguard WorkerCan be used to set common variables such as `http_proxy`, `https_proxy` and `no_proxy` 39*60517a1eSAndroid Build Coastguard WorkerNote that pip is run with "--isolated" on the CLI so `PIP_<VAR>_<NAME>` 40*60517a1eSAndroid Build Coastguard Workerstyle env vars are ignored, but env vars that control requests and urllib3 41*60517a1eSAndroid Build Coastguard Workercan be passed. If you need `PIP_<VAR>_<NAME>`, take a look at `extra_pip_args` 42*60517a1eSAndroid Build Coastguard Workerand `envsubst`. 43*60517a1eSAndroid Build Coastguard Worker """, 44*60517a1eSAndroid Build Coastguard Worker default = {}, 45*60517a1eSAndroid Build Coastguard Worker ), 46*60517a1eSAndroid Build Coastguard Worker "envsubst": attr.string_list( 47*60517a1eSAndroid Build Coastguard Worker mandatory = False, 48*60517a1eSAndroid Build Coastguard Worker doc = """\ 49*60517a1eSAndroid Build Coastguard WorkerA list of environment variables to substitute (e.g. `["PIP_INDEX_URL", 50*60517a1eSAndroid Build Coastguard Worker"PIP_RETRIES"]`). The corresponding variables are expanded in `extra_pip_args` 51*60517a1eSAndroid Build Coastguard Workerusing the syntax `$VARNAME` or `${VARNAME}` (expanding to empty string if unset) 52*60517a1eSAndroid Build Coastguard Workeror `${VARNAME:-default}` (expanding to default if the variable is unset or empty 53*60517a1eSAndroid Build Coastguard Workerin the environment). Note: On Bazel 6 and Bazel 7.0 changes to the variables named 54*60517a1eSAndroid Build Coastguard Workerhere do not cause packages to be re-fetched. Don't fetch different things based 55*60517a1eSAndroid Build Coastguard Workeron the value of these variables. 56*60517a1eSAndroid Build Coastguard Worker""", 57*60517a1eSAndroid Build Coastguard Worker ), 58*60517a1eSAndroid Build Coastguard Worker "experimental_requirement_cycles": attr.string_list_dict( 59*60517a1eSAndroid Build Coastguard Worker default = {}, 60*60517a1eSAndroid Build Coastguard Worker doc = """\ 61*60517a1eSAndroid Build Coastguard WorkerA mapping of dependency cycle names to a list of requirements which form that cycle. 62*60517a1eSAndroid Build Coastguard Worker 63*60517a1eSAndroid Build Coastguard WorkerRequirements which form cycles will be installed together and taken as 64*60517a1eSAndroid Build Coastguard Workerdependencies together in order to ensure that the cycle is always satisified. 65*60517a1eSAndroid Build Coastguard Worker 66*60517a1eSAndroid Build Coastguard WorkerExample: 67*60517a1eSAndroid Build Coastguard Worker `sphinx` depends on `sphinxcontrib-serializinghtml` 68*60517a1eSAndroid Build Coastguard Worker When listing both as requirements, ala 69*60517a1eSAndroid Build Coastguard Worker 70*60517a1eSAndroid Build Coastguard Worker ``` 71*60517a1eSAndroid Build Coastguard Worker py_binary( 72*60517a1eSAndroid Build Coastguard Worker name = "doctool", 73*60517a1eSAndroid Build Coastguard Worker ... 74*60517a1eSAndroid Build Coastguard Worker deps = [ 75*60517a1eSAndroid Build Coastguard Worker "@pypi//sphinx:pkg", 76*60517a1eSAndroid Build Coastguard Worker "@pypi//sphinxcontrib_serializinghtml", 77*60517a1eSAndroid Build Coastguard Worker ] 78*60517a1eSAndroid Build Coastguard Worker ) 79*60517a1eSAndroid Build Coastguard Worker ``` 80*60517a1eSAndroid Build Coastguard Worker 81*60517a1eSAndroid Build Coastguard Worker Will produce a Bazel error such as 82*60517a1eSAndroid Build Coastguard Worker 83*60517a1eSAndroid Build Coastguard Worker ``` 84*60517a1eSAndroid Build Coastguard Worker ERROR: .../external/pypi_sphinxcontrib_serializinghtml/BUILD.bazel:44:6: in alias rule @pypi_sphinxcontrib_serializinghtml//:pkg: cycle in dependency graph: 85*60517a1eSAndroid Build Coastguard Worker //:doctool (...) 86*60517a1eSAndroid Build Coastguard Worker @pypi//sphinxcontrib_serializinghtml:pkg (...) 87*60517a1eSAndroid Build Coastguard Worker .-> @pypi_sphinxcontrib_serializinghtml//:pkg (...) 88*60517a1eSAndroid Build Coastguard Worker | @pypi_sphinxcontrib_serializinghtml//:_pkg (...) 89*60517a1eSAndroid Build Coastguard Worker | @pypi_sphinx//:pkg (...) 90*60517a1eSAndroid Build Coastguard Worker | @pypi_sphinx//:_pkg (...) 91*60517a1eSAndroid Build Coastguard Worker `-- @pypi_sphinxcontrib_serializinghtml//:pkg (...) 92*60517a1eSAndroid Build Coastguard Worker ``` 93*60517a1eSAndroid Build Coastguard Worker 94*60517a1eSAndroid Build Coastguard Worker Which we can resolve by configuring these two requirements to be installed together as a cycle 95*60517a1eSAndroid Build Coastguard Worker 96*60517a1eSAndroid Build Coastguard Worker ``` 97*60517a1eSAndroid Build Coastguard Worker pip_parse( 98*60517a1eSAndroid Build Coastguard Worker ... 99*60517a1eSAndroid Build Coastguard Worker experimental_requirement_cycles = { 100*60517a1eSAndroid Build Coastguard Worker "sphinx": [ 101*60517a1eSAndroid Build Coastguard Worker "sphinx", 102*60517a1eSAndroid Build Coastguard Worker "sphinxcontrib-serializinghtml", 103*60517a1eSAndroid Build Coastguard Worker ] 104*60517a1eSAndroid Build Coastguard Worker }, 105*60517a1eSAndroid Build Coastguard Worker ) 106*60517a1eSAndroid Build Coastguard Worker ``` 107*60517a1eSAndroid Build Coastguard Worker 108*60517a1eSAndroid Build Coastguard WorkerWarning: 109*60517a1eSAndroid Build Coastguard Worker If a dependency participates in multiple cycles, all of those cycles must be 110*60517a1eSAndroid Build Coastguard Worker collapsed down to one. For instance `a <-> b` and `a <-> c` cannot be listed 111*60517a1eSAndroid Build Coastguard Worker as two separate cycles. 112*60517a1eSAndroid Build Coastguard Worker""", 113*60517a1eSAndroid Build Coastguard Worker ), 114*60517a1eSAndroid Build Coastguard Worker "experimental_target_platforms": attr.string_list( 115*60517a1eSAndroid Build Coastguard Worker default = [], 116*60517a1eSAndroid Build Coastguard Worker doc = """\ 117*60517a1eSAndroid Build Coastguard WorkerA list of platforms that we will generate the conditional dependency graph for 118*60517a1eSAndroid Build Coastguard Workercross platform wheels by parsing the wheel metadata. This will generate the 119*60517a1eSAndroid Build Coastguard Workercorrect dependencies for packages like `sphinx` or `pylint`, which include 120*60517a1eSAndroid Build Coastguard Worker`colorama` when installed and used on Windows platforms. 121*60517a1eSAndroid Build Coastguard Worker 122*60517a1eSAndroid Build Coastguard WorkerAn empty list means falling back to the legacy behaviour where the host 123*60517a1eSAndroid Build Coastguard Workerplatform is the target platform. 124*60517a1eSAndroid Build Coastguard Worker 125*60517a1eSAndroid Build Coastguard WorkerWARNING: It may not work as expected in cases where the python interpreter 126*60517a1eSAndroid Build Coastguard Workerimplementation that is being used at runtime is different between different platforms. 127*60517a1eSAndroid Build Coastguard WorkerThis has been tested for CPython only. 128*60517a1eSAndroid Build Coastguard Worker 129*60517a1eSAndroid Build Coastguard WorkerFor specific target platforms use values of the form `<os>_<arch>` where `<os>` 130*60517a1eSAndroid Build Coastguard Workeris one of `linux`, `osx`, `windows` and arch is one of `x86_64`, `x86_32`, 131*60517a1eSAndroid Build Coastguard Worker`aarch64`, `s390x` and `ppc64le`. 132*60517a1eSAndroid Build Coastguard Worker 133*60517a1eSAndroid Build Coastguard WorkerYou can also target a specific Python version by using `cp3<minor_version>_<os>_<arch>`. 134*60517a1eSAndroid Build Coastguard WorkerIf multiple python versions are specified as target platforms, then select statements 135*60517a1eSAndroid Build Coastguard Workerof the `lib` and `whl` targets will include usage of version aware toolchain config 136*60517a1eSAndroid Build Coastguard Workersettings like `@rules_python//python/config_settings:is_python_3.y`. 137*60517a1eSAndroid Build Coastguard Worker 138*60517a1eSAndroid Build Coastguard WorkerSpecial values: `host` (for generating deps for the host platform only) and 139*60517a1eSAndroid Build Coastguard Worker`<prefix>_*` values. For example, `cp39_*`, `linux_*`, `cp39_linux_*`. 140*60517a1eSAndroid Build Coastguard Worker 141*60517a1eSAndroid Build Coastguard WorkerNOTE: this is not for cross-compiling Python wheels but rather for parsing the `whl` METADATA correctly. 142*60517a1eSAndroid Build Coastguard Worker""", 143*60517a1eSAndroid Build Coastguard Worker ), 144*60517a1eSAndroid Build Coastguard Worker "extra_pip_args": attr.string_list( 145*60517a1eSAndroid Build Coastguard Worker doc = """Extra arguments to pass on to pip. Must not contain spaces. 146*60517a1eSAndroid Build Coastguard Worker 147*60517a1eSAndroid Build Coastguard WorkerSupports environment variables using the syntax `$VARNAME` or 148*60517a1eSAndroid Build Coastguard Worker`${VARNAME}` (expanding to empty string if unset) or 149*60517a1eSAndroid Build Coastguard Worker`${VARNAME:-default}` (expanding to default if the variable is unset 150*60517a1eSAndroid Build Coastguard Workeror empty in the environment), if `"VARNAME"` is listed in the 151*60517a1eSAndroid Build Coastguard Worker`envsubst` attribute. See also `envsubst`. 152*60517a1eSAndroid Build Coastguard Worker""", 153*60517a1eSAndroid Build Coastguard Worker ), 154*60517a1eSAndroid Build Coastguard Worker "isolated": attr.bool( 155*60517a1eSAndroid Build Coastguard Worker doc = """\ 156*60517a1eSAndroid Build Coastguard WorkerWhether or not to pass the [--isolated](https://pip.pypa.io/en/stable/cli/pip/#cmdoption-isolated) flag to 157*60517a1eSAndroid Build Coastguard Workerthe underlying pip command. Alternatively, the {envvar}`RULES_PYTHON_PIP_ISOLATED` environment variable can be used 158*60517a1eSAndroid Build Coastguard Workerto control this flag. 159*60517a1eSAndroid Build Coastguard Worker""", 160*60517a1eSAndroid Build Coastguard Worker default = True, 161*60517a1eSAndroid Build Coastguard Worker ), 162*60517a1eSAndroid Build Coastguard Worker "pip_data_exclude": attr.string_list( 163*60517a1eSAndroid Build Coastguard Worker doc = "Additional data exclusion parameters to add to the pip packages BUILD file.", 164*60517a1eSAndroid Build Coastguard Worker ), 165*60517a1eSAndroid Build Coastguard Worker "python_interpreter": attr.string( 166*60517a1eSAndroid Build Coastguard Worker doc = """\ 167*60517a1eSAndroid Build Coastguard WorkerThe python interpreter to use. This can either be an absolute path or the name 168*60517a1eSAndroid Build Coastguard Workerof a binary found on the host's `PATH` environment variable. If no value is set 169*60517a1eSAndroid Build Coastguard Worker`python3` is defaulted for Unix systems and `python.exe` for Windows. 170*60517a1eSAndroid Build Coastguard Worker""", 171*60517a1eSAndroid Build Coastguard Worker # NOTE: This attribute should not have a default. See `_get_python_interpreter_attr` 172*60517a1eSAndroid Build Coastguard Worker # default = "python3" 173*60517a1eSAndroid Build Coastguard Worker ), 174*60517a1eSAndroid Build Coastguard Worker "python_interpreter_target": attr.label( 175*60517a1eSAndroid Build Coastguard Worker allow_single_file = True, 176*60517a1eSAndroid Build Coastguard Worker doc = """ 177*60517a1eSAndroid Build Coastguard WorkerIf you are using a custom python interpreter built by another repository rule, 178*60517a1eSAndroid Build Coastguard Workeruse this attribute to specify its BUILD target. This allows pip_repository to invoke 179*60517a1eSAndroid Build Coastguard Workerpip using the same interpreter as your toolchain. If set, takes precedence over 180*60517a1eSAndroid Build Coastguard Workerpython_interpreter. An example value: "@python3_x86_64-unknown-linux-gnu//:python". 181*60517a1eSAndroid Build Coastguard Worker""", 182*60517a1eSAndroid Build Coastguard Worker ), 183*60517a1eSAndroid Build Coastguard Worker "quiet": attr.bool( 184*60517a1eSAndroid Build Coastguard Worker default = True, 185*60517a1eSAndroid Build Coastguard Worker doc = """\ 186*60517a1eSAndroid Build Coastguard WorkerIf True, suppress printing stdout and stderr output to the terminal. 187*60517a1eSAndroid Build Coastguard Worker 188*60517a1eSAndroid Build Coastguard WorkerIf you would like to get more diagnostic output, set 189*60517a1eSAndroid Build Coastguard Worker{envvar}`RULES_PYTHON_REPO_DEBUG=1 <RULES_PYTHON_REPO_DEBUG>` 190*60517a1eSAndroid Build Coastguard Workeror 191*60517a1eSAndroid Build Coastguard Worker{envvar}`RULES_PYTHON_REPO_DEBUG_VERBOSITY=<INFO|DEBUG|TRACE> <RULES_PYTHON_REPO_DEBUG_VERBOSITY>` 192*60517a1eSAndroid Build Coastguard Worker""", 193*60517a1eSAndroid Build Coastguard Worker ), 194*60517a1eSAndroid Build Coastguard Worker # 600 is documented as default here: https://docs.bazel.build/versions/master/skylark/lib/repository_ctx.html#execute 195*60517a1eSAndroid Build Coastguard Worker "timeout": attr.int( 196*60517a1eSAndroid Build Coastguard Worker default = 600, 197*60517a1eSAndroid Build Coastguard Worker doc = "Timeout (in seconds) on the rule's execution duration.", 198*60517a1eSAndroid Build Coastguard Worker ), 199*60517a1eSAndroid Build Coastguard Worker} 200*60517a1eSAndroid Build Coastguard Worker 201*60517a1eSAndroid Build Coastguard Workerdef use_isolated(ctx, attr): 202*60517a1eSAndroid Build Coastguard Worker """Determine whether or not to pass the pip `--isolated` flag to the pip invocation. 203*60517a1eSAndroid Build Coastguard Worker 204*60517a1eSAndroid Build Coastguard Worker Args: 205*60517a1eSAndroid Build Coastguard Worker ctx: repository or module context 206*60517a1eSAndroid Build Coastguard Worker attr: attributes for the repo rule or tag extension 207*60517a1eSAndroid Build Coastguard Worker 208*60517a1eSAndroid Build Coastguard Worker Returns: 209*60517a1eSAndroid Build Coastguard Worker True if --isolated should be passed 210*60517a1eSAndroid Build Coastguard Worker """ 211*60517a1eSAndroid Build Coastguard Worker use_isolated = attr.isolated 212*60517a1eSAndroid Build Coastguard Worker 213*60517a1eSAndroid Build Coastguard Worker # The environment variable will take precedence over the attribute 214*60517a1eSAndroid Build Coastguard Worker isolated_env = ctx.os.environ.get("RULES_PYTHON_PIP_ISOLATED", None) 215*60517a1eSAndroid Build Coastguard Worker if isolated_env != None: 216*60517a1eSAndroid Build Coastguard Worker if isolated_env.lower() in ("0", "false"): 217*60517a1eSAndroid Build Coastguard Worker use_isolated = False 218*60517a1eSAndroid Build Coastguard Worker else: 219*60517a1eSAndroid Build Coastguard Worker use_isolated = True 220*60517a1eSAndroid Build Coastguard Worker 221*60517a1eSAndroid Build Coastguard Worker return use_isolated 222