Hey all, I'm trying to solve this bug (?): <https:...
# development
a
Hey all, I'm trying to solve this bug (?): https://github.com/pantsbuild/pants/issues/21443 What I noticed is that dependencies are not parametrized when using
!!
exclude transitive addresses. Therefore, these have a conflict in
transitive_targets()
(https://github.com/pantsbuild/pants/blob/4d96bccba3078497697337e67c09d4b77fa53067/src/python/pants/engine/internals/graph.py#L838) because they do not bring parametrization elements in their addresses. Where would be the best place to add these? I cannot find a way to resolve parametrization for those at that point of the code.
c
Excellent repro repo! With that, I hacked a proof-of-concept together, here's the diff for inspiration of a possible direction to tackle this (some of it is not needed, but I kept it in as I think it is a little known feature that you can catch rule invocations), and also, we can't always assume that the parameters for the target applies also to its dependencies so there's more work to be done to make this generally applicable:
Copy code
diff --git a/src/python/pants/engine/addresses.py b/src/python/pants/engine/addresses.py
index 4a0255cb4d..a6a4f2d53a 100644
--- a/src/python/pants/engine/addresses.py
+++ b/src/python/pants/engine/addresses.py
@@ -16,6 +16,7 @@ from pants.build_graph.address import MaybeAddress as MaybeAddress  # noqa: F401
 from pants.build_graph.address import ResolveError
 from pants.engine.collection import Collection
 from pants.util.strutil import bullet_list
+from pants.util.frozendict import FrozenDict
 
 
 def assert_single_address(addresses: Sequence[Address]) -> None:
@@ -62,6 +63,7 @@ class UnparsedAddressInputs:
     relative_to: str | None
     description_of_origin: str
     skip_invalid_addresses: bool
+    parameters: FrozenDict[str, str] | None
 
     def __init__(
         self,
@@ -77,3 +79,11 @@ class UnparsedAddressInputs:
         )
         object.__setattr__(self, "description_of_origin", description_of_origin)
         object.__setattr__(self, "skip_invalid_addresses", skip_invalid_addresses)
+        object.__setattr__(
+            self,
+            "parameters",
+            (
+                FrozenDict(owning_address.parameters)
+                if owning_address and owning_address.parameters else None
+            )
+        )
diff --git a/src/python/pants/engine/internals/graph.py b/src/python/pants/engine/internals/graph.py
index c1246e6e15..c96074311a 100644
--- a/src/python/pants/engine/internals/graph.py
+++ b/src/python/pants/engine/internals/graph.py
@@ -833,6 +833,7 @@ async def transitive_targets(
     for t in targets:
         unparsed = t.get(Dependencies).unevaluated_transitive_excludes
         if unparsed.values:
+            <http://logger.info|logger.info>(f"TRANS EXCLUDES for {t.address}: {unparsed}")
             unevaluated_transitive_excludes.append(unparsed)
 
     transitive_exclude_addresses = []
@@ -1707,16 +1707,24 @@ async def resolve_unparsed_address_inputs(
         return Addresses(valid_addresses)
 
     addresses = await MultiGet(Get(Address, AddressInput, ai) for ai in address_inputs)
+    if request.parameters:
+        addresses = [addr.parametrize(dict(request.parameters)) for addr in addresses]
+    <http://logger.info|logger.info>(f"ADDRESSES: {addresses}")
     # Validate that the addresses exist. We do this eagerly here because
     # `Addresses -> UnexpandedTargets` does not preserve the `description_of_origin`, so it would
     # be too late, per <https://github.com/pantsbuild/pants/issues/15858>.
-    await MultiGet(
-        Get(
-            WrappedTarget,
-            WrappedTargetRequest(addr, description_of_origin=request.description_of_origin),
+    try:
+        await MultiGet(
+            Get(
+                WrappedTarget,
+                WrappedTargetRequest(addr, description_of_origin=request.description_of_origin),
+            )
+            for addr in addresses
         )
-        for addr in addresses
-    )
+    except ResolveError as e:
+        logger.error(f"RESOLVE ERROR: {e}")
+        raise
+
     return Addresses(addresses)
👀 1
🙇 1
a
I produced a solution but it's very hacky: https://github.com/pasqualesalza/pants/blob/7db119ace7583a42cffb454edd98bcdd857c9d45/src/python/pants/engine/internals/graph.py#L838 It seems to work now. I need to test this with my company's repo but somehow I cannot make it work by using
PANT_SOURCE
, it conflicts with some plugins we created. I wonder, would it be possible to replace that rule with a plugin? I know it's a core rule, but maybe it's possible to replace it in its union_membership?
@curved-television-6568 your solution seems to work also in my huge monorepo! For the moment, I will keep it to continue with my kind of poc...
👍 1
Found a first problem, it will parametrize also fields like:
complete_platforms
c
yea, that was kind of expected
[...] we can't always assume that the parameters for the target applies also to its dependencies [...]
a
Do you have in mind a quick hack I could apply here?
It would sufficient for me, I believe, to recognize the field
dependencies
only
c
this is during address resolution, so there's no notion of fields here, per-se, right?
It's more about which field is being parametrized, perhaps. If you want this to apply for the parametrized
resolve
, but not anything else..?
a
The problem is that it correcly behaves with the interested fields (which would be
dependencies
here) except for transitive excludes.
c
yea, I don't know how this works by heart, I dive in and read/learn as I go. So have no quick-hack suggestions to offer of the top of my head unfortunately 😉
a
I will report on the issue I created when I'll find time. Thanks!
👍 1
c
you're welcome 🙂
a
I might have a question actually
With your solution, hoping to understand your solution better. Did you basically bring forward the parameters for all the addresses?
Because now, if the address will arrive with those parameters, it means that I could avoid applying this:
Copy code
if request.parameters:
        addresses = tuple(addr.parametrize(dict(request.parameters)) for addr in addresses)
But instead do this only where I need, which would be:
transitive_targets(
c
yea, that might do it.
a
I'll try then