rules_python icon indicating copy to clipboard operation
rules_python copied to clipboard

Gazelle: `python_default_visibility` Not Applied to `py_test` Targets

Open ctcjab opened this issue 2 months ago • 0 comments

Description

The # gazelle:python_default_visibility directive is not being applied to py_test targets, even though it correctly applies to py_library and py_binary targets. This occurs when using # gazelle:map_kind to map to custom rule macros.

Environment

  • rules_python version: Latest (tested with rules_python_gazelle_plugin)
  • Gazelle version: Latest
  • Bazel version: 8.0+
  • Operating System: Linux

Reproduction Steps

  1. Create a BUILD file with the following directives:
# gazelle:map_kind py_binary py_binary @aspect_rules_py//py:defs.bzl
# gazelle:map_kind py_library py_library @aspect_rules_py//py:defs.bzl
# gazelle:map_kind py_test py_test @aspect_rules_py//py:defs.bzl
# gazelle:python_default_visibility //visibility:public
  1. Run bazel run //:gazelle

  2. Observe generated BUILD files

Expected Behavior

Both py_library and py_test targets should have visibility = ["//visibility:public"] added:

py_library(
    name = "mylib",
    srcs = ["mylib.py"],
    visibility = ["//visibility:public"],  # ✓ Generated correctly
)

py_test(
    name = "mylib_test",
    srcs = ["mylib_test.py"],
    visibility = ["//visibility:public"],  # ✗ NOT generated
    deps = [":mylib"],
)

Actual Behavior

Only py_library targets get the visibility attribute. py_test targets are generated without any visibility:

py_library(
    name = "mylib",
    srcs = ["mylib.py"],
    visibility = ["//visibility:public"],  # ✓ Generated correctly
)

ctc_py_test(
    name = "mylib_test",
    srcs = ["mylib_test.py"],
    # visibility is missing
    deps = [":mylib"],
)

Impact

This causes visibility errors when test targets need to be referenced as dependencies elsewhere in the build graph (e.g., for creating development virtual environments that include test dependencies).

Example error:

ERROR: /path/to/BUILD:12:12: in _py_venv_binary rule //ctc_pylibs:dev_venv:
Visibility error: target '//ctc_pylibs/auth:vault_test' is not visible from
target '//ctc_pylibs:dev_venv'

Root Cause

In rules_python_gazelle_plugin/python/generate.go, the visibility is correctly retrieved from configuration:

visibility := cfg.Visibility()

However, when generating py_test targets, the newPyTestTargetBuilder function (line ~412) creates targets without calling addVisibility(visibility):

newPyTestTargetBuilder := func(srcs *treeset.Set, pyTestTargetName string) *targetBuilder {
    // ... parsing logic ...
    return newTargetBuilder(pyTestKind, pyTestTargetName, pythonProjectRoot, args.Rel, pyFileNames, cfg.ResolveSiblingImports()).
        addSrcs(srcs).
        addModuleDependencies(deps).
        addResolvedDependencies(annotations.includeDeps).
        setAnnotations(*annotations).
        generateImportsAttribute()
        // ❌ Missing: .addVisibility(visibility)
}

In contrast, py_library and py_binary targets correctly call addVisibility(visibility).

Proposed Fix

Add .addVisibility(visibility) to the test target builder in generate.go:

return newTargetBuilder(pyTestKind, pyTestTargetName, pythonProjectRoot, args.Rel, pyFileNames, cfg.ResolveSiblingImports()).
    addSrcs(srcs).
    addModuleDependencies(deps).
    addResolvedDependencies(annotations.includeDeps).
    setAnnotations(*annotations).
    generateImportsAttribute().
    addVisibility(visibility)  // ← Add this line

This should be added in both the per-package test generation path (line ~438) and the per-file test generation path (line ~460).

Additional Context

The python_default_visibility directive is documented to apply to "all python targets" according to the directives documentation, but in practice it only applies to non-test targets.

Similarly, the python_visibility directive (which appends additional visibility labels) also does not affect test targets.

ctcjab avatar Nov 04 '25 03:11 ctcjab