Shell completion doesn't work on scripts with a dot in name
I found out, that a shell completion doesn't work on scripts with a dot in their name, mainly the scripts themselves (without an entry point linked) or entry points with a dot in their name (less common). The main problem is that the dot is copied into the name of the completion variable.
MWE:
Let's have a script /tmp/example.py
import click
@click.command()
def main():
pass
if __name__ == '__main__':
main()
Completion on this script doesn't do anything using any of reasonable variable names:
_EXAMPLE_COMPLETE=bash_source python3 /tmp/example.py
_EXAMPLEPY_COMPLETE=bash_source python3 /tmp/example.py
_EXAMPLE_PY_COMPLETE=bash_source python3 /tmp/example.py
I found out, click requires the variable _EXAMPLE.PY_COMPLETE to be set, which is not possible (at least) in bash.
It would help if the dot was replaced by an underscore, the same way a dash is handled.
Environment:
- Python version: 3.9.9
- Click version: 8.0.3
Completion in general will not work with filenames (./example.py) or modules (python -m example), I don't believe that's something Click can control.
While I'd discorage anyone from making an entry point script with a dot in the name (example.hello), there shouldn't be anything technically wrong with that, so it makes sense to support that.
The solution might be to normalize dots the same way we normalize dashes, by replacing them with underscores.
I'll be working on this
Hey @ziima,
This PR #2275 should fix the issue you raised. It is important you setup an entry point in your setup.py or equivalent with the console script that has the dot in the name. Given your /tmp/example.py an example setup.py should look like:
from setuptools import setup
setup(
name='issue2166', # Your package name
version='0.1.0',
py_modules=['example'], # your example.py module
entry_points={
'console_scripts': [
'example.hello = example:main',
],
},
)
See click's documentation on setup tools
@OdinTech3 Nice, I looking forward for the change.
I have the entry_points set up, but they're hard to use in development or ad hoc scripts :shrug:
There shouldn't be anything different between dev and prod regarding entry points. pip install -e . will set up any defined entry points just as pip install . would. To be clear, the PR does not make it possible to complete with ./myscript.py or python -m myscript, that's an inability of the shell, not of Click. The only thing it changes is allow a dot in the entry point name.