Would it ever be possible/make sense for a `Union`...
# plugins
b
Would it ever be possible/make sense for a
Union
to work as a return type? E.g.
await Get(Foo, ...)
gives me all rules registered returning a type that has an associated
UnionRule(Foo, ...
)?
c
Reflection would be useful for generating rule (currently my Metalint experiment needs to cache which rules it has generated). But I think this would be runtime-only, because it's a Get? Which is too late for registering new rules? So I'm not sure what you could actually do with these in userland.
b
My idea is to use this for
lint
which also runs formatters and fixers. Instead of 6 Gets, if I used inheritance I think I'd be able to use only 2 Gets (target tools and targetless tools)
Oh wait...
Copy code
@rule
def downgrade(req: Sub) -> Base:
    return req
c
I think c++ calls that an upcast
b
yeah. Type-erasure ftw
c
This might lead to ambiguous paths in the case of diamond inheritance, or multiple layers of inheritance. Eg
A > B > C
, C might have an ambiguous path to A with routes
C=>A
and
C=>B=>A
b
1. Unions dont actually take into account inheritance 2. The rule graph doesn't allow ambiguity (I think) 3. Python doesn't have this problem because it enforces a consistent MRO
w
yea. here is some discussion of one position where we could potentially remove the restriction: https://github.com/pantsbuild/pants/issues/11354
b
Seems the technical half is just registering these "type-erasure" rules? The scarier side is the "what does this mean" side
Ad those rules could be generated using
__subclasses__()
đŸ¤”
I think this hits on my question of union inheritance too. Which I'm about to re-pose as I found an interesting idea to help reduce boilerplate
w
I think that your original question is one of the use cases covered in the ticket I linked: it's just a question of whether you want to bound the subtypes of the declared type to only being union members, or actually using inheritance.
b
Why don't we require inheritance for union members today?
w
the motivation was to allow a plugin to declare that an existing type was in a `@union`… just a hypothetical though.
my feeling is that before making changes in this area, getting a handle on https://github.com/pantsbuild/pants/issues/12934 would be great… basically, what is the API at a callsite involving a
@union
? what parameters are available?
and then, relatedly, the idea of resolving
@rule_helper
methods on `@union`s
but yea, i think that
@union
return types would be fairly low risk.
b
In this case, the union member set is bounded (only need 2 boilerplate rules) so I'm prone to punt as to not implement something that isn't needed and give us a headache later
w
yea