argcomplete-3.6.2/Authors.rst0000644000000000000000000000004313615410400013120 0ustar00Andrey Kislyuk argcomplete-3.6.2/Changes.rst0000644000000000000000000004144213615410400013053 0ustar00Changes for v3.6.2 (2025-04-02) =============================== - Revert “zsh: skip repeat Python runs in the same completion run” This reverts a regression introduced in zsh tab completion configurations utilizing multiple matchers. Changes for v3.6.1 (2025-03-22) =============================== - zsh: add global completion system install dir to user fpath if not present - Update shell_integration.py to support spaces in script file path. (#525) - Fix completion when wordbreak is first character (#526) Changes for v3.6.0 (2025-03-05) =============================== - Support namespace package traversal when completing Python entry points - zsh: skip repeat Python runs in the same completion run - Make \_parse_known_args signature more general for future API changes Changes for v3.5.3 (2024-12-31) =============================== - Use interactive shells and bind to make environment variable name completions work in older Bash versions (#506) Changes for v3.5.2 (2024-12-06) =============================== - Fix \_parse_known_args monkeypatching - Note: This fix is required to restore compatibility with Python 3.12.8 and 3.13.1. - CI improvements Changes for v3.5.1 (2024-10-06) =============================== - Restore compatibility with argparse in Python 3.12.7+ (#508) Changes for v3.5.0 (2024-08-06) =============================== - Use project.scripts instead of setuptools scripts (#498) - Test infrastructure improvements Changes for v3.4.0 (2024-06-16) =============================== - No stdin for python calls from bash completion functions (#488) Prevents usage of stdin by (python) executables that are called during completion generation. This prevents the completion locking up the entire shell when the python script is broken i.e. it enters an interactive mode (REPL) instead of generating the completions, as expected. - Localize shell variable REPLY to avoid overwriting users’ value (#489) The variable REPLY is used by default by the ``read`` shell builtin to store the return value, and like all bash/zsh variables, is scoped globally. This change allows this variable to be used for other needs by appropriately scoping its internal use by an argcomplete utility function that uses ``read``. Changes for v3.3.0 (2024-04-14) =============================== - Preserve compatibility with argparse option tuples of length 4. This update is required to use argcomplete on Python 3.11.9+ or 3.12.3+. Changes for v3.2.3 (2024-03-07) =============================== - Allow register-python-argcomplete output to be used as lazy-loaded zsh completion module (#475) - Move debug_stream initialization to helper method to allow fd 9 behavior to be overridden in subclasses (#471) Changes for v3.2.2 (2024-01-23) =============================== Expand tilde in zsh Changes for v3.2.1 (2023-12-10) =============================== - Allow explicit zsh global completion activation (#467) Changes for v3.2.0 (2023-12-09) =============================== - Fix and test global completion in zsh (#463, #466) - Add –yes option to activate-global-python-argcomplete (#461) - Test suite improvements Changes for v3.1.6 (2023-11-12) =============================== - Respect user choice in activate-global-python-argcomplete Changes for v3.1.5 (2023-11-12) =============================== - Escape colon in zsh completions. Fixes #456 Changes for v3.1.4 (2023-11-01) =============================== - Call \_default as a fallback in zsh global completion Changes for v3.1.3 (2023-11-01) =============================== - Use homebrew prefix by default - zsh: Allow to use external script (#453) - Add support for Python 3.12 and drop EOL 3.6 and 3.7 (#449) Changes for v3.1.3 (2023-11-01) =============================== - Use homebrew prefix by default - zsh: Allow to use external script (#453) - Add support for Python 3.12 and drop EOL 3.6 and 3.7 (#449) Changes for v3.1.2 (2023-09-16) =============================== - Ensure Python 3.12+ compatibility in check_console_script (#448) Changes for v3.1.1 (2023-06-11) =============================== - Search through asdf shims - Use \` as escape character in PowerShell (#434) Changes for v3.1.0 (2023-06-10) =============================== - setup.py -> pyproject.toml migration start (#427) - Improve user install logic in activate-global-python-argcomplete (#437) - Ensure Python 3.7 compatibility in check_console_script (#436) - ZSH implementation fixes (#431, #433) - Documentation improvements Changes for v3.0.8 (2023-04-23) =============================== - Test suite shell wrapper: Accept OSError on exit Changes for v3.0.7 (2023-04-23) =============================== - Test suite: Use general regex to cut zsh reset ANSI sequences (#425) Changes for v3.0.6 (2023-04-22) =============================== - Allow importlib-metadata 6.x; skip test failures on Python 3.7 (#420, #424) - Note completers can return iterables of strings, not just lists (#422) - Documentation and test improvements Changes for v3.0.5 (2023-03-25) =============================== - Call \_default as fallback in zsh global completion hook - Begin support for mapping-emitting completers Changes for v3.0.4 (2023-03-21) =============================== - activate-global-python-argcomplete: do not overwrite existing dotfile in user directory - Add NOTICE file - Establish long term name for split_line as argcomplete.lexers.split_line Changes for v3.0.3 (2023-03-20) =============================== - Re-add split_line to API (#419) Changes for v3.0.2 (2023-03-19) =============================== Fix zsh default completion issues Changes for v3.0.1 (2023-03-19) =============================== - Fix zsh autoload issues Changes for v3.0.0 (2023-03-19) =============================== - Fully support zsh. Argcomplete now supports completion descriptions and global completion in zsh. - Clean up top level namespace. - Documentation and test improvements. Changes for v2.1.2 (2023-03-17) =============================== - Test infrastructure improvements - Indicate that there is no support commitment for fish and tcsh shells Changes for v2.1.1 (2023-03-06) =============================== - Documentation and test improvements Changes for v2.1.0 (2023-03-06) =============================== - Remove scripts for contrib-supported shells from global namespace Changes for v2.0.6 (2023-03-06) =============================== - setup.py: exclude test.\* subpackages from find_packages (#406) - Support PowerShell (#405) - CI updates Changes for v2.0.5 (2023-03-04) =============================== - Revert “Support powershell (#392)” Changes for v2.0.4 (2023-03-04) =============================== - Fix interrupted release (v2.0.1) Changes for v2.0.3 (2023-03-04) =============================== - Fix interrupted release (v2.0.1) Changes for v2.0.2 (2023-03-04) =============================== - Fix interrupted release (v2.0.1) Changes for v2.0.1 (2023-03-04) =============================== - Support powershell (#392) - Update importlib-metadata dependency to include versions 5.x (#389) - Test and documentation improvements Changes for v2.0.0 (2022-01-03) =============================== - Truncate input after cursor. Fixes #351 (#352) - Support of path completion in fish #327 (#359) - Drop support for Python 2.7 and 3.5 (#361) - Add support for Python 3.10 (#356) - Test, documentation, and release infrastructure improvements Changes for v1.12.3 (2021-04-19) ================================ - Update importlib-metadata version pin (#345) - Display script debug output in tcsh (#342) - Fish support improvements (#338, #339) - Print ``warn()`` message from beginning of line (#335) - Test infrastructure improvements Changes for v1.12.2 (2020-11-23) ================================ - Update importlib-metadata dependency pin (#332) - Add change log project URL (#312) - Replace Travis CI with GitHub Actions (#323) Changes for v1.12.1 (2020-09-26) ================================ - Update importlib-metadata dependency version range - Bash nounset mode fixes (#313) Changes for v1.11.1 (2020-01-14) ================================ - Add -o bashdefault to register-python-argcomplete’s output command (#284) Changes for v1.11.0 (2019-12-23) ================================ - Use shell builtins where possible (#280) - Switch from pkg_resources to importlib (#283) - Remove .sh extension by bash-completion convention (#281) - Catch exceptions in \_check_module (#269) - Documentation and test improvements Changes for v1.10.3 (2019-11-26) ================================ - Do not suggest options after – (end-of-options delimiter) Changes for v1.10.2 (2019-11-17) ================================ - Include all test directory contents in source distribution Changes for v1.10.1 (2019-11-16) ================================ - Trigger completers on –optional=PARTIAL_VALUE - Complete console scripts installed from wheels (#241) Changes for v1.10.0 (2019-05-12) ================================ - Fish support #68 (#260), thanks to @volkov Changes for v1.9.5 (2019-04-02) =============================== - check_module: Don’t crash, exit with error instead (#261) - Register completion for multiple commands (#246) Changes for v1.9.4 (2018-02-13) =============================== - Use the correct interpreter when checking wrappers (#226) - Provide shellcode as a module function (#237) Changes for v1.9.3 (2017-11-16) =============================== - Fix handling of COMP\_POINT (#236) - Fix crash when writing unicode to debug\_stream in Python 2 (#230) Changes for v1.9.2 (2017-08-23) =============================== - Fix release Changes for v1.9.1 (2017-08-23) =============================== - Fix release Changes for v1.9.0 (2017-08-23) =============================== - Add SuppressCompleter to skip completion for specific arguments while allowing help text (#224) - Redirect all output to debug stream in debug mode (#206) - Complete python -m module (#204) Changes for v1.8.2 (2017-01-26) =============================== - Fix bug introduced in v0.7.1 where completers would not receive the parser keyword argument. - Documentation improvements. Changes for v1.8.1 (2017-01-21) =============================== - Fix completion after tokens with wordbreak chars (#197) Changes for v1.8.0 (2017-01-19) =============================== This release contains work by @evanunderscore with numerous improvements to the handling of special characters in completions. - Simplify nospace handling in global completion (#195) - Specially handle all characters in COMP\_WORDBREAKS (#187) - Use setuptools tests-require directive, fixes #186 - Complete files using the specified interpreter (#192) - Fix completion for scripts run via python (#191) - Clarify argument to register-python-argcomplete (#190) - Fix handling of commas and other special chars (#172); handle more special characters (#189) - Fix handling of special characters in tcsh (#188) - Update my\_shlex to Python 3.6 version (#184) - Fix additional trailing space in exact matches (#183) - Adjust tests to handle development environments (#180) - Fix tcsh tests on OSX (#177); Update bash on OSX (#176); Check output of test setup command (#179) - Optionally disable duplicated flags (#143) - Add default\_completer option to CompletionFinder.\ **call** (#167) - Let bash add or suppress trailing space (#159) Changes for v1.7.0 (2016-11-30) =============================== - Restore parser to its original state to allow reuse after completion (#150). - Expose COMP\_TYPE environment variable (#157). Thanks to Matt Clay (@mattclay). - Test infrastructure and documentation improvements. Changes for v1.6.0 (2016-10-20) =============================== - Add support for tcsh (#155) - Fix handling of unquoted completions containing $ (#154) - Don't insert unnecessary leading quote char in completions (#152) - Fix parser reuse with positional arguments (#149) - Tests: Add simple pexpect tests for bash (#153); Add test case to verify #20 is fixed (#148) - Thanks to @davvid and @evanunderscore for their work on this release. Changes for v1.5.1 (2016-10-11) =============================== - Packaging fix Changes for v1.5.0 (2016-10-11) =============================== - Do not suggest options from mutually exclusive groups (#145). Version 1.4.1 (2016-06-14) ========================== - activate-global-python-argcomplete runs on Homebrew out of the box Version 1.4.0 (2016-06-10) ========================== - Correctly handle suggestions for positionals with variable-length nargs. Thanks to @evanunderscore (#132, #133). Version 1.3.0 (2016-06-01) ========================== - Correctly handle suggestions with custom nargs for optionals. Thanks to @evanunderscore (#131). Version 1.2.0 (2016-05-25) ========================== - Fix propagation of partially parsed subparser namespace into parent parser namespace upon subparser failure due to partial args. This allows completers to access partial parse results for subparser optionals in parsed_args (#114). - The default completer can now be specified when manually instantiating CompletionFinder. Thanks to @avylove (#130). Version 1.1.1 (2016-03-22) ========================== - Use FilesCompleter as default completer fallback (#120). Version 1.1.0 (2016-02-21) ========================== - Recognize subclasses of argparse._SubParsersAction. Thanks to Stephen Koo (#118). - Support parsed_args in custom completers with missing args. Thanks to Dan Kilman (#124). - Non-ASCII support in FilesCompleter. - Automatically enable FilesCompleter for argparse.FileType arguments. Version 1.0.0 (2015-08-22) ========================== - Don't print args with suppressed help by default; add ``argcomplete.autocomplete(print_suppressed=True)`` to control this behavior (#113). Version 0.9.0 (2015-07-03) ========================== - Fix always_complete_options=False support (#115). Version 0.8.9 (2015-06-01) ========================== - Correct doc filename in setup.cfg (fixes bdist_rpm failure, Issue 111). - Make context managers exception-safe. Thanks to Mikołaj Siedlarek (pull request #110). Version 0.8.8 (2015-05-01) ========================== - Build and upload universal wheel packages in release. - Fix issue with non-string choices for arguments. Thanks to @neizod (pull request #107). - Improve non-ascii argparse argument support on Python 2.7. Version 0.8.7 (2015-04-11) ========================== - register-python-argcomplete: add option to avoid default readline completion. Thanks to @drmalex07 (pull request #99). Version 0.8.6 (2015-04-11) ========================== - Expand tilde in script name, allowing argcomplete to work when invoking scripts from one's home directory. Thanks to @VorpalBlade (Issue 104). Version 0.8.5 (2015-04-07) ========================== - Fix issues related to using argcomplete in a REPL environment. - New helper method for custom completion display. - Expand test suite; formatting cleanup. Version 0.8.4 (2014-12-11) ========================== - Fix issue related to using argcomplete in a REPL environment. Thanks to @wapiflapi (pull request #91). Version 0.8.3 (2014-11-09) ========================== - Fix multiple issues related to using argcomplete in a REPL environment. Thanks to @wapiflapi (pull request #90). Version 0.8.2 (2014-11-03) ========================== - Don't strip colon prefix in completion results if COMP_WORDBREAKS does not contain a colon. Thanks to @berezv (pull request #88). Version 0.8.1 (2014-07-02) ========================== - Use complete --nospace to avoid issues with directory completion. Version 0.8.0 (2014-04-07) ========================== - Refactor main body of code into a class to enable subclassing and overriding of functionality (Issue #78). Version 0.7.1 (2014-03-29) ========================== - New keyword option "argcomplete.autocomplete(validator=...)" to supply a custom validator or bypass default validation. Thanks to @thijsdezoete (Issue #77). - Document debug options. Version 0.7.0 (2014-01-19) ========================== - New keyword option "argcomplete.autocomplete(exclude=[...])" to suppress options (Issue #74). - More speedups to code path for global completion hook negative result. Version 0.6.9 (2014-01-19) ========================== - Fix handling of development mode script wrappers. Thanks to @jmlopez-rod and @dcosson (Issue #69). - Speed up code path for global completion hook negative result by loading pkg_resources on demand. Version 0.6.8 (2014-01-18) ========================== - Begin tracking changes in changelog. - Add completion support for PBR installed scripts (PR #71). - Detect easy-install shims with shebang lines that contain Py instead of py (Issue #69). argcomplete-3.6.2/MANIFEST.in0000644000000000000000000000011713615410400012501 0ustar00include argcomplete/bash_completion.d/* include *.rst recursive-include test * argcomplete-3.6.2/Makefile0000644000000000000000000000136513615410400012411 0ustar00SHELL=/bin/bash test_deps: python -m pip install .[test] lint: for dir in $$(dirname */__init__.py); do ruff check $$dir; done for script in scripts/*[^cmd]; do if grep -q python $$script; then ruff check $$script; fi; done mypy --install-types --non-interactive argcomplete test: coverage run --source=argcomplete --omit=argcomplete/packages/_shlex.py ./test/test.py -v init_docs: cd docs; sphinx-quickstart docs: python -m pip install furo sphinx-copybutton sphinxext-opengraph sphinx-build docs docs/html install: clean python -m pip install build python -m build python -m pip install --upgrade $$(echo dist/*.whl)[test] clean: -rm -rf build dist -rm -rf *.egg-info .PHONY: test_deps lint test docs install clean include common.mk argcomplete-3.6.2/SECURITY.md0000644000000000000000000000130113615410400012530 0ustar00# Security Policy ## Reporting a Vulnerability If you believe you have found a security vulnerability in this project, please report it to us by submitting a security advisory at https://github.com/kislyuk/argcomplete/security/advisories. You can expect an initial response within 14 days. ## Supported Versions In general, the maintainers of this project provide security updates only for the most recent published release. If you need support for prior versions, please open an issue and describe your situation. Requests for updates to prior releases will be considered on a case-by-case basis, and will generally be accommodated only for the latest releases in prior major version release series. argcomplete-3.6.2/common.mk0000644000000000000000000000373713615410400012577 0ustar00SHELL=/bin/bash -eo pipefail release-major: $(eval export TAG=$(shell git describe --tags --match 'v*.*.*' | perl -ne '/^v(\d+)\.(\d+)\.(\d+)/; print "v@{[$$1+1]}.0.0"')) $(MAKE) release release-minor: $(eval export TAG=$(shell git describe --tags --match 'v*.*.*' | perl -ne '/^v(\d+)\.(\d+)\.(\d+)/; print "v$$1.@{[$$2+1]}.0"')) $(MAKE) release release-patch: $(eval export TAG=$(shell git describe --tags --match 'v*.*.*' | perl -ne '/^v(\d+)\.(\d+)\.(\d+)/; print "v$$1.$$2.@{[$$3+1]}"')) $(MAKE) release release: @if ! git diff --cached --exit-code; then echo "Commit staged files before proceeding"; exit 1; fi @if [[ -z $$TAG ]]; then echo "Use release-{major,minor,patch}"; exit 1; fi @if ! type -P pandoc; then echo "Please install pandoc"; exit 1; fi @if ! type -P sponge; then echo "Please install moreutils"; exit 1; fi @if ! type -P gh; then echo "Please install gh"; exit 1; fi git pull git clean -x --force argcomplete TAG_MSG=$$(mktemp); \ echo "# Changes for ${TAG} ($$(date +%Y-%m-%d))" > $$TAG_MSG; \ git log --pretty=format:%s $$(git describe --abbrev=0)..HEAD >> $$TAG_MSG; \ $${EDITOR:-emacs} $$TAG_MSG; \ if [[ -f Changes.md ]]; then cat $$TAG_MSG <(echo) Changes.md | sponge Changes.md; git add Changes.md; fi; \ if [[ -f Changes.rst ]]; then cat <(pandoc --from markdown --to rst $$TAG_MSG) <(echo) Changes.rst | sponge Changes.rst; git add Changes.rst; fi; \ git commit -m ${TAG}; \ git tag --annotate --file $$TAG_MSG ${TAG} git push --follow-tags $(MAKE) install gh release create ${TAG} dist/*.whl --notes="$$(git tag --list ${TAG} -n99 | perl -pe 's/^\S+\s*// if $$. == 1' | sed 's/^\s\s\s\s//')" $(MAKE) release-docs release-docs: $(MAKE) docs -git branch -D gh-pages git checkout -B gh-pages-stage touch docs/html/.nojekyll git add --force docs/html git commit -m "Docs for ${TAG}" git push --force origin $$(git subtree split --prefix docs/html --branch gh-pages):refs/heads/gh-pages git checkout - .PHONY: release argcomplete-3.6.2/setup.cfg0000644000000000000000000000020713615410400012564 0ustar00[bdist_rpm] provides=python-argcomplete doc_files = Authors.rst Changes.rst README.rst LICENSE.rst argcomplete-3.6.2/.github/FUNDING.yml0000644000000000000000000000002213615410400014113 0ustar00github: [kislyuk] argcomplete-3.6.2/.github/workflows/ci.yml0000644000000000000000000000264613615410400015467 0ustar00name: Python package on: [push, pull_request] jobs: build: runs-on: ${{matrix.os}} strategy: fail-fast: false matrix: os: [ubuntu-20.04, ubuntu-latest, macos-13, macos-latest] python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: ${{matrix.python-version}} allow-prereleases: true - name: Install CI dependencies run: | [[ $(uname) == Linux ]] && sudo apt-get install --yes rpm tcsh fish zsh [[ $(uname) == Darwin ]] && brew install bash tcsh fish # Some runners have python-argcomplete preinstalled # as a dependency of pipx, which interferes with the tests. [[ $(uname) == Darwin ]] && brew uninstall --ignore-dependencies python-argcomplete || true python -m pip install --quiet --upgrade codecov - run: make install - run: make lint - run: make test - uses: codecov/codecov-action@v5 if: ${{matrix.python-version == '3.12' && matrix.os == 'ubuntu-22.04'}} isort: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - uses: isort/isort-action@v1.1.0 ruff: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/ruff-action@v1 - uses: astral-sh/ruff-action@v1 with: args: "format --check" argcomplete-3.6.2/.github/workflows/release.yml0000644000000000000000000000075213615410400016510 0ustar00name: Publish release to PyPI on: push: tags: - 'v[0-9]+.[0-9]+.[0-9]+' jobs: pypi-publish: name: Build and upload release to PyPI runs-on: ubuntu-latest environment: release permissions: id-token: write steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 - run: pip install build - run: python -m build - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 argcomplete-3.6.2/argcomplete/__init__.py0000644000000000000000000000126513615410400015363 0ustar00# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. # Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. from . import completers from .completers import ChoicesCompleter, DirectoriesCompleter, EnvironCompleter, FilesCompleter, SuppressCompleter from .exceptions import ArgcompleteException from .finders import CompletionFinder, ExclusiveCompletionFinder, safe_actions from .io import debug, mute_stderr, warn from .lexers import split_line from .shell_integration import shellcode autocomplete = CompletionFinder() autocomplete.__doc__ = """ Use this to access argcomplete. See :meth:`argcomplete.CompletionFinder.__call__()`. """ argcomplete-3.6.2/argcomplete/_check_console_script.py0000644000000000000000000000455513615410400020153 0ustar00""" Utility for locating the module (or package's __init__.py) associated with a given console_script name and verifying it contains the PYTHON_ARGCOMPLETE_OK marker. Such scripts are automatically generated and cannot contain the marker themselves, so we defer to the containing module or package. For more information on setuptools console_scripts, see https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation Intended to be invoked by argcomplete's global completion function. """ import os import sys from importlib.metadata import EntryPoint from importlib.metadata import entry_points as importlib_entry_points from typing import Iterable from ._check_module import ArgcompleteMarkerNotFound, find def main(): # Argument is the full path to the console script. script_path = sys.argv[1] # Find the module and function names that correspond to this # assuming it is actually a console script. name = os.path.basename(script_path) entry_points: Iterable[EntryPoint] = importlib_entry_points() # type:ignore # Python 3.12+ returns a tuple of entry point objects # whereas <=3.11 returns a SelectableGroups object if sys.version_info < (3, 12): entry_points = entry_points["console_scripts"] # type:ignore entry_points = [ep for ep in entry_points if ep.name == name and ep.group == "console_scripts"] # type:ignore if not entry_points: raise ArgcompleteMarkerNotFound("no entry point found matching script") entry_point = entry_points[0] module_name, function_name = entry_point.value.split(":", 1) # Check this looks like the script we really expected. with open(script_path) as f: script = f.read() if "from {} import {}".format(module_name, function_name) not in script: raise ArgcompleteMarkerNotFound("does not appear to be a console script") if "sys.exit({}())".format(function_name) not in script: raise ArgcompleteMarkerNotFound("does not appear to be a console script") # Look for the argcomplete marker in the script it imports. with open(find(module_name, return_package=True)) as f: head = f.read(1024) if "PYTHON_ARGCOMPLETE_OK" not in head: raise ArgcompleteMarkerNotFound("marker not found") if __name__ == "__main__": try: main() except ArgcompleteMarkerNotFound as e: sys.exit(str(e)) argcomplete-3.6.2/argcomplete/_check_module.py0000644000000000000000000000420213615410400016377 0ustar00""" Utility for locating a module (or package's __main__.py) with a given name and verifying it contains the PYTHON_ARGCOMPLETE_OK marker. The module name should be specified in a form usable with `python -m`. Intended to be invoked by argcomplete's global completion function. """ import os import sys import tokenize from importlib.util import find_spec class ArgcompleteMarkerNotFound(RuntimeError): pass def find(name, return_package=False): names = name.split(".") # Look for the first importlib ModuleSpec that has `origin` set, indicating it's not a namespace package. for package_name_boundary in range(len(names)): spec = find_spec(".".join(names[: package_name_boundary + 1])) if spec is not None and spec.origin is not None: break if spec is None: raise ArgcompleteMarkerNotFound('no module named "{}"'.format(names[0])) if not spec.has_location: raise ArgcompleteMarkerNotFound("cannot locate file") if spec.submodule_search_locations is None: if len(names) != 1: raise ArgcompleteMarkerNotFound("{} is not a package".format(names[0])) return spec.origin if len(spec.submodule_search_locations) != 1: raise ArgcompleteMarkerNotFound("expecting one search location") path = os.path.join(spec.submodule_search_locations[0], *names[package_name_boundary + 1 :]) if os.path.isdir(path): filename = "__main__.py" if return_package: filename = "__init__.py" return os.path.join(path, filename) else: return path + ".py" def main(): try: name = sys.argv[1] except IndexError: raise ArgcompleteMarkerNotFound("missing argument on the command line") filename = find(name) try: fp = tokenize.open(filename) except OSError: raise ArgcompleteMarkerNotFound("cannot open file") with fp: head = fp.read(1024) if "PYTHON_ARGCOMPLETE_OK" not in head: raise ArgcompleteMarkerNotFound("marker not found") if __name__ == "__main__": try: main() except ArgcompleteMarkerNotFound as e: sys.exit(str(e)) argcomplete-3.6.2/argcomplete/completers.py0000644000000000000000000001106113615410400015774 0ustar00# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. # Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. import argparse import os import subprocess def _call(*args, **kwargs): # TODO: replace "universal_newlines" with "text" once 3.6 support is dropped kwargs["universal_newlines"] = True try: return subprocess.check_output(*args, **kwargs).splitlines() except subprocess.CalledProcessError: return [] class BaseCompleter: """ This is the base class that all argcomplete completers should subclass. """ def __call__( self, *, prefix: str, action: argparse.Action, parser: argparse.ArgumentParser, parsed_args: argparse.Namespace ) -> None: raise NotImplementedError("This method should be implemented by a subclass.") class ChoicesCompleter(BaseCompleter): def __init__(self, choices): self.choices = choices def _convert(self, choice): if not isinstance(choice, str): choice = str(choice) return choice def __call__(self, **kwargs): return (self._convert(c) for c in self.choices) EnvironCompleter = ChoicesCompleter(os.environ) class FilesCompleter(BaseCompleter): """ File completer class, optionally takes a list of allowed extensions """ def __init__(self, allowednames=(), directories=True): # Fix if someone passes in a string instead of a list if isinstance(allowednames, (str, bytes)): allowednames = [allowednames] self.allowednames = [x.lstrip("*").lstrip(".") for x in allowednames] self.directories = directories def __call__(self, prefix, **kwargs): completion = [] if self.allowednames: if self.directories: # Using 'bind' in this and the following commands is a workaround to a bug in bash # that was fixed in bash 5.3 but affects older versions. Environment variables are not treated # correctly in older versions and calling bind makes them available. For details, see # https://savannah.gnu.org/support/index.php?111125 files = _call( ["bash", "-c", "bind; compgen -A directory -- '{p}'".format(p=prefix)], stderr=subprocess.DEVNULL ) completion += [f + "/" for f in files] for x in self.allowednames: completion += _call( ["bash", "-c", "bind; compgen -A file -X '!*.{0}' -- '{p}'".format(x, p=prefix)], stderr=subprocess.DEVNULL, ) else: completion += _call( ["bash", "-c", "bind; compgen -A file -- '{p}'".format(p=prefix)], stderr=subprocess.DEVNULL ) anticomp = _call( ["bash", "-c", "bind; compgen -A directory -- '{p}'".format(p=prefix)], stderr=subprocess.DEVNULL ) completion = list(set(completion) - set(anticomp)) if self.directories: completion += [f + "/" for f in anticomp] return completion class _FilteredFilesCompleter(BaseCompleter): def __init__(self, predicate): """ Create the completer A predicate accepts as its only argument a candidate path and either accepts it or rejects it. """ assert predicate, "Expected a callable predicate" self.predicate = predicate def __call__(self, prefix, **kwargs): """ Provide completions on prefix """ target_dir = os.path.dirname(prefix) try: names = os.listdir(target_dir or ".") except Exception: return # empty iterator incomplete_part = os.path.basename(prefix) # Iterate on target_dir entries and filter on given predicate for name in names: if not name.startswith(incomplete_part): continue candidate = os.path.join(target_dir, name) if not self.predicate(candidate): continue yield candidate + "/" if os.path.isdir(candidate) else candidate class DirectoriesCompleter(_FilteredFilesCompleter): def __init__(self): _FilteredFilesCompleter.__init__(self, predicate=os.path.isdir) class SuppressCompleter(BaseCompleter): """ A completer used to suppress the completion of specific arguments """ def __init__(self): pass def suppress(self): """ Decide if the completion should be suppressed """ return True argcomplete-3.6.2/argcomplete/exceptions.py0000644000000000000000000000016013615410400015776 0ustar00class ArgcompleteException(Exception): "Exception raised when the shell argument completion process fails." argcomplete-3.6.2/argcomplete/finders.py0000644000000000000000000006715113615410400015264 0ustar00# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. Licensed under the terms of the # `Apache License, Version 2.0 `_. Distribution of the LICENSE and NOTICE # files with source copies of this package and derivative works is **REQUIRED** as specified by the Apache License. # See https://github.com/kislyuk/argcomplete for more info. import argparse import os import sys from collections.abc import Mapping from typing import Callable, Dict, List, Optional, Sequence, TextIO, Union from . import io as _io from .completers import BaseCompleter, ChoicesCompleter, FilesCompleter, SuppressCompleter from .io import debug, mute_stderr from .lexers import split_line from .packages._argparse import IntrospectiveArgumentParser, action_is_greedy, action_is_open, action_is_satisfied safe_actions = { argparse._StoreAction, argparse._StoreConstAction, argparse._StoreTrueAction, argparse._StoreFalseAction, argparse._AppendAction, argparse._AppendConstAction, argparse._CountAction, } def default_validator(completion, prefix): return completion.startswith(prefix) class CompletionFinder(object): """ Inherit from this class if you wish to override any of the stages below. Otherwise, use ``argcomplete.autocomplete()`` directly (it's a convenience instance of this class). It has the same signature as :meth:`CompletionFinder.__call__()`. """ def __init__( self, argument_parser=None, always_complete_options=True, exclude=None, validator=None, print_suppressed=False, default_completer=FilesCompleter(), append_space=None, ): self._parser = argument_parser self.always_complete_options = always_complete_options self.exclude = exclude if validator is None: validator = default_validator self.validator = validator self.print_suppressed = print_suppressed self.completing = False self._display_completions: Dict[str, str] = {} self.default_completer = default_completer if append_space is None: append_space = os.environ.get("_ARGCOMPLETE_SUPPRESS_SPACE") != "1" self.append_space = append_space def __call__( self, argument_parser: argparse.ArgumentParser, always_complete_options: Union[bool, str] = True, exit_method: Callable = os._exit, output_stream: Optional[TextIO] = None, exclude: Optional[Sequence[str]] = None, validator: Optional[Callable] = None, print_suppressed: bool = False, append_space: Optional[bool] = None, default_completer: BaseCompleter = FilesCompleter(), ) -> None: """ :param argument_parser: The argument parser to autocomplete on :param always_complete_options: Controls the autocompletion of option strings if an option string opening character (normally ``-``) has not been entered. If ``True`` (default), both short (``-x``) and long (``--x``) option strings will be suggested. If ``False``, no option strings will be suggested. If ``long``, long options and short options with no long variant will be suggested. If ``short``, short options and long options with no short variant will be suggested. :param exit_method: Method used to stop the program after printing completions. Defaults to :meth:`os._exit`. If you want to perform a normal exit that calls exit handlers, use :meth:`sys.exit`. :param exclude: List of strings representing options to be omitted from autocompletion :param validator: Function to filter all completions through before returning (called with two string arguments, completion and prefix; return value is evaluated as a boolean) :param print_suppressed: Whether or not to autocomplete options that have the ``help=argparse.SUPPRESS`` keyword argument set. :param append_space: Whether to append a space to unique matches. The default is ``True``. .. note:: If you are not subclassing CompletionFinder to override its behaviors, use :meth:`argcomplete.autocomplete()` directly. It has the same signature as this method. Produces tab completions for ``argument_parser``. See module docs for more info. Argcomplete only executes actions if their class is known not to have side effects. Custom action classes can be added to argcomplete.safe_actions, if their values are wanted in the ``parsed_args`` completer argument, or their execution is otherwise desirable. """ self.__init__( # type: ignore argument_parser, always_complete_options=always_complete_options, exclude=exclude, validator=validator, print_suppressed=print_suppressed, append_space=append_space, default_completer=default_completer, ) if "_ARGCOMPLETE" not in os.environ: # not an argument completion invocation return self._init_debug_stream() if output_stream is None: filename = os.environ.get("_ARGCOMPLETE_STDOUT_FILENAME") if filename is not None: debug("Using output file {}".format(filename)) output_stream = open(filename, "w") if output_stream is None: try: output_stream = os.fdopen(8, "w") except Exception: debug("Unable to open fd 8 for writing, quitting") exit_method(1) assert output_stream is not None ifs = os.environ.get("_ARGCOMPLETE_IFS", "\013") if len(ifs) != 1: debug("Invalid value for IFS, quitting [{v}]".format(v=ifs)) exit_method(1) dfs = os.environ.get("_ARGCOMPLETE_DFS") if dfs and len(dfs) != 1: debug("Invalid value for DFS, quitting [{v}]".format(v=dfs)) exit_method(1) comp_line = os.environ["COMP_LINE"] comp_point = int(os.environ["COMP_POINT"]) cword_prequote, cword_prefix, cword_suffix, comp_words, last_wordbreak_pos = split_line(comp_line, comp_point) # _ARGCOMPLETE is set by the shell script to tell us where comp_words # should start, based on what we're completing. # 1: