Skip to content

Commit 5c6af5e

Browse files
committed
wip: basic interpreter_args impl
1 parent c0b5075 commit 5c6af5e

File tree

5 files changed

+59
-0
lines changed

5 files changed

+59
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ Unreleased changes template.
9191
* (pypi) Direct HTTP urls for wheels and sdists are now supported when using
9292
{obj}`experimental_index_url` (bazel downloader).
9393
Partially fixes [#2363](https://github.com/bazelbuild/rules_python/issues/2363).
94+
* (rules) Added {obj}`interpreter_args` attribute to `py_binary` and `py_test`,
95+
which allows pass arguments to the interpreter before the regular args.
9496

9597
{#v0-0-0-removed}
9698
### Removed

python/private/py_executable.bzl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,21 @@ EXECUTABLE_ATTRS = dicts.add(
8787
IMPORTS_ATTRS,
8888
COVERAGE_ATTRS,
8989
{
90+
"interpreter_args": lambda: attrb.StringList(
91+
doc = """
92+
Arguments that are only applicable to the interpreter.
93+
94+
The args an interpreter supports are specific to the interpreter. For
95+
CPython, see https://docs.python.org/3/using/cmdline.html.
96+
97+
:::{note}
98+
Only supported for {obj}`--bootstrap_impl=script`. Ignored otherwise.
99+
:::
100+
101+
:::{versionadded} VERSION_NEXT_FEATURE
102+
:::
103+
""",
104+
),
90105
"legacy_create_init": lambda: attrb.Int(
91106
default = -1,
92107
values = [-1, 0, 1],
@@ -664,6 +679,10 @@ def _create_stage1_bootstrap(
664679
"%recreate_venv_at_runtime%": str(int(venv.recreate_venv_at_runtime)) if venv else "0",
665680
"%target%": str(ctx.label),
666681
"%workspace_name%": ctx.workspace_name,
682+
"%interpreter_args%": "\n".join([
683+
'"{}"'.format(v)
684+
for v in ctx.attr.interpreter_args
685+
]),
667686
}
668687

669688
if stage2_bootstrap:

python/private/stage1_bootstrap_template.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ IS_ZIPFILE="%is_zipfile%"
2121
# 0 or 1
2222
RECREATE_VENV_AT_RUNTIME="%recreate_venv_at_runtime%"
2323

24+
# array of strings
25+
declare -a INTERPRETER_ARGS_FROM_TARGET=(
26+
%interpreter_args%
27+
)
28+
2429
if [[ "$IS_ZIPFILE" == "1" ]]; then
2530
# NOTE: Macs have an old version of mktemp, so we must use only the
2631
# minimal functionality of it.
@@ -222,6 +227,7 @@ command=(
222227
"${interpreter_env[@]}"
223228
"$python_exe"
224229
"${interpreter_args[@]}"
230+
"${INTERPRETER_ARGS_FROM_TARGET[@]}"
225231
"$stage2_bootstrap"
226232
"$@"
227233
)

tests/bootstrap_impls/BUILD.bazel

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,13 @@ sh_py_run_test(
124124
target_compatible_with = SUPPORTS_BOOTSTRAP_SCRIPT,
125125
)
126126

127+
py_reconfig_test(
128+
name = "interpreter_args_test",
129+
srcs = ["interpreter_args_test.py"],
130+
bootstrap_impl = "script",
131+
interpreter_args = ["-XSPECIAL=1"],
132+
main = "interpreter_args_test.py",
133+
target_compatible_with = SUPPORTS_BOOTSTRAP_SCRIPT,
134+
)
135+
127136
relative_path_test_suite(name = "relative_path_tests")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2025 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import sys
16+
import unittest
17+
18+
class InterpreterArgsTest(unittest.TestCase):
19+
def test_interpreter_args(self):
20+
self.assertEqual(sys._xoptions, {"SPECIAL": "1"})
21+
22+
if __name__ == "__main__":
23+
unittest.main()

0 commit comments

Comments
 (0)