diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-08-21 14:11:39 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-08-21 14:27:47 +0300 |
commit | 1ca193d726bed5ece8656b0072bfe03ebb0478c6 (patch) | |
tree | bb891c7d29b0e2c620716a5c9a24a8285afad073 /contrib/python/argcomplete | |
parent | 3391579f10b1bab2f82c4ea4921c794ab67e0d8b (diff) | |
download | ydb-1ca193d726bed5ece8656b0072bfe03ebb0478c6.tar.gz |
Intermediate changes
Diffstat (limited to 'contrib/python/argcomplete')
10 files changed, 351 insertions, 8 deletions
diff --git a/contrib/python/argcomplete/py3/.dist-info/METADATA b/contrib/python/argcomplete/py3/.dist-info/METADATA index adbd1293a6..ce75d7bfa8 100644 --- a/contrib/python/argcomplete/py3/.dist-info/METADATA +++ b/contrib/python/argcomplete/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: argcomplete -Version: 3.4.0 +Version: 3.5.0 Summary: Bash tab completion for argparse Home-page: https://github.com/kislyuk/argcomplete Author: Andrey Kislyuk diff --git a/contrib/python/argcomplete/py3/.dist-info/entry_points.txt b/contrib/python/argcomplete/py3/.dist-info/entry_points.txt new file mode 100644 index 0000000000..f13e435faf --- /dev/null +++ b/contrib/python/argcomplete/py3/.dist-info/entry_points.txt @@ -0,0 +1,4 @@ +[console_scripts] +activate-global-python-argcomplete = argcomplete.scripts.activate_global_python_argcomplete:main +python-argcomplete-check-easy-install-script = argcomplete.scripts.python_argcomplete_check_easy_install_script:main +register-python-argcomplete = argcomplete.scripts.register_python_argcomplete:main diff --git a/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete b/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete index dec7cdac16..81c9d41f80 100644 --- a/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete +++ b/contrib/python/argcomplete/py3/argcomplete/bash_completion.d/_python-argcomplete @@ -1,5 +1,6 @@ #compdef -default- +# argcomplete global completion loader for zsh and bash # Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. # Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. diff --git a/contrib/python/argcomplete/py3/argcomplete/completers.py b/contrib/python/argcomplete/py3/argcomplete/completers.py index d89cdbfbc3..b62c593d64 100644 --- a/contrib/python/argcomplete/py3/argcomplete/completers.py +++ b/contrib/python/argcomplete/py3/argcomplete/completers.py @@ -22,7 +22,7 @@ class BaseCompleter: 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.") diff --git a/contrib/python/argcomplete/py3/argcomplete/finders.py b/contrib/python/argcomplete/py3/argcomplete/finders.py index fb0f31cefd..793b462eed 100644 --- a/contrib/python/argcomplete/py3/argcomplete/finders.py +++ b/contrib/python/argcomplete/py3/argcomplete/finders.py @@ -7,10 +7,10 @@ import argparse import os import sys from collections.abc import Mapping -from typing import Callable, Dict, List, Optional, Sequence, Union +from typing import Callable, Dict, List, Optional, Sequence, TextIO, Union from . import io as _io -from .completers import ChoicesCompleter, FilesCompleter, SuppressCompleter +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 @@ -66,13 +66,13 @@ class CompletionFinder(object): argument_parser: argparse.ArgumentParser, always_complete_options: Union[bool, str] = True, exit_method: Callable = os._exit, - output_stream=None, + 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=FilesCompleter(), - ): + default_completer: BaseCompleter = FilesCompleter(), + ) -> None: """ :param argument_parser: The argument parser to autocomplete on :param always_complete_options: @@ -132,6 +132,8 @@ class CompletionFinder(object): 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)) diff --git a/contrib/python/argcomplete/py3/argcomplete/scripts/__init__.py b/contrib/python/argcomplete/py3/argcomplete/scripts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/contrib/python/argcomplete/py3/argcomplete/scripts/__init__.py diff --git a/contrib/python/argcomplete/py3/argcomplete/scripts/activate_global_python_argcomplete.py b/contrib/python/argcomplete/py3/argcomplete/scripts/activate_global_python_argcomplete.py new file mode 100644 index 0000000000..768b8aa6bf --- /dev/null +++ b/contrib/python/argcomplete/py3/argcomplete/scripts/activate_global_python_argcomplete.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK + +# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. +# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. + +""" +Activate the generic bash-completion script or zsh completion autoload function for the argcomplete module. +""" + +import argparse +import os +import shutil +import site +import subprocess +import sys + +import argcomplete + +# PEP 366 +__package__ = "argcomplete.scripts" + +zsh_shellcode = """ +# Begin added by argcomplete +fpath=( {zsh_fpath} "${{fpath[@]}}" ) +# End added by argcomplete +""" + +bash_shellcode = """ +# Begin added by argcomplete +source "{activator}" +# End added by argcomplete +""" + +parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) +parser.add_argument("-y", "--yes", help="automatically answer yes for all questions", action="store_true") +parser.add_argument("--dest", help='Specify the shell completion modules directory to install into, or "-" for stdout') +parser.add_argument("--user", help="Install into user directory", action="store_true") +argcomplete.autocomplete(parser) +args = None + + +def get_local_dir(): + try: + return subprocess.check_output(["brew", "--prefix"]).decode().strip() + except (FileNotFoundError, subprocess.CalledProcessError): + return "/usr/local" + + +def get_zsh_system_dir(): + return f"{get_local_dir()}/share/zsh/site-functions" + + +def get_bash_system_dir(): + if "BASH_COMPLETION_COMPAT_DIR" in os.environ: + return os.environ["BASH_COMPLETION_COMPAT_DIR"] + elif sys.platform == "darwin": + return f"{get_local_dir()}/etc/bash_completion.d" # created by homebrew + else: + return "/etc/bash_completion.d" # created by bash-completion + + +def get_activator_dir(): + return os.path.join(os.path.abspath(os.path.dirname(argcomplete.__file__)), "bash_completion.d") + + +def get_activator_path(): + return os.path.join(get_activator_dir(), "_python-argcomplete") + + +def install_to_destination(dest): + activator = get_activator_path() + if dest == "-": + with open(activator) as fh: + sys.stdout.write(fh.read()) + return + destdir = os.path.dirname(dest) + if not os.path.exists(destdir): + try: + os.makedirs(destdir, exist_ok=True) + except Exception as e: + parser.error(f"path {destdir} does not exist and could not be created: {e}") + try: + print(f"Installing {activator} to {dest}...", file=sys.stderr) + shutil.copy(activator, dest) + print("Installed.", file=sys.stderr) + except Exception as e: + parser.error( + f"while installing to {dest}: {e}. Please run this command using sudo, or see --help for more options." + ) + + +def get_consent(): + assert args is not None + if args.yes is True: + return True + while True: + res = input("OK to proceed? [y/n] ") + if res.lower() not in {"y", "n", "yes", "no"}: + print('Please answer "yes" or "no".', file=sys.stderr) + elif res.lower() in {"y", "yes"}: + return True + else: + return False + + +def append_to_config_file(path, shellcode): + if os.path.exists(path): + with open(path, 'r') as fh: + if shellcode in fh.read(): + print(f"The code already exists in the file {path}.", file=sys.stderr) + return + print(f"argcomplete needs to append to the file {path}. The following code will be appended:", file=sys.stderr) + for line in shellcode.splitlines(): + print(">", line, file=sys.stderr) + if not get_consent(): + print("Not added.", file=sys.stderr) + return + print(f"Adding shellcode to {path}...", file=sys.stderr) + with open(path, "a") as fh: + fh.write(shellcode) + print("Added.", file=sys.stderr) + + +def link_user_rcfiles(): + # TODO: warn if running as superuser + zsh_rcfile = os.path.join(os.path.expanduser(os.environ.get("ZDOTDIR", "~")), ".zshenv") + append_to_config_file(zsh_rcfile, zsh_shellcode.format(zsh_fpath=get_activator_dir())) + + bash_completion_user_file = os.path.expanduser("~/.bash_completion") + append_to_config_file(bash_completion_user_file, bash_shellcode.format(activator=get_activator_path())) + + +def main(): + global args + args = parser.parse_args() + + destinations = [] + + if args.dest: + if args.dest != "-" and not os.path.exists(args.dest): + parser.error(f"directory {args.dest} was specified via --dest, but it does not exist") + destinations.append(args.dest) + elif site.ENABLE_USER_SITE and site.USER_SITE and site.USER_SITE in argcomplete.__file__: + print( + "Argcomplete was installed in the user site local directory. Defaulting to user installation.", + file=sys.stderr, + ) + link_user_rcfiles() + elif sys.prefix != sys.base_prefix: + print("Argcomplete was installed in a virtual environment. Defaulting to user installation.", file=sys.stderr) + link_user_rcfiles() + elif args.user: + link_user_rcfiles() + else: + print("Defaulting to system-wide installation.", file=sys.stderr) + destinations.append(f"{get_zsh_system_dir()}/_python-argcomplete") + destinations.append(f"{get_bash_system_dir()}/python-argcomplete") + + for destination in destinations: + install_to_destination(destination) + + if args.dest is None: + print("Please restart your shell or source the installed file to activate it.", file=sys.stderr) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/python/argcomplete/py3/argcomplete/scripts/python_argcomplete_check_easy_install_script.py b/contrib/python/argcomplete/py3/argcomplete/scripts/python_argcomplete_check_easy_install_script.py new file mode 100644 index 0000000000..d914c222fe --- /dev/null +++ b/contrib/python/argcomplete/py3/argcomplete/scripts/python_argcomplete_check_easy_install_script.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 + +# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. +# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. + +""" +This script is part of the Python argcomplete package (https://github.com/kislyuk/argcomplete). +It is used to check if an EASY-INSTALL-SCRIPT wrapper redirects to a script that contains the string +"PYTHON_ARGCOMPLETE_OK". If you have enabled global completion in argcomplete, the completion hook will run it every +time you press <TAB> in your shell. + +Usage: + python-argcomplete-check-easy-install-script <input executable file> +""" + +import sys + +# PEP 366 +__package__ = "argcomplete.scripts" + + +def main(): + if len(sys.argv) != 2: + sys.exit(__doc__) + + sys.tracebacklimit = 0 + + with open(sys.argv[1]) as fh: + line1, head = fh.read(1024).split("\n", 1)[:2] + if line1.startswith("#") and ("py" in line1 or "Py" in line1): + import re + + lines = head.split("\n", 12) + for line in lines: + if line.startswith("# EASY-INSTALL-SCRIPT"): + import pkg_resources + + re_match = re.match("# EASY-INSTALL-SCRIPT: '(.+)','(.+)'", line) + assert re_match is not None + dist, script = re_match.groups() + if "PYTHON_ARGCOMPLETE_OK" in pkg_resources.get_distribution(dist).get_metadata( + "scripts/" + script + ): + return 0 + elif line.startswith("# EASY-INSTALL-ENTRY-SCRIPT"): + re_match = re.match("# EASY-INSTALL-ENTRY-SCRIPT: '(.+)','(.+)','(.+)'", line) + assert re_match is not None + dist, group, name = re_match.groups() + import pkgutil + + import pkg_resources + + entry_point_info = pkg_resources.get_distribution(dist).get_entry_info(group, name) + assert entry_point_info is not None + module_name = entry_point_info.module_name + with open(pkgutil.get_loader(module_name).get_filename()) as mod_fh: # type: ignore + if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): + return 0 + elif line.startswith("# EASY-INSTALL-DEV-SCRIPT"): + for line2 in lines: + if line2.startswith("__file__"): + re_match = re.match("__file__ = '(.+)'", line2) + assert re_match is not None + filename = re_match.group(1) + with open(filename) as mod_fh: + if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): + return 0 + elif line.startswith("# PBR Generated"): + re_match = re.search("from (.*) import", head) + assert re_match is not None + module = re_match.groups()[0] + import pkgutil + + import pkg_resources + + with open(pkgutil.get_loader(module).get_filename()) as mod_fh: # type: ignore + if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): + return 0 + + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/python/argcomplete/py3/argcomplete/scripts/register_python_argcomplete.py b/contrib/python/argcomplete/py3/argcomplete/scripts/register_python_argcomplete.py new file mode 100644 index 0000000000..1e68029825 --- /dev/null +++ b/contrib/python/argcomplete/py3/argcomplete/scripts/register_python_argcomplete.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK + +# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. +# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. + +""" +Register a Python executable for use with the argcomplete module. + +To perform the registration, source the output of this script in your bash shell +(quote the output to avoid interpolation). + +Example: + + $ eval "$(register-python-argcomplete my-favorite-script.py)" + +For Tcsh + + $ eval `register-python-argcomplete --shell tcsh my-favorite-script.py` + +For Fish + + $ register-python-argcomplete --shell fish my-favourite-script.py > ~/.config/fish/my-favourite-script.py.fish +""" + +import argparse +import sys + +import argcomplete + +# PEP 366 +__package__ = "argcomplete.scripts" + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + + parser.add_argument( + "--no-defaults", + dest="use_defaults", + action="store_false", + default=True, + help="when no matches are generated, do not fallback to readline's default completion (affects bash only)", + ) + parser.add_argument( + "--complete-arguments", + nargs=argparse.REMAINDER, + help="arguments to call complete with; use of this option discards default options (affects bash only)", + ) + parser.add_argument( + "-s", + "--shell", + choices=("bash", "zsh", "tcsh", "fish", "powershell"), + default="bash", + help="output code for the specified shell", + ) + parser.add_argument( + "-e", "--external-argcomplete-script", help="external argcomplete script for auto completion of the executable" + ) + + parser.add_argument("executable", nargs="+", help="executable to completed (when invoked by exactly this name)") + + argcomplete.autocomplete(parser) + + if len(sys.argv) == 1: + parser.print_help() + sys.exit(1) + + args = parser.parse_args() + + sys.stdout.write( + argcomplete.shellcode( + args.executable, args.use_defaults, args.shell, args.complete_arguments, args.external_argcomplete_script + ) + ) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/python/argcomplete/py3/ya.make b/contrib/python/argcomplete/py3/ya.make index e2cc4f6540..16487619c8 100644 --- a/contrib/python/argcomplete/py3/ya.make +++ b/contrib/python/argcomplete/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(3.4.0) +VERSION(3.5.0) LICENSE(Apache-2.0) @@ -21,12 +21,17 @@ PY_SRCS( argcomplete/packages/__init__.py argcomplete/packages/_argparse.py argcomplete/packages/_shlex.py + argcomplete/scripts/__init__.py + argcomplete/scripts/activate_global_python_argcomplete.py + argcomplete/scripts/python_argcomplete_check_easy_install_script.py + argcomplete/scripts/register_python_argcomplete.py argcomplete/shell_integration.py ) RESOURCE_FILES( PREFIX contrib/python/argcomplete/py3/ .dist-info/METADATA + .dist-info/entry_points.txt .dist-info/top_level.txt argcomplete/bash_completion.d/_python-argcomplete argcomplete/py.typed |