Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions news/slash-target-venv-output.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(rules) Fixed venv output paths for `py_binary` and `py_test` targets whose
names contain path separators so distinct targets with the same basename no
longer share the same venv output directory.
5 changes: 4 additions & 1 deletion python/private/py_executable.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ def _create_executable(
else:
base_executable_name = executable.basename

# Venv outputs are package-relative, so preserve the full target name to
# avoid collisions between targets like foo/tool, bar/tool, and foo_tool.
venv_output_prefix = ctx.label.name
venv = None

# The check for stage2_bootstrap_template is to support legacy
Expand All @@ -318,7 +321,7 @@ def _create_executable(
):
venv = _create_venv(
ctx,
output_prefix = base_executable_name,
output_prefix = venv_output_prefix,
imports = imports,
runtime_details = runtime_details,
add_runfiles_root_to_sys_path = (
Expand Down
39 changes: 39 additions & 0 deletions tests/base_rules/py_executable_base_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,45 @@ def _test_py_runtime_info_provided_impl(env, target):

_tests.append(_test_py_runtime_info_provided)

def _test_venv_output_prefix_with_path_separators(name, config):
rt_util.helper_target(
config.rule,
name = name + "/foo/tool",
srcs = ["main.py"],
main = "main.py",
)
rt_util.helper_target(
config.rule,
name = name + "/bar/tool",
srcs = ["main.py"],
main = "main.py",
)
rt_util.helper_target(
config.rule,
name = name + "/foo_tool",
srcs = ["main.py"],
main = "main.py",
)
analysis_test(
name = name,
impl = _test_venv_output_prefix_with_path_separators_impl,
targets = {
"bar": name + "/bar/tool",
"foo": name + "/foo/tool",
"foo_underscore": name + "/foo_tool",
},
)

def _test_venv_output_prefix_with_path_separators_impl(env, targets):
for target in [targets.foo, targets.bar, targets.foo_underscore]:
target = env.expect.that_target(target)
venv_file = "*/_{}.venv/*site-packages/bazel.pth".format(
target.meta.format_str("{name}"),
)
target.runfiles().contains_predicate(matching.str_matches(venv_file))

_tests.append(_test_venv_output_prefix_with_path_separators)

def _test_windows_target_with_path_separators(name, config):
rt_util.helper_target(
config.rule,
Expand Down