cli: misleading error message when mistyping deploy module
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
-vvand--debug.
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 🙏
Switched to using the user input value only (since we only add one more option ever): https://github.com/pyinfra-dev/pyinfra/commit/1ef3741359adf79d990d06adf7e7f31d25243eb5