Hi, with a custom target, how do I add some value ...
# general
b
Hi, with a custom target, how do I add some value of the payload to the dependencies ? I'm trying this :
Copy code
python
class MyTarget(JvmTarget):
    
    def __init__(self,
                 payload=None,
                 spec=None,
                 **kwargs):
        payload = payload or Payload()
        payload.add_fields({
            'spec': PrimitiveField(spec),
            })

        if spec:
            self.inject_dependency(Address.parse(spec))

        super(ControllersLibrary, self).__init__(payload=payload,
                                                 **kwargs)
but I get :
Copy code
Failed to instantiate Target with type <class 'MyTarget'>: 'MyTarget' object has no attribute '_build_graph'
a
i believe you may need to call the super constructor first
b
ok than is on my lack of experience in python. I thought the call to super needed to be the last thing facepalm . However it still do not work. I get something like
Copy code
Exception message: Invalid target BuildFileAddress(my_target/BUILD, the_target): Failed to instantiate Target with type <class 'MyTarget'>: Cannot inject dependency from BuildFileAddress(my_target/BUILD, the_target) on the-spec:the-spec because the dependent is not in the BuildGraph.
All usage I see from
inject_dependency
is within a task rather than a target. Here should I just add the element to the
dependencies
list before passing it to the super constructor ?
a
if you have a
spec
arg, is there a reason you can't just add that spec to the
dependencies
when making the target in a BUILD file? what is the spec for?
b
MyTarget is a target that generate some code based on the spec during the gen goal and then compiles this generated code during the compile phase
I realize writing this the question is then why do I need it the dependencies
I'm checking it because when I wrote it, I know I needed it
ok, seems the only reason I put it separatly is that because it is a mandatory special kind of dependency and I wanted to highlight it in the BUILD file
kind of "user experience" for my colleagues writing the BUILD, and to find it more easily when reading it afterwards
a
oh, ok. then i think what you mentioned actually makes sense (adding that
spec
argument to the dependencies). i think you won't need to necessarily change any payload fields here then, and you could just add an entry to
dependencies
before calling the super constructor.
b
so I naivelly tried this :
Copy code
ds = kwargs.pop('dependencies', [])
ds.append(spec)
kwargs.update({'dependencies': ds})
but it bakfired heavily. Do you know how I can add an entry to
dependencies
a
backfired how? it may be that the
dependencies
arg is a list of a different type than the
spec
parameter (pants might be doing some magic, not sure)
b
I had another topic to close yesterday so I'm just working on this problem again. It "backfired" in the sens that target does not have a 'dependencies' field in its args:
Copy code
Exception message: Invalid target mytarget: MyTarget received unknown arguments: 
  dependencies = ['the_spec']
In the Target class a comment on the constructor says
Copy code
# NB: dependencies are in the pydoc above as a BUILD dictionary hack only; implementation hides
    # the dependencies via TargetAddressable.
But I have some pain finding out how TargetAddressable comes in play during the target building
Seems
inject_dependency
is a better trail however as explained earlier, when using it in the target constructor, I run into a
Invalid target  …  because the dependent is not in the BuildGraph.
. Looking at the usage of
inject_dependency
it seems used in the task rather than the targets, however using it in the
execute
seems too late because my real dependency is not
SpecTarget
but a
SyntheticSpecTarget
created by another task previously run …
@enough-analyst-54434 ?
e
OK - give me a minute to page this all back in...
b
yeah of course, thank you very much !
e
Injection is the right general concept but wrong tool. Only (v1) Tasks inject, Targets themselves use this: https://github.com/twitter/pants/blob/abc966fe12aa3ab545beb45600aeb788d8fadc0a/src/python/pants/build_graph/target.py#L628
b
\o/
thank you very much !!
e
SOrry for the twitter fork links 😕
You're welcome
b
no problem !