Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ Unreleased changes template.
* (pypi) Direct HTTP urls for wheels and sdists are now supported when using
{obj}`experimental_index_url` (bazel downloader).
Partially fixes [#2363](https://github.com/bazelbuild/rules_python/issues/2363).
* (rules) Added {obj}`interpreter_args` attribute to `py_binary` and `py_test`,
which allows pass arguments to the interpreter before the regular args.

{#v0-0-0-removed}
### Removed
Expand Down
19 changes: 19 additions & 0 deletions python/private/py_executable.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,21 @@ EXECUTABLE_ATTRS = dicts.add(
IMPORTS_ATTRS,
COVERAGE_ATTRS,
{
"interpreter_args": lambda: attrb.StringList(
doc = """
Arguments that are only applicable to the interpreter.

The args an interpreter supports are specific to the interpreter. For
CPython, see https://docs.python.org/3/using/cmdline.html.

:::{note}
Only supported for {obj}`--bootstrap_impl=script`. Ignored otherwise.
:::

:::{versionadded} VERSION_NEXT_FEATURE
:::
""",
),
"legacy_create_init": lambda: attrb.Int(
default = -1,
values = [-1, 0, 1],
Expand Down Expand Up @@ -664,6 +679,10 @@ def _create_stage1_bootstrap(
"%recreate_venv_at_runtime%": str(int(venv.recreate_venv_at_runtime)) if venv else "0",
"%target%": str(ctx.label),
"%workspace_name%": ctx.workspace_name,
"%interpreter_args%": "\n".join([
'"{}"'.format(v)
for v in ctx.attr.interpreter_args
]),
}

if stage2_bootstrap:
Expand Down
6 changes: 6 additions & 0 deletions python/private/stage1_bootstrap_template.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ IS_ZIPFILE="%is_zipfile%"
# 0 or 1
RECREATE_VENV_AT_RUNTIME="%recreate_venv_at_runtime%"

# array of strings
declare -a INTERPRETER_ARGS_FROM_TARGET=(
%interpreter_args%
)

if [[ "$IS_ZIPFILE" == "1" ]]; then
# NOTE: Macs have an old version of mktemp, so we must use only the
# minimal functionality of it.
Expand Down Expand Up @@ -222,6 +227,7 @@ command=(
"${interpreter_env[@]}"
"$python_exe"
"${interpreter_args[@]}"
"${INTERPRETER_ARGS_FROM_TARGET[@]}"
"$stage2_bootstrap"
"$@"
)
Expand Down
9 changes: 9 additions & 0 deletions tests/bootstrap_impls/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,13 @@ sh_py_run_test(
target_compatible_with = SUPPORTS_BOOTSTRAP_SCRIPT,
)

py_reconfig_test(
name = "interpreter_args_test",
srcs = ["interpreter_args_test.py"],
bootstrap_impl = "script",
interpreter_args = ["-XSPECIAL=1"],
main = "interpreter_args_test.py",
target_compatible_with = SUPPORTS_BOOTSTRAP_SCRIPT,
)

relative_path_test_suite(name = "relative_path_tests")
23 changes: 23 additions & 0 deletions tests/bootstrap_impls/interpreter_args_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2025 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.

import sys
import unittest

class InterpreterArgsTest(unittest.TestCase):
def test_interpreter_args(self):
self.assertEqual(sys._xoptions, {"SPECIAL": "1"})

if __name__ == "__main__":
unittest.main()