From 903b2bd9168b8419713bc0d19ce6344ea3170635 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 31 Jul 2024 09:42:04 +0300 Subject: [PATCH 1/4] Move the scripts inside the package Split from #474 --- argcomplete/scripts/__init__.py | 0 .../scripts/activate_global_python_argcomplete.py | 0 .../scripts/python_argcomplete_check_easy_install_script.py | 0 .../scripts/register_python_argcomplete.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 argcomplete/scripts/__init__.py rename scripts/activate-global-python-argcomplete => argcomplete/scripts/activate_global_python_argcomplete.py (100%) rename scripts/python-argcomplete-check-easy-install-script => argcomplete/scripts/python_argcomplete_check_easy_install_script.py (100%) rename scripts/register-python-argcomplete => argcomplete/scripts/register_python_argcomplete.py (100%) diff --git a/argcomplete/scripts/__init__.py b/argcomplete/scripts/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/scripts/activate-global-python-argcomplete b/argcomplete/scripts/activate_global_python_argcomplete.py similarity index 100% rename from scripts/activate-global-python-argcomplete rename to argcomplete/scripts/activate_global_python_argcomplete.py diff --git a/scripts/python-argcomplete-check-easy-install-script b/argcomplete/scripts/python_argcomplete_check_easy_install_script.py similarity index 100% rename from scripts/python-argcomplete-check-easy-install-script rename to argcomplete/scripts/python_argcomplete_check_easy_install_script.py diff --git a/scripts/register-python-argcomplete b/argcomplete/scripts/register_python_argcomplete.py similarity index 100% rename from scripts/register-python-argcomplete rename to argcomplete/scripts/register_python_argcomplete.py From 570e8dd6efb2a6e8026fb7be47613e1c6421a828 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 31 Jul 2024 09:44:35 +0300 Subject: [PATCH 2/4] Convert scripts to the format used by console_scripts Split from kislyuk#474 --- .../activate_global_python_argcomplete.py | 77 +++++++------ ...n_argcomplete_check_easy_install_script.py | 101 ++++++++++-------- .../scripts/register_python_argcomplete.py | 87 ++++++++------- scripts/activate-global-python-argcomplete | 9 ++ ...thon-argcomplete-check-easy-install-script | 8 ++ scripts/register-python-argcomplete | 6 ++ 6 files changed, 168 insertions(+), 120 deletions(-) create mode 100644 scripts/activate-global-python-argcomplete create mode 100644 scripts/python-argcomplete-check-easy-install-script create mode 100644 scripts/register-python-argcomplete diff --git a/argcomplete/scripts/activate_global_python_argcomplete.py b/argcomplete/scripts/activate_global_python_argcomplete.py index 96017cb7..b2ba183e 100755 --- a/argcomplete/scripts/activate_global_python_argcomplete.py +++ b/argcomplete/scripts/activate_global_python_argcomplete.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # PYTHON_ARGCOMPLETE_OK # Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. @@ -17,6 +17,8 @@ import argcomplete +__package__ = "argcomplete" + zsh_shellcode = """ # Begin added by argcomplete fpath=( {zsh_fpath} "${{fpath[@]}}" ) @@ -29,6 +31,13 @@ # 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: @@ -120,35 +129,37 @@ def link_user_rcfiles(): append_to_config_file(bash_completion_user_file, bash_shellcode.format(activator=get_activator_path())) -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 = 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 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) +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 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/argcomplete/scripts/python_argcomplete_check_easy_install_script.py b/argcomplete/scripts/python_argcomplete_check_easy_install_script.py index 07961a23..09dc68af 100755 --- a/argcomplete/scripts/python_argcomplete_check_easy_install_script.py +++ b/argcomplete/scripts/python_argcomplete_check_easy_install_script.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/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. @@ -15,49 +15,56 @@ import sys -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 - - dist, script = re.match("# EASY-INSTALL-SCRIPT: '(.+)','(.+)'", line).groups() - if "PYTHON_ARGCOMPLETE_OK" in pkg_resources.get_distribution(dist).get_metadata("scripts/" + script): - exit(0) - elif line.startswith("# EASY-INSTALL-ENTRY-SCRIPT"): - dist, group, name = re.match("# EASY-INSTALL-ENTRY-SCRIPT: '(.+)','(.+)','(.+)'", line).groups() - import pkgutil - - import pkg_resources - - module_name = pkg_resources.get_distribution(dist).get_entry_info(group, name).module_name - with open(pkgutil.get_loader(module_name).get_filename()) as mod_fh: - if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): - exit(0) - elif line.startswith("# EASY-INSTALL-DEV-SCRIPT"): - for line2 in lines: - if line2.startswith("__file__"): - filename = re.match("__file__ = '(.+)'", line2).group(1) - with open(filename) as mod_fh: - if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): - exit(0) - elif line.startswith("# PBR Generated"): - module = re.search("from (.*) import", head).groups()[0] - import pkgutil - - import pkg_resources - - with open(pkgutil.get_loader(module).get_filename()) as mod_fh: - if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): - exit(0) - -exit(1) +__package__ = "argcomplete" + +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 + + dist, script = re.match("# EASY-INSTALL-SCRIPT: '(.+)','(.+)'", line).groups() + if "PYTHON_ARGCOMPLETE_OK" in pkg_resources.get_distribution(dist).get_metadata("scripts/" + script): + return 0 + elif line.startswith("# EASY-INSTALL-ENTRY-SCRIPT"): + dist, group, name = re.match("# EASY-INSTALL-ENTRY-SCRIPT: '(.+)','(.+)','(.+)'", line).groups() + import pkgutil + + import pkg_resources + + module_name = pkg_resources.get_distribution(dist).get_entry_info(group, name).module_name + with open(pkgutil.get_loader(module_name).get_filename()) as mod_fh: + 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__"): + filename = re.match("__file__ = '(.+)'", line2).group(1) + with open(filename) as mod_fh: + if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): + return 0 + elif line.startswith("# PBR Generated"): + module = re.search("from (.*) import", head).groups()[0] + import pkgutil + + import pkg_resources + + with open(pkgutil.get_loader(module).get_filename()) as mod_fh: + if "PYTHON_ARGCOMPLETE_OK" in mod_fh.read(1024): + return 0 + + return 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/argcomplete/scripts/register_python_argcomplete.py b/argcomplete/scripts/register_python_argcomplete.py index d95eb3fb..df67114d 100755 --- a/argcomplete/scripts/register_python_argcomplete.py +++ b/argcomplete/scripts/register_python_argcomplete.py @@ -28,44 +28,51 @@ import argcomplete -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 +__package__ = "argcomplete" + +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/scripts/activate-global-python-argcomplete b/scripts/activate-global-python-argcomplete new file mode 100644 index 00000000..0b661a31 --- /dev/null +++ b/scripts/activate-global-python-argcomplete @@ -0,0 +1,9 @@ +#!/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. + +import sys +from argcomplete.scripts import activate_global_python_argcomplete +sys.exit(activate_global_python_argcomplete()) diff --git a/scripts/python-argcomplete-check-easy-install-script b/scripts/python-argcomplete-check-easy-install-script new file mode 100644 index 00000000..a3b499ab --- /dev/null +++ b/scripts/python-argcomplete-check-easy-install-script @@ -0,0 +1,8 @@ +#!/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. + +import sys +from argcomplete.scripts import python_argcomplete_check_easy_install_script +sys.exit(python_argcomplete_check_easy_install_script()) diff --git a/scripts/register-python-argcomplete b/scripts/register-python-argcomplete new file mode 100644 index 00000000..ac376c6a --- /dev/null +++ b/scripts/register-python-argcomplete @@ -0,0 +1,6 @@ +# Copyright 2012-2023, Andrey Kislyuk and argcomplete contributors. +# Licensed under the Apache License. See https://github.com/kislyuk/argcomplete for more info. + +import sys +from argcomplete.scripts import register_python_argcomplete +sys.exit(register_python_argcomplete()) From ed3f9ed37471ec272cacfe015656fecbde6ea14f Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 31 Jul 2024 09:45:58 +0300 Subject: [PATCH 3/4] Review fix --- argcomplete/scripts/activate_global_python_argcomplete.py | 1 + .../scripts/python_argcomplete_check_easy_install_script.py | 1 + argcomplete/scripts/register_python_argcomplete.py | 1 + 3 files changed, 3 insertions(+) diff --git a/argcomplete/scripts/activate_global_python_argcomplete.py b/argcomplete/scripts/activate_global_python_argcomplete.py index b2ba183e..74dbb583 100755 --- a/argcomplete/scripts/activate_global_python_argcomplete.py +++ b/argcomplete/scripts/activate_global_python_argcomplete.py @@ -17,6 +17,7 @@ import argcomplete +# PEP 366 __package__ = "argcomplete" zsh_shellcode = """ diff --git a/argcomplete/scripts/python_argcomplete_check_easy_install_script.py b/argcomplete/scripts/python_argcomplete_check_easy_install_script.py index 09dc68af..0cf9c8b1 100755 --- a/argcomplete/scripts/python_argcomplete_check_easy_install_script.py +++ b/argcomplete/scripts/python_argcomplete_check_easy_install_script.py @@ -15,6 +15,7 @@ import sys +# PEP 366 __package__ = "argcomplete" def main(): diff --git a/argcomplete/scripts/register_python_argcomplete.py b/argcomplete/scripts/register_python_argcomplete.py index df67114d..6444963a 100755 --- a/argcomplete/scripts/register_python_argcomplete.py +++ b/argcomplete/scripts/register_python_argcomplete.py @@ -28,6 +28,7 @@ import argcomplete +# PEP 366 __package__ = "argcomplete" def main(): From 0461c108c6c403770fbb84a4422dd598e6a9b2ef Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Thu, 1 Aug 2024 17:22:03 +0300 Subject: [PATCH 4/4] Fix __package__ PEP 366 specification --- argcomplete/scripts/activate_global_python_argcomplete.py | 2 +- .../scripts/python_argcomplete_check_easy_install_script.py | 2 +- argcomplete/scripts/register_python_argcomplete.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/argcomplete/scripts/activate_global_python_argcomplete.py b/argcomplete/scripts/activate_global_python_argcomplete.py index 74dbb583..01142fed 100755 --- a/argcomplete/scripts/activate_global_python_argcomplete.py +++ b/argcomplete/scripts/activate_global_python_argcomplete.py @@ -18,7 +18,7 @@ import argcomplete # PEP 366 -__package__ = "argcomplete" +__package__ = "argcomplete.scripts" zsh_shellcode = """ # Begin added by argcomplete diff --git a/argcomplete/scripts/python_argcomplete_check_easy_install_script.py b/argcomplete/scripts/python_argcomplete_check_easy_install_script.py index 0cf9c8b1..b74a745e 100755 --- a/argcomplete/scripts/python_argcomplete_check_easy_install_script.py +++ b/argcomplete/scripts/python_argcomplete_check_easy_install_script.py @@ -16,7 +16,7 @@ import sys # PEP 366 -__package__ = "argcomplete" +__package__ = "argcomplete.scripts" def main(): if len(sys.argv) != 2: diff --git a/argcomplete/scripts/register_python_argcomplete.py b/argcomplete/scripts/register_python_argcomplete.py index 6444963a..d2f6ae9d 100755 --- a/argcomplete/scripts/register_python_argcomplete.py +++ b/argcomplete/scripts/register_python_argcomplete.py @@ -29,7 +29,7 @@ import argcomplete # PEP 366 -__package__ = "argcomplete" +__package__ = "argcomplete.scripts" def main(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)