Skip to content

Don't fail with error when bash is not found or too old #2574

@superatomic

Description

@superatomic

As discussed in #2152 and #2200, click does not support bash shell autocompletion for bash versions older than version 4.4. I understand this and the rational behind this decision, and I am not requesting that this should be changed. However, the way that click makes developers aware of this version limitation has caused an issue with the ability for autocompletion generation to be scripted.

I have developed a CLI tool using click and I have tried to package it for the Homebrew package manager. As a part of the installation script, autocompletion scripts for bash, zsh, and fish must be generated at installation time. Homebrew isolates builds by removing /usr/local/bin and all user PATHs that are not essential for the build. This means that a newer version of bash (>4.4) will not be present at build time, even if it is present on the system, which causes click to fail to generate bash autocompletion, even if a user has a newer version of bash installed on their system:

Traceback (most recent call last):
  File "/Users/Olivia/Code/tldr-man/.venv/bin/tldr", line 6, in <module>
    sys.exit(cli())
  File "/Users/Olivia/Code/tldr-man/.venv/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/Users/Olivia/Code/tldr-man/.venv/lib/python3.10/site-packages/click/core.py", line 1050, in main
    self._main_shell_completion(extra, prog_name, complete_var)
  File "/Users/Olivia/Code/tldr-man/.venv/lib/python3.10/site-packages/click/core.py", line 1125, in _main_shell_completion
    rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction)
  File "/Users/Olivia/Code/tldr-man/.venv/lib/python3.10/site-packages/click/shell_completion.py", line 45, in shell_complete
    echo(comp.source())
  File "/Users/Olivia/Code/tldr-man/.venv/lib/python3.10/site-packages/click/shell_completion.py", line 326, in source
    self._check_version()
  File "/Users/Olivia/Code/tldr-man/.venv/lib/python3.10/site-packages/click/shell_completion.py", line 314, in _check_version
    raise RuntimeError(
RuntimeError: Shell completion is not supported for Bash versions older than 4.4.

This error is caused by the following function, which will make bash autocompletion simply fail if it detects that an incompatible version is being used:

def _check_version(self) -> None:
import subprocess
output = subprocess.run(
["bash", "-c", 'echo "${BASH_VERSION}"'], stdout=subprocess.PIPE
)
match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode())
if match is not None:
major, minor = match.groups()
if major < "4" or major == "4" and minor < "4":
raise RuntimeError(
_(
"Shell completion is not supported for Bash"
" versions older than 4.4."
)
)
else:
raise RuntimeError(
_("Couldn't detect Bash version, shell completion is not supported.")
)

It makes sense for bash autocompletion generation to always succeed, like it does for both zsh and fish (zsh and fish autocompletion generation will succeed no matter what, even if neither shell is present on the system). While it is important to notify the user if they are using a version of bash that is too old to be supported, it is a bug for this to cause autocompletion generation to fail entirely. I propose for these error messages to be changed into warning messages that are still displayed, but do not prevent the generation from succeeding.

I am willing to submit a pull request myself with the proposed changes if these changes are wanted.

Environment:

  • Python version: 3.10.12
  • Click version: 8.1.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions