python bash command-line-interface argparse tab-completion

Finalización de la pestaña personalizada en python argparse



bash command-line-interface (2)

¿Cómo obtener la finalización de la pestaña de shell cooperando con argparse en un script de Python?

#!/usr/bin/env python import argparse def main(**args): pass if __name__ == ''__main__'': parser = argparse.ArgumentParser() parser.add_argument(''positional'', choices=[''spam'', ''eggs'']) parser.add_argument(''--optional'', choices=[''foo1'', ''foo2'', ''bar'']) args = parser.parse_args() main(**vars(args))

Con un indicador ejecutable establecido en el archivo .py, los resultados esperados deberían ser algo como:

$ ./example.py sp<tab> -> completes to "./example.py spam" $ ./example.py --op<tab> -> completes to "./example.py --optional" $ ./example.py --optional b<tab> -> completes to "./example.py --optional bar" $ ./example.py --optional f<tab> -> completes to "./example.py --optional foo" and, additionally, prints "foo1 foo2" choices on stdout on a new line


Echa un vistazo a argcomplete por Andrey Kislyuk.

Instalalo con:

pip install argcomplete

Importe el módulo y agregue una línea en su fuente antes de llamar a parser.parse_args() :

#!/usr/bin/env python import argparse as ap import argcomplete def main(**args): pass if __name__ == ''__main__'': parser = ap.ArgumentParser() parser.add_argument(''positional'', choices=[''spam'', ''eggs'']) parser.add_argument(''--optional'', choices=[''foo1'', ''foo2'', ''bar'']) argcomplete.autocomplete(parser) args = parser.parse_args() main(**vars(args))

y para asegurarse de que bash sepa acerca de este script, use

eval "$(register-python-argcomplete your_script)"

debe poner esa línea en su ~/.bashrc o seguir los documentos de argcomplete y activar la finalización ''global''.

Después de que su finalización funciona según lo solicitado.

La forma en que funciona es que la línea eval crea una función _python_argcomlete que se registra usando complete . (Ejecute register-python-argcomplete your_script para ver lo que se evalúa en bash). La función autocompletar busca las variables de entorno establecidas por el mecanismo de finalización de bash para ver si necesita actuar. Si actúa, sale del programa. Si no actúa, esta es una llamada normal al programa, esa función no hace nada y el flujo normal del programa continúa.


Para que la función de autocompletar funcione, necesita una función bash para generar las opciones posibles, y luego debe ejecutar el complete -F <function_name> <program_name>

La mejor manera de hacer esto es hacer que el programa genere la función de finalización basada en su propio algoritmo de análisis para evitar la duplicación. Sin embargo, a simple vista de argparse, no pude encontrar una forma de acceder a su estructura interna, pero le sugiero que la busque.

Aquí está una función de bash que hará para el programa anterior:

function _example_auto() { local cur=${COMP_WORDS[COMP_CWORD]} local prev=${COMP_WORDS[COMP_CWORD-1]} case "$prev" in --optional ) COMPREPLY=( $(compgen -W "foo1 foo2 bar" -- $cur) ) return 0 ;; *) COMPREPLY=( $(compgen -W "--optional spam eggs" -- $cur) ) return 0 ;; esac }