Skip to content

Add TraverseIfNotPackageTarget deps traversal predicate for use in plugins#19306

Merged
jriddy merged 4 commits intomainfrom
cognifloyd/package-deps-traversal
Jun 17, 2023
Merged

Add TraverseIfNotPackageTarget deps traversal predicate for use in plugins#19306
jriddy merged 4 commits intomainfrom
cognifloyd/package-deps-traversal

Conversation

@cognifloyd
Copy link
Member

@cognifloyd cognifloyd commented Jun 14, 2023

This builds on #19272, adding another should_traverse_deps_predicate that stops dependency traversal at any package targets.

This is mostly extracted from #19155.

TraverseIfNotPackageTarget will be useful whenever a TransitiveTargetsRequest, CoarsenedTargetsRequest, or DependenciesRequest could benefit from treating package targets as leaves. This PR does not change any TransitiveTargetsRequests because that is probably a change in user-facing behavior (even if it counts as a bugfix) and needs to be documented as such. This PR merely adds the feature, which, on its own, does not impact anything else.

Related:

Co-authored-by: Andreas Stenius <andreas.stenius@imanage.com>
@cognifloyd cognifloyd changed the title Add TraverseIfNotPackageTarget predicate for use in plugins Add TraverseIfNotPackageTarget deps traversal predicate for use in plugins Jun 15, 2023
@thejcannon
Copy link
Member

thejcannon commented Jun 16, 2023

Throw #18044 in the pile in the description 😄

Whoops. Related, but not the exact same 😛

@cognifloyd
Copy link
Member Author

@benjyw could you review this one? It's the next piece of the deps traversal work.

return False
if self.always_traverse_roots and target.address in self.roots:
return True
for field_set_type in self.package_field_set_types:
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice if we could do isinstance(target, PackageTarget) or some such. This is where our very flexible fieldset model becomes a pain... But it is what it is, for now at least.

Copy link
Member

Choose a reason for hiding this comment

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

If you file an issue, assign it to me. I have some thoughts

@jriddy jriddy merged commit d5812af into main Jun 17, 2023
@jriddy jriddy deleted the cognifloyd/package-deps-traversal branch June 17, 2023 23:43
Copy link
Member

@thejcannon thejcannon left a comment

Choose a reason for hiding this comment

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

VERY excited for this. I really can't express my thanks enough to you @cognifloyd for this. It's something that's plagued my headspace for quite some time, and this is quite elegant/simple.

I know this PR is merged, so all of my comments are just suggestions for if this code is going to be touched again.

class TraverseIfNotPackageTarget(ShouldTraverseDepsPredicate):
package_field_set_types: FrozenOrderedSet[PackageFieldSet]
roots: FrozenOrderedSet[Address]
always_traverse_roots: bool = True # traverse roots even if they are package targets
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't need a default, since you define __init__

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed in #19387

Comment on lines +213 to +214
# False means do not traverse dependencies of this target
return False
Copy link
Member

Choose a reason for hiding this comment

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

If you find yourself doing this often (and I forsee it happening) please switch to an enum so it is explicit 😄

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah. Yes, that would make this more clear.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed in #19387

Comment on lines +211 to +215
for field_set_type in self.package_field_set_types:
if field_set_type.is_applicable(target):
# False means do not traverse dependencies of this target
return False
return True
Copy link
Member

Choose a reason for hiding this comment

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

Alternatively you could use any(field_set_type.is_applicable(target) for field_set_type in self.package_field_set_types)

I tend to prefer any and all because they express intent better (e.g. "return if any is packageable" is the English way, and it uses the word any)

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed in #19387



@dataclass(frozen=True)
class TraverseIfNotPackageTarget(ShouldTraverseDepsPredicate):
Copy link
Member

Choose a reason for hiding this comment

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

If you're in the vicinity of this code, add a helpful little docstring maybe?

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed in #19387

cognifloyd added a commit that referenced this pull request Jun 27, 2023
This addresses feedback from
#19306 (review)

The `ShouldTraverseDepsPredicate` returned a bool before. But, the bool
was sometimes unclear, so this adds an enum to make the code more
readable.

NB: The values of the enum are not important.
cognifloyd added a commit that referenced this pull request Jul 15, 2023
…19155)

This builds on:
- #19272
- #19306
- #19387

This only updates the `pex_binary` rule to use the new
`TraverseIfNotPackageTarget` predicate when requesting the source files
that should be included in this pex. Wheels, other pex_binaries, and
other package targets are not handled via this code path since those are
not python sources that get included in the pex based on the
`include_sources` flag.

Fixes #15855

This fixes #15855 because anything in a `python_distribution` does not
need to be included as a source file in the `pex_binary`. wheels get
included via the `LocalDists` rules. In some cases, we might still get
more sources in the pex than intended. This might happen if a dependency
is inferred between sources, bypassing the logic that looks for wheels
that own the relevant things. In any case, this is PR provides an
improvement and resolves the sample error in #15855.

Related:
- #18254
- #17368
- #15082

---------

Co-authored-by: Joshua Cannon <joshdcannon@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants