pyinfra icon indicating copy to clipboard operation
pyinfra copied to clipboard

cli: misleading error message when mistyping deploy module

Open karlicoss opened this issue 1 year ago • 1 comments

Describe the bug

I have the following package structure for my deploys:

$ cat mysetup/mymodule.py 
from pyinfra.api import deploy

from pyinfra.operations import files


@deploy("mydeploy")
def mydeploy():
    files.file('/tmp/pyinfra_test')

It works great when I invoke it via pyinfra cli!

$ pyinfra @local mysetup.mymodule:mydeploy 
...
--> Detected changes:
    Operation                                   Change       Conditional Change   
    mydeploy | files.file (/tmp/pyinfra_test)   1 (@local)   -                    

Misleading error message

The issue is when you make a typo somewhere, then the error message is kind of misleading:

  • typo in the deploy function name:
$ pyinfra @local mysetup.mymodule:mydeploy_typo  --debug
--> pyinfra error: No such attribute in module pyinfra.operations.mysetup.mymodule: mydeploy_typo
  • typo in the deploy module name:
$ pyinfra @local mysetup.mymodule_typo:mydeploy  --debug
--> pyinfra error: No such module: pyinfra.operations.mysetup.mymodule_typo
  • forgotten deploy function name (not sure it's allowed though, but still, the error is kinda confusing):
$ pyinfra @local mysetup.mymodule  --debug
--> pyinfra error: No such attribute in module pyinfra.operations.mysetup: mymodule

Seems like everything you pass gets prefixed with pyinfra.operations, creating a false impression pyinfra cli only supports builtin operations.

I debugged a bit and seems like it happens because in try_import_module_attribute. prefix is equal to pyinfra.operations, so it always gets appended to possible_modules. Later, the CliError only includes the last of possible_modules, so whatever you passed to pyinfra is going to get prefixed with pyinfra.operations.

Expected behavior

Perhaps the error needs to include all candidates so it's a bit more obvious what's going on? Happy to do a PR if it's welcome!

Meta

    System: Linux
      Platform: Linux-6.8.0-38-generic-x86_64-with-glibc2.39
      Release: 6.8.0-38-generic
      Machine: x86_64
    pyinfra: v3.0.2
    Executable: /home/karlicos/.local/bin/pyinfra
    Python: 3.12.3 (CPython, GCC 13.2.0)
  • Include output of pyinfra --support.
  • How was pyinfra installed (source/pip)?
  • Include pyinfra-debug.log (if one was created)
  • Consider including output with -vv and --debug.

karlicoss avatar Jul 30 '24 22:07 karlicoss

Perhaps the error needs to include all candidates so it's a bit more obvious what's going on? Happy to do a PR if it's welcome!

Definitely this! PR would be amazing 🙏

Fizzadar avatar Aug 04 '24 13:08 Fizzadar

Switched to using the user input value only (since we only add one more option ever): https://github.com/pyinfra-dev/pyinfra/commit/1ef3741359adf79d990d06adf7e7f31d25243eb5

Fizzadar avatar Sep 25 '24 21:09 Fizzadar