🐞 bug report
Affected Rule
The issue is caused by the rule: `py_binary`
py_test likely has the same issue because it shares the executable creation
implementation, but the minimal reproduction below uses py_binary.
Is this a regression?
Unknown. I reproduced this with `rules_python` 2.0.3, but I have not
identified the last version where this worked correctly.
Description
When two Python executable targets in the same package have names
containing path separators and the same basename, rules_python derives the
venv output directory from the executable basename. Because the venv outputs are
declared package-relative, distinct labels can declare the same venv output
paths.
For example, both of these labels are distinct:
But both generated executables have basename tool, so unpatched
rules_python 2.0.3 declares the same venv root for both targets:
bazel-out/.../bin/_tool.venv
Expected behavior: distinct executable labels should use distinct venv output
directories, for example _foo_tool.venv and _bar_tool.venv.
This looks related to the slash target handling fixed in #3790 for bootstrap
stub placement, but this issue affects the venv output prefix.
🔬 Minimal Reproduction
Create a fresh bzlmod workspace with these files:
MODULE.bazel
module(
name = "rules_python_slash_venv_repro",
version = "0.0.0",
)
bazel_dep(
name = "rules_python",
version = "2.0.3",
)
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
python_version = "3.11",
)
use_repo(python, "python_3_11")
register_toolchains("@python_3_11//:all")
BUILD.bazel
load("@rules_python//python:defs.bzl", "py_binary")
py_binary(
name = "foo/tool",
srcs = ["foo_tool.py"],
main = "foo_tool.py",
)
py_binary(
name = "bar/tool",
srcs = ["bar_tool.py"],
main = "bar_tool.py",
)
foo_tool.py
def main():
print("foo")
if __name__ == "__main__":
main()
bar_tool.py
def main():
print("bar")
if __name__ == "__main__":
main()
Then run:
bazel clean --expunge
bazel build //:foo/tool //:bar/tool
bazel aquery 'outputs(".*_tool[.]venv/pyvenv[.]cfg", deps(//:foo/tool + //:bar/tool))'
🔥 Exception or Error
Bazel 9.1.1 completes the build in this minimal reproduction, apparently
because these FileWrite actions are identical. However, filtered aquery shows
that two distinct targets declare the same package-relative venv output:
action 'Writing file _tool.venv/pyvenv.cfg'
Target: //:bar/tool
Outputs: [bazel-out/k8-fastbuild/bin/_tool.venv/pyvenv.cfg]
action 'Writing file _tool.venv/pyvenv.cfg'
Target: //:foo/tool
Outputs: [bazel-out/k8-fastbuild/bin/_tool.venv/pyvenv.cfg]
🌍 Your Environment
Operating System:
Ubuntu 24.04.3 LTS
Linux 6.8.0-124-generic x86_64
Output of bazel version:
Bazelisk version: v1.27.0
Build label: 9.1.1
Build target: @@//src/main/java/com/google/devtools/build/lib/bazel:BazelServer
Build time: Wed Jun 03 15:41:13 2026 (1780501273)
Build timestamp: 1780501273
Build timestamp as int: 1780501273
Rules_python version:
Anything else relevant?
The reproduction uses the rules_python Python toolchain extension with
python_version = "3.11".
🐞 bug report
Affected Rule
The issue is caused by the rule: `py_binary`py_testlikely has the same issue because it shares the executable creationimplementation, but the minimal reproduction below uses
py_binary.Is this a regression?
Unknown. I reproduced this with `rules_python` 2.0.3, but I have notidentified the last version where this worked correctly.
Description
When two Python executable targets in the same package have namescontaining path separators and the same basename,
rules_pythonderives thevenv output directory from the executable basename. Because the venv outputs are
declared package-relative, distinct labels can declare the same venv output
paths.
For example, both of these labels are distinct:
But both generated executables have basename
tool, so unpatchedrules_python2.0.3 declares the same venv root for both targets:Expected behavior: distinct executable labels should use distinct venv output
directories, for example
_foo_tool.venvand_bar_tool.venv.This looks related to the slash target handling fixed in #3790 for bootstrap
stub placement, but this issue affects the venv output prefix.
🔬 Minimal Reproduction
Create a fresh bzlmod workspace with these files:
MODULE.bazelBUILD.bazelfoo_tool.pybar_tool.pyThen run:
bazel clean --expunge bazel build //:foo/tool //:bar/tool bazel aquery 'outputs(".*_tool[.]venv/pyvenv[.]cfg", deps(//:foo/tool + //:bar/tool))'🔥 Exception or Error
🌍 Your Environment
Operating System:
Output of
bazel version:Rules_python version:
Anything else relevant?
The reproduction uses the
rules_pythonPython toolchain extension withpython_version = "3.11".