Skip to content
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ Unreleased changes are tracked as individual files in the [news/](./news)
directory, or view the [latest generated
changelog](https://rules-python.readthedocs.io/en/latest/changelog.html).

### Fixed
* Fixed {attr}`py_library.pyi_deps` being erroneously included in {obj}`PyInfo.transitive_sources` and propagated into downstream binary and test runfiles.

{#v2-4-0}
## [2.4.0] - 2026-09-22

Expand Down
9 changes: 8 additions & 1 deletion python/private/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,14 @@ def create_py_info(
for target in ctx.attr.pyi_deps:
# PyInfo may not be present e.g. cc_library rules.
if PyInfo in target or (BuiltinPyInfo != None and BuiltinPyInfo in target):
py_info.merge(_get_py_info(target))
info = _get_py_info(target)
Comment thread
rickeylev marked this conversation as resolved.
Outdated
py_info.imports.add(info.imports)
Comment thread
rickeylev marked this conversation as resolved.
Outdated
if hasattr(info, "transitive_pyi_files"):
py_info.transitive_pyi_files.add(info.transitive_pyi_files)
if hasattr(info, "transitive_original_sources"):
py_info.transitive_original_sources.add(info.transitive_original_sources)
Comment thread
rickeylev marked this conversation as resolved.
Outdated
elif hasattr(info, "transitive_sources"):
py_info.transitive_original_sources.add(info.transitive_sources)

py_info.transitive_sources.add(required_py_files)

Expand Down
3 changes: 3 additions & 0 deletions tests/base_rules/base_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ def _test_py_info_populated_impl(env, target):
"{package}/lib2.pyi",
"{package}/subject.pyi",
])
info.transitive_sources().contains_exactly([
"{package}/test_py_info_populated_subject.py",
])

_tests.append(_test_py_info_populated)

Expand Down
37 changes: 37 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,43 @@ def _test_py_runtime_info_provided_impl(env, target):

_tests.append(_test_py_runtime_info_provided)

def _test_pyi_deps_not_in_runfiles(name, config):
rt_util.helper_target(
py_library,
name = name + "_types",
srcs = [rt_util.empty_file(name + "_type_stub.py")],
)
rt_util.helper_target(
py_library,
name = name + "_lib",
srcs = [rt_util.empty_file(name + "_lib.py")],
pyi_deps = [name + "_types"],
)
rt_util.helper_target(
config.rule,
name = name + "_subject",
srcs = [name + "_main.py"],
main = name + "_main.py",
deps = [name + "_lib"],
)
analysis_test(
name = name,
impl = _test_pyi_deps_not_in_runfiles_impl,
target = name + "_subject",
)

def _test_pyi_deps_not_in_runfiles_impl(env, target):
target = env.expect.that_target(target)
target.runfiles().contains_at_least([
"{workspace}/{package}/{test_name}_main.py",
"{workspace}/{package}/{test_name}_lib.py",
])
target.runfiles().not_contains(
"{workspace}/{package}/{test_name}_type_stub.py",
)

_tests.append(_test_pyi_deps_not_in_runfiles)

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