Skip to content

Danielohayon/py-args-autocomplete

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

py-args-autocomplete — It Just Works

License: MIT

Why?

Ever found yourself typing python script.py --output and freezing... "Was it --output_path or --output_base_path? Or maybe just --output?" 😅

We've all been there: hastily hitting Ctrl+C, running python script.py --help, only to realize your carefully crafted command is now lost to the bash history void. And of course, the moment you see the help output, you remember you also needed to set --num-workers.

py-args-autocomplete gives you Tab-completion for the arguments of any Python CLI — with zero configuration and no changes to the target script. Unlike argcomplete (which needs a marker in every script) or click's completion (which only works for click apps), it derives completions from the one interface every CLI already has: its --help output.

How it works

A ~40-line shell stub asks a small Python engine for candidates on Tab. The engine resolves what you're running (a python script.py, a python -m pkg, or an installed entry point like vllm), runs its --help once, parses it into a completion spec, and caches the spec on disk. Every Tab after that is a ~45 ms cache hit — even for scripts that take seconds to import.

$ python train.py --[Tab]
--batch-size  --epochs  --learning-rate  --model  --num-workers  --optimizer

$ python train.py --optimizer [Tab]
adam  adamw  sgd

$ python train.py --optimizer adam --[Tab]        # used args are filtered out
--batch-size  --epochs  --learning-rate  --model  --num-workers

✨ Features

  • Zero configuration — works with argparse, click, typer, docopt, fire... anything with --help.
  • Fast — on-disk spec cache keyed by script mtime; warm Tab ≈ 45 ms. Scripts whose --help hangs or fails are negative-cached so Tab never hangs twice.
  • venv-correct with no hooks — the target always runs on the python from your current PATH; activate a venv and completions reflect it. The engine itself stays pinned to its own interpreter.
  • bash and zsh — native integration for both; on zsh you also get per-option descriptions pulled from the help text.
  • Entry points too — on bash ≥ 4.1 and zsh, any command with a python shebang (e.g. vllm, lm_eval, anything pip installs into your venv) is detected and completed automatically on first Tab. No registration step.
  • Choice values--mode {fast,slow} and click's [red|green|blue] complete their values, including after --mode=.
  • Alias-aware filtering — using -c hides --config; -h/--help is never suggested.
  • Safe by default — a script is only executed for --help if it textually looks like a CLI (imports argparse/click/...); execution is sandboxed with a 3 s timeout, closed stdin, and a process-group kill.

📥 Installation

pipx install py-args-autocomplete        # or: pip install --user py-args-autocomplete

Then add one line to your shell config:

# ~/.bashrc
eval "$(py-args-autocomplete init bash)"

# ~/.zshrc  (after compinit / after oh-my-zsh loads)
eval "$(py-args-autocomplete init zsh)"

Reload your shell, and Tab away.

Upgrading from v1? Your old source /path/to/repo/src/python_argparse_complete.sh line keeps working — it now delegates to the engine above (install it first). detect_venv_commands and friends are no-ops: v2 detects venv CLIs automatically. The last pure-bash release is preserved at the v1-legacy tag.

🛠 Usage notes

Environment variable Effect
PYAC_TIMEOUT Seconds allowed for a --help run on first Tab (default 3.0)
PYAC_EXEC auto (default): run --help only on CLI-looking scripts; always; never
PYAC_EXCLUDE Space-separated commands the dynamic dispatcher must leave alone
PYAC_CACHE 0 disables the spec cache
PYAC_CACHE_DIR Cache location (default ~/.cache/py-args-autocomplete)
PYAC_DEBUG 1 lets engine stderr through to the terminal

Handy commands (also available as the shorter pyac alias):

py-args-autocomplete doctor                          # check your setup
py-args-autocomplete spec -- python train.py         # show the parsed spec as JSON
py-args-autocomplete cache list                      # what's cached, with status & age
py-args-autocomplete cache refresh -- python train.py  # force re-parse one target
py-args-autocomplete cache clear

🔍 Troubleshooting

  • Nothing completes: run py-args-autocomplete doctor. On zsh, the eval line must come after compinit (oh-my-zsh runs it for you — put the eval after the framework loads).
  • A script never completes: check python script.py --help actually prints a help text; if your script's parser lives in an imported module, set PYAC_EXEC=always.
  • Stale suggestions after editing a script: the cache invalidates on mtime change automatically; cache refresh forces it.
  • First Tab on a heavy script is slow: that one run is the --help cost (bounded by PYAC_TIMEOUT); afterwards it's cached. A timeout is remembered for 10 minutes, so Tab won't re-hang.

🧪 Development

python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/pytest                  # parser goldens, completer, protocol, real-shell pexpect tests
.venv/bin/python tests/bench/bench_latency.py

The parser is developed against a golden corpus (tests/corpus/<case>/help.txtspec.json). After an intentional parser change, run pytest --update-goldens and review the diffs. The v1 behavioral suites live on in tests/cases/*/tests.txt and run through the new engine.

🤝 Contributing

  1. Check the project page for open features or suggest your own.
  2. Fork, branch, add tests (corpus cases make great PRs), and run pytest before submitting.

📄 License

MIT.

📫 Contact

About

Automatic command-line argument autocompletion for Python scripts—no code changes or dependencies required.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors