How would one go about setting up union rules for ...
# general
r
How would one go about setting up union rules for return types? Say I have a call for `Get(B, A)`where
B
is a
union
with a member type
C
- how can I use a rule that goes
A -> C
for this get?
Basically, how can I tell pants that the rule which returns a subclass of B is acceptable for
Get(B, A)
c
By registering the subclass using a
UnionRule
as described here: https://www.pantsbuild.org/docs/rules-api-unions#how-to-create-a-new-union
Granted, those docs are rather terse, so feel free to ask for clarifications on those 😉
r
The impression the docs give is the union rule is for input types, not output. I also have that but the rule graph error is
No installed rules return the type B
where B is the union base.
c
I think the docs are lacking in the example, a rule that uses that union along with a rule that provides a truck instance.
r
I changed the return type of the rule to the base class and went from 2 to 61 rule graph errors 😬
c
Ah, you’re right the unions are for inputs.
What we do for having dynamic return types is to wrap them:
Copy code
@dataclass
class WrappedVehicle:
  impl: Vehicle
Copy code
@rule
def create_truck() -> WrappedVehicle:
  return WrappedVehicle(Truck())
🙏 1
r
Okay now I'm getting
No installed rules return the type
for a type that is provided by the caller in every instance. 🤔
ooh, one of the parameters is mutable, wonder if that's the issue
c
that feels unlikely to affect the graph..
you use unions here, right?
r
Oh I should've been more clear, it's a different type than the one from before. This one isn't a union type.
c
do you have that single rule graph error, or does it cascade into hundreds of (similar) errors?
r
It's cascading but only for rules in my plugin it seems
c
ah ,yea but still.. there’s some trickery with unions and environments.. do you declare your union with:
Copy code
@union(in_scope_types=[EnvironmentName])
?
r
Well not entirely within my plugin actually
No source of dependency Get(DigestContents, [Digest])
😅
c
try add the above to your union decorator.. 😉
r
For my own knowledge, what does that do?
c
Copy code
from pants.engine.environment import EnvironmentName
btw.. if you didn’t have it.
that allows the current environment to be used across union calls, which are otherwise a barrier filtering it out, so any rule that needs the
Environment
as input you’d have to provide it
this is a huge gotcha, that’s not easy to deduce from the errors you get when it hits you
a sign that is it is that it usually generates rule graph errors in the hundreds (even seen thousands of errors from this issue alone)
depends a bit on which part of the graph you hit from your union impl rule.
r
So that didn't solve the issue, but the rule that's throwing this error requests a
UnionMembership
parameter even though the input type isn't a union class or member. Could that be the issue?
c
no, the
UnionMembership
parameter is provided by the engine and is always available.
and doesn’t care about what other parameters or return type you have
what may help is run with
-ldebug
in which case you should get a
.dot
graph in the logs you can render and make it easier to read the graph and spot the root issue.
r
Where do logs get dumped again?
c
this would be just console logs..
r
ah wait, found them in
.pants.d
c
oh, it might be you need
-ltrace
..
haven’t used it for quite some time..
r
I'm not even seeing my plugin in the rule graph, probably because it's failing to load? I do see it listed in
graph.001
but not in
rule_graph
This probably isn't the issue but I do call a big
MultiGet
in this code but I put all of the
Get
objects into a dict and pass
gets.values()
to the multiget. Could that be screwing with the ast parser?
c
no, that should be fine. It’ll pick up the created `Get`s as long as it’s done in the rule itself, or from a called method that’s not too buried in a complex expression.
f
FWIW if you are new to plugins development, you may benefit from going through the tutorials, see https://www.pantsbuild.org/docs/create-a-new-goal
https://www.pantsbuild.org/docs/create-a-new-goal#writing-a-rule provides an explanation over the logic of how rules are written in addition to what is already present in the docs; perhaps another wording may make it easier to understand it better
c
there’s some introspection in
pants help
that may be useful to see what’s loaded and not. try
pants YourType --help-advanced
see what turns up 😉
r
Ahh, think I got the error when I turned trace level logging on.
Yep, I forgot to switch out a call for the wrapper type 🫣
👍 1
c
great find. always tricky to wade through rule graph errors.