Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The "call" and "call_silent" methods are not working as expected #130

Open
ianrodrigues opened this issue Jan 28, 2022 · 1 comment
Open
Milestone

Comments

@ianrodrigues
Copy link

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│
@qezz
Copy link

qezz commented Jan 30, 2022

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'}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants