blob: 6e5d93b16007b5bb4fc9b0815590d95b779a97fd [file] [log] [blame]
# Copyright 2024 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.
""
load("//python:versions.bzl", "WINDOWS_NAME")
load("//python/private:toolchains_repo.bzl", "get_host_os_arch")
def _get_python_interpreter_attr(ctx, *, python_interpreter = None):
"""A helper function for getting the `python_interpreter` attribute or it's default
Args:
ctx (repository_ctx): Handle to the rule repository context.
python_interpreter (str): The python interpreter override.
Returns:
str: The attribute value or it's default
"""
if python_interpreter:
return python_interpreter
if "win" in ctx.os.name:
return "python.exe"
else:
return "python3"
def _resolve_python_interpreter(ctx, *, python_interpreter = None, python_interpreter_target = None):
"""Helper function to find the python interpreter from the common attributes
Args:
ctx: Handle to the rule repository context.
python_interpreter: The python interpreter to use.
python_interpreter_target: The python interpreter to use after downloading the label.
Returns:
`path` object, for the resolved path to the Python interpreter.
"""
python_interpreter = _get_python_interpreter_attr(ctx, python_interpreter = python_interpreter)
if python_interpreter_target != None:
python_interpreter = ctx.path(python_interpreter_target)
(os, _) = get_host_os_arch(ctx)
# On Windows, the symlink doesn't work because Windows attempts to find
# Python DLLs where the symlink is, not where the symlink points.
if os == WINDOWS_NAME:
python_interpreter = python_interpreter.realpath
elif "/" not in python_interpreter:
# It's a plain command, e.g. "python3", to look up in the environment.
found_python_interpreter = ctx.which(python_interpreter)
if not found_python_interpreter:
fail("python interpreter `{}` not found in PATH".format(python_interpreter))
python_interpreter = found_python_interpreter
else:
python_interpreter = ctx.path(python_interpreter)
return python_interpreter
def _construct_pypath(rctx, *, entries):
"""Helper function to construct a PYTHONPATH.
Contains entries for code in this repo as well as packages downloaded from //python/pip_install:repositories.bzl.
This allows us to run python code inside repository rule implementations.
Args:
rctx: Handle to the repository_context.
entries: The list of entries to add to PYTHONPATH.
Returns: String of the PYTHONPATH.
"""
separator = ":" if not "windows" in rctx.os.name.lower() else ";"
pypath = separator.join([
str(rctx.path(entry).dirname)
# Use a dict as a way to remove duplicates and then sort it.
for entry in sorted({x: None for x in entries})
])
return pypath
pypi_repo_utils = struct(
resolve_python_interpreter = _resolve_python_interpreter,
construct_pythonpath = _construct_pypath,
)