argcomplete
argcomplete copied to clipboard
zsh filename completion when using "python foo.py" rather than "./foo.py"
I ran into one more issue with the FilesCompleter
, this one zsh-specific:
To reproduce
Test environment:
- Ubuntu 24.04
- Python 3.12.3
- argcomplete 3.1.4-1ubuntu0.1 (this is 3.1.4 with a patch back-ported from 3.3.0 to make it compatible with Python 12.3)
- zsh 5.9
I tested this with the following file foo.py
#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK
import argcomplete, argparse
parser = argparse.ArgumentParser()
arg = parser.add_argument("file")
arg.completer = argcomplete.completers.FilesCompleter()
argcomplete.autocomplete(parser)
./foo.py /e<TAB> # completes to /etc as expected
python ./foo.py /e<TAB> # completes to /etc as expected
python foo.py /e<TAB> # deletes /e instead
Likely Cause
It looks like the root cause for this is in line 154, where [[ "$executable" == python* ]]
checks if the executable is python or the script.
In this context, $executable
was set earlier (line 148) as executable="${words[1]}"
. By this time zsh probably already did some preprocessing because words
is ( foo.py /e)
, not (python foo.py /e)
. This then means that the test fails and no completions are generated there. The elif
case in line 172 also fails because __python_argcomplete_which "$executable"
executes whence -p "foo.py"
which fails because the current working directory is not on the PATH. This also explains why python ./foo.py /e<TAB>
works while python foo.py /e<TAB>
doesn't.