diff --git a/WORKSPACE b/WORKSPACE index f64e7e5a1..39d6ebb29 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -26,23 +26,24 @@ load("@rules_python//python:repositories.bzl", "py_repositories") py_repositories() -local_repository( - name = "python", - path = "third_party/python_legacy", -) +load("//third_party:python_configure.bzl", "python_configure") + +python_configure() + +load("@local_config_python//:defs.bzl", "interpreter") -load("@python//:defs.bzl", "interpreter") +register_toolchains("@local_config_python//:py_toolchain") load("@rules_python//python:pip.bzl", "pip_parse") pip_parse( name = "pypi", - requirements_lock = "//:requirements.txt", - python_interpreter = interpreter, extra_pip_args = [ "--index-url", "https://pypi.org/simple/", ], + python_interpreter = interpreter, + requirements_lock = "//:requirements.txt", ) load("@pypi//:requirements.bzl", "install_deps") diff --git a/configure.sh b/configure.sh index b1b138543..95fec058a 100755 --- a/configure.sh +++ b/configure.sh @@ -51,37 +51,7 @@ function inside_docker() { fi } -function write_legacy_python_repo() { - mkdir -p third_party/python_legacy - - # empty WORKSPACE - cat > third_party/python_legacy/WORKSPACE <<'EOF' -# AUTOGENERATED by configure.sh. -# This file is intentionally empty. -EOF - - # simple BUILD that exports defs.bzl - cat > third_party/python_legacy/BUILD <<'EOF' -# AUTOGENERATED by configure.sh. - -package(default_visibility = ["//visibility:public"]) -exports_files(["defs.bzl"]) -EOF - - # defs.bzl MUST define 'interpreter' as a string, not a function. - # We also export py_runtime to satisfy older loads. - cat > third_party/python_legacy/defs.bzl < +The `configure.sh` script detects your Python interpreter and sets up a Bazel toolchain. If you need to manually specify a Python interpreter, you can do so by passing the `--python` flag or by setting the `PYTHON_BIN_PATH` environment variable: + + +
+  ./configure.sh --python=/path/to/python
+
+ + +> [!TIP] +> You can also bypass manual configuration by passing the Python path directly to Bazel using `--repo_env=PYTHON_BIN_PATH=/path/to/python`. + Now build TensorFlow Quantum: diff --git a/third_party/BUILD b/third_party/BUILD index c172b454e..a4792a7cd 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -11,3 +11,11 @@ # 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. + +package(default_visibility = ["//visibility:public"]) + +exports_files([ + "python_configure.bzl", + "python/BUILD.tpl", + "python/defs.bzl.tpl", +]) diff --git a/third_party/python/BUILD b/third_party/python/BUILD new file mode 100644 index 000000000..1a0ec3114 --- /dev/null +++ b/third_party/python/BUILD @@ -0,0 +1,17 @@ +# Copyright 2026 The TensorFlow Quantum 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. +# ============================================================================== + +# Build file intentionally left empty. +# This file is used to define the Python interpreter path for the TFQ build. diff --git a/third_party/python/BUILD.tpl b/third_party/python/BUILD.tpl new file mode 100644 index 000000000..88752bad0 --- /dev/null +++ b/third_party/python/BUILD.tpl @@ -0,0 +1,37 @@ +# Copyright 2026 The TensorFlow Quantum Authors +# +# 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. + +"""Generated BUILD file for the Python toolchain repository.""" + +load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair") + +package(default_visibility = ["//visibility:public"]) + +# Detected path: %{PYTHON_BIN_PATH}% +py_runtime( + name = "py3_runtime", + interpreter_path = "%{PYTHON_BIN_PATH}%", + python_version = "PY3", +) + +py_runtime_pair( + name = "py_runtime_pair", + py3_runtime = ":py3_runtime", +) + +toolchain( + name = "py_toolchain", + toolchain = ":py_runtime_pair", + toolchain_type = "@bazel_tools//tools/python:toolchain_type", +) diff --git a/third_party/python/defs.bzl.tpl b/third_party/python/defs.bzl.tpl new file mode 100644 index 000000000..1cc59a099 --- /dev/null +++ b/third_party/python/defs.bzl.tpl @@ -0,0 +1,16 @@ +# Copyright 2026 The TensorFlow Quantum 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. + +# Generated by python_configure.bzl +interpreter = "%{PYTHON_BIN_PATH}%" diff --git a/third_party/python_configure.bzl b/third_party/python_configure.bzl new file mode 100644 index 000000000..688206465 --- /dev/null +++ b/third_party/python_configure.bzl @@ -0,0 +1,61 @@ +# Copyright 2026 The TensorFlow Quantum Authors +# +# 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. + +"""Repository rule for Python detection and toolchain registration.""" + +def _python_configure_impl(repository_ctx): + python_bin = repository_ctx.os.environ.get("PYTHON_BIN_PATH") or \ + repository_ctx.which("python3") or \ + repository_ctx.which("python") + + if not python_bin: + fail("Python interpreter not found. Please provide it via --repo_env=PYTHON_BIN_PATH=/path/to/python or set the PYTHON_BIN_PATH environment variable.") + + substitutions = {"%{PYTHON_BIN_PATH}%": str(python_bin).replace("\\", "\\\\")} + + repository_ctx.template( + "BUILD", + Label("//third_party/python:BUILD.tpl"), + substitutions, + ) + repository_ctx.template( + "defs.bzl", + Label("//third_party/python:defs.bzl.tpl"), + substitutions, + ) + +_python_configure = repository_rule( + implementation = _python_configure_impl, + environ = [ + "PYTHON_BIN_PATH", + "PATH", + ], +) + +def python_configure(): + """Configures the Python toolchain for TFQ, TF, and XLA. + + Three identical repositories are created to satisfy the naming expectations + of various external dependencies: + - 'local_config_python': Used by TensorFlow Quantum and its internal rules. + - 'local_execution_config_python': Required by TensorFlow (org_tensorflow) + and TSL for certain toolchain configurations. + - 'python': Provided as a generic handle. + + Although redundant, this ensures compatibility across the diverse dependency + tree without requiring extensive repo_mapping. + """ + _python_configure(name = "local_config_python") + _python_configure(name = "local_execution_config_python") + _python_configure(name = "python")