Skip to content

Fix use of generic target in runtime package dependencies#23248

Open
RaniSputnik wants to merge 4 commits intopantsbuild:mainfrom
RaniSputnik:fix/follow-dependencies-through-generic-target
Open

Fix use of generic target in runtime package dependencies#23248
RaniSputnik wants to merge 4 commits intopantsbuild:mainfrom
RaniSputnik:fix/follow-dependencies-through-generic-target

Conversation

@RaniSputnik
Copy link
Copy Markdown

What

Fixes the following setup:

# BUILD
pex_binary(name='bin_a', entry_point='main_a.py')
pex_binary(name='bin_b', entry_point='main_b.py')
target(name='all_bins', dependencies=[':bin_a', ':bin_b'])
python_test(name="tests", runtime_package_dependencies=[":all_bins"])

Previously the PEX dependencies would not get packaged and materialized when the tests were run.

Why

Allows a target() alias to be used in runtime_package_dependencies to group packageable targets, rather than having to list each one individually. This would help simplify a setup I have where I have the misfortune of having to write a loop to generate a list of targets:

# BUILD
for model in models:
  docker_image(name=model.name)

target(name="models", dependencies=[model.name for model in models])

Using the generic target I can isolate this mess to the one relevant directory and keep the rest of the codebase clear.

Test plan

  • New test added to cover the scenario

Open questions

  • Is this the kind of thing we would add to the release notes? Or is it a bit niche?
  • Is this the most reliable way to implement this? I was surprised to find that generic target isn't modeled as a TargetGenerator would that be a more robust fix? (sounds like it would be a much more invasive change)
  • I think this issue affects the archive target too. Shall I investigate that in this PR? Or keep it small and investigate separately?

@RaniSputnik RaniSputnik changed the title Unwrap GenericTarget deps in runtime_package_dependencies Fix use of generic target in runtime package dependencies Apr 14, 2026
@benjyw
Copy link
Copy Markdown
Contributor

benjyw commented Apr 14, 2026

  • Is this the kind of thing we would add to the release notes? Or is it a bit niche?

I think this is useful in the release notes, yes. docs/notes/2.32.x.md in this case.

  • Is this the most reliable way to implement this? I was surprised to find that generic target isn't modeled as a TargetGenerator would that be a more robust fix? (sounds like it would be a much more invasive change)

GenericTarget has no sources, so there is nothing for it to generate targets from. It is just a simple target. So your approach here is good.

I think this issue affects the archive target too. Shall I investigate that in this PR? Or keep it small and investigate separately?

I don't think one would naturally use archive() as a grouping target?

Copy link
Copy Markdown
Contributor

@benjyw benjyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! Just one fix needed, plus the release notes

Comment thread src/python/pants/core/goals/test.py Outdated
RaniSputnik and others added 3 commits April 15, 2026 08:51
Allows a `target()` alias to be used in `runtime_package_dependencies` to
group packageable targets, rather than having to list each one individually.

Uses a ShouldTraverseDepsPredicate to delegate traversal to the existing
transitive_dependency_mapping infrastructure, which handles batched-concurrent
BFS and cycle safety.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@RaniSputnik RaniSputnik force-pushed the fix/follow-dependencies-through-generic-target branch from 0b8b431 to e8ba29a Compare April 15, 2026 07:56
@RaniSputnik RaniSputnik marked this pull request as ready for review April 15, 2026 07:57
@RaniSputnik
Copy link
Copy Markdown
Author

I don't think one would naturally use archive() as a grouping target?

Apologies for being unclear @benjyw, I meant that if one were to depend on a generic target in the packages field of archive, I don't think the transitive dependencies would be packaged. I haven't actually tested that so I might be wrong - I'll investigate if I get the chance.

GenericTarget has no sources, so there is nothing for it to generate targets from. It is just a simple target. So your approach here is good.

Right, that makes sense.

The thing that felt weird to me about the implementation is it felt like a behaviour that generic target should own rather than it being imposed on the caller. I'm not familiar enough with the codebase to know how that would work, and the dependency walking + predicate model also makes sense 🤷‍♂️ it just means that callers has to be mindful to implement the behaviour of generic target rather than it being implemented once and used transparently everywhere.


Thanks for the review! Should be all ready to go now 🚀

@benjyw
Copy link
Copy Markdown
Contributor

benjyw commented Apr 15, 2026

Currently the callers have to know how they want to traverse the graph. But yeah, it's possible that "give me my direct dependencies" should always elide GenericTarget, and so we could push this logic up to there.

Comment thread docs/notes/2.32.x.md Outdated

When generating lockfiles, the new `python.resolves_to_uploaded_prior_to` option can be used to pass along [`--uploaded-prior-to`](https://pip.pypa.io/en/stable/user_guide/#filtering-by-upload-time). This allows you to filter packages by their upload time to an index, only considering packages that were uploaded before a specified point in time.

Including a generic `target` in the `runtime_package_dependencies` of `python_test` now correctly packages the transitive dependencies.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a matter of correctness - it's more that we moved the goalposts (to a hopefully better place). But I wouldn't classify the previous behavior as a bug, more as an over-literal interpretation of direct dependencies...

Comment thread docs/notes/2.32.x.md Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants