cleo
cleo copied to clipboard
The "call" and "call_silent" methods are not working as expected
I'm using this sample app.py:
from cleo.commands.command import Command
from cleo.application import Application
from cleo.helpers import argument
class FooCommand(Command):
name = "foo"
arguments = [argument("baz", "The baz argument.")]
def handle(self):
baz = self.argument("baz")
self.line(baz)
class BarCommand(Command):
name = "bar"
def handle(self):
self.call("foo", "baz")
application = Application()
application.add(FooCommand())
application.add(BarCommand())
if __name__ == "__main__":
application.run()
When I'm calling the foo command itself, it works:
$ python app.py foo baz
baz
But when I'm calling the bar command, I'm getting this:
$ python app.py bar
Not enough arguments (missing: "baz")
If I replace self.call by self.call_silent that's the error:
$ python app.py bar
AttributeError
'builtin_function_or_method' object has no attribute 'bind'
at ~/Library/Caches/pypoetry/virtualenvs/app-wSCSi1z6-py3.9/lib/python3.9/site-packages/cleo/commands/base_command.py:103 in run
99│ def run(self, io: IO) -> int:
100│ self.merge_application_definition()
101│
102│ try:
→ 103│ io.input.bind(self.definition)
104│ except CleoException:
105│ if not self._ignore_validation_errors:
106│ raise
107│
Faced the same issue today. Found out that in call() cleo parses the arguments differently, e.g.
# trying to call command "x" with a required argument "value" as "100"
return_code = self.call("x", "100")
leads to the internal representation as
self._arguments: {'command': '100'} # not `x`!
though, when I call it from the terminal, the representation is:
# ./app.py x 100
self._arguments: {'command': 'x', 'value': '100'}
Eventually, I made it work with the following hack:
return_code = self.call("x", "x 100")
# inner:
self._arguments: {'command': 'x', 'value': '100'}
So, apparently the first word of the arguments is meaningless when calling a command.
return_code = self.call("x", "<anything> 100")
# inner:
self._arguments: {'command': '<anything>', 'value': '100'}