click icon indicating copy to clipboard operation
click copied to clipboard

Shell completion doesn't work on scripts with a dot in name

Open ziima opened this issue 4 years ago • 5 comments

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

ziima avatar Jan 04 '22 14:01 ziima

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.

davidism avatar May 03 '22 17:05 davidism

I'll be working on this

nicksspirit avatar May 03 '22 17:05 nicksspirit

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

nicksspirit avatar May 03 '22 18:05 nicksspirit

@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:

ziima avatar May 09 '22 17:05 ziima

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.

davidism avatar May 09 '22 17:05 davidism