fix: make bash completion script work without bash-completion pkg#3801
Merged
frostming merged 1 commit intoJun 3, 2026
Merged
Conversation
The generated bash completion script for pdm calls two helpers from the `bash-completion` package (`_get_comp_words_by_ref` and `__ltrim_colon_completions`). When those helpers are not loaded — e.g. Git Bash on Windows or a minimal Linux container — bash prints `command not found` for each missing helper in the middle of the candidate list every time the user presses Tab. Define small fallback implementations at the top of the script, guarded with `declare -F` so the real helpers from `bash-completion` take precedence when present. The fallbacks intentionally cover only what this script needs: pdm subcommands and option names contain no word-break characters, so `_get_comp_words_by_ref -n :` reduces to "read the current word and $COMP_WORDS" and `__ltrim_colon_completions` becomes a no-op. A regression test sources the script in a clean bash subprocess with the helpers explicitly cleared, invokes the completion function for `pdm <TAB>`, and asserts no `command not found` reaches stderr while the expected subcommand candidates still appear on stdout. Fixes pdm-project#3793
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3801 +/- ##
=======================================
Coverage 86.29% 86.29%
=======================================
Files 118 118
Lines 12536 12536
Branches 2093 2093
=======================================
Hits 10818 10818
Misses 1147 1147
Partials 571 571
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Checklist
news/describing what is new.Describe what you have changed in this PR.
Fixes #3793.
The bug
pdm completion bash's output assumes thebash-completionpackage is loaded in the user's shell. It calls two helpers from that package —_get_comp_words_by_refand__ltrim_colon_completions— without checking whether they exist. When they don't (Git Bash on Windows is the common case, but it also affects minimal Linux containers withoutbash-completioninstalled), bash printsin the middle of every Tab-completion the user triggers, exactly as reported in #3793.
The fix
Define small fallback implementations of both helpers at the top of
pdm.bash, guarded withdeclare -F …so the real implementations frombash-completiontake precedence whenever they're available.The fallbacks intentionally cover only what the rest of the script needs:
_get_comp_words_by_refaccepts the same option shape (-n <chars>,-c,-w, etc.) without honoring it, then populatescur/prev/words/cwordstraight from$COMP_WORDS. pdm subcommand and option names contain no word-break characters, so this output matches the real helper for every invocation in this script.__ltrim_colon_completionsbecomes a no-op for the same reason — there are no colons in pdm command/option names to trim.This keeps the patch small (~35 lines of bash) and avoids any new runtime dependency. The bash syntax was checked with
bash -nand the file behaves the same as before whenbash-completionis loaded.Tests
Added
test_completion_bash_runs_without_bash_completion_pkgintests/cli/test_completion.py. It:pdm.bashin a freshbashsubprocess with_get_comp_words_by_refand__ltrim_colon_completionsexplicitly cleared (so the test is deterministic even on hosts that already havebash-completioninstalled).pdm <TAB>.command not foundreaches stderr and that the expected subcommand candidates (add,install,venv) still appear on stdout.Verified that the test fails on
main(it reproduces bothcommand not founderrors) and passes with this change. The test is skipped on Windows and whenbashis not on$PATH.Full
tests/cli/test_completion.pysuite: 9 passed locally on macOS / Python 3.13.Notes
The file header still says
# Generated by pycomplete 0.4.0.pycompleteitself hasn't seen activity since 2023 and the dev-dep is pinned to~=0.3, so the bash template upstream wouldn't be regenerated through it on the next release. Patching the checked-in file directly is the lowest-risk fix; the same fallback pattern can be lifted intopycomplete/templates/bash.tpllater if a regeneration is ever done.