Deshabilitar abreviatura en argparse

Usos argparse por abreviatura predeterminada en casos no ambiguos.

No quiero la abreviatura y me gustaría desactivarla. Pero no lo encontré en la documentación .

¿Es posible?

Ejemplo:

import argparse parser = argparse.ArgumentParser() parser.add_argument('--send', action='store_true') parser.parse_args(['--se']) # returns Namespace(send=True) 

Pero quiero que solo sea cierto cuando se suministre el parámetro completo. Para evitar errores de usuario.

ACTUALIZAR:

Creé un ticket en Python bugtracker después de que Vikas respondiera. Y ya se ha procesado.

A partir de Python 3.5.0 puede desactivar las abreviaturas iniciando ArgumentParser con lo siguiente:

 parser = argparse.ArgumentParser(allow_abbrev=False) 

Véase también la documentación .

No, al parecer esto no es posible. Al menos en Python 2.7.2.

En primer lugar, eché un vistazo a la documentación, en vano.

Luego abrí el archivo Lib \ argparse.py y miré el código fuente. Omitiendo muchos detalles, parece que cada argumento es analizado por una expresión regular como esta (argparse: 2152):

  # allow one or more arguments elif nargs == ONE_OR_MORE: nargs_pattern = '(-*A[A-]*)' 

Esta expresión regular analizará con éxito tanto ‘-‘ como ‘-‘, por lo que no tenemos control sobre los argumentos cortos y largos. Otras expresiones regulares también usan la construcción – *, por lo que no depende del tipo de parámetro (no hay argumentos secundarios, 1 argumento secundario, etc.).

Más adelante en el código, los guiones dobles se convierten en un guión (solo para argumentos no opcionales), nuevamente, sin ninguna marca para controlar por el usuario:

  # if this is an optional action, -- is not allowed if action.option_strings: nargs_pattern = nargs_pattern.replace('-*', '') nargs_pattern = nargs_pattern.replace('-', '') 

No, bueno no sin hacks feos.

El fragmento de código @Vladimir publicado, supongo que no es lo que está buscando. El código real que está haciendo esto es:

 def _get_option_tuples(self, option_string): ... if option_string.startswith(option_prefix): ... 

Ver el cheque es startswith no == .

Y siempre puede extender argparse.ArgumentParser para proporcionar sus propias _get_option_tuples(self, option_string) para cambiar este comportamiento. Acabo de hacerlo reemplazando dos apariciones de option_string.startswith(option_prefix) por option_string == option_prefix y:

 >>> parser = my_argparse.MyArgparse >>> parser = my_argparse.MyArgparse() >>> parser.add_argument('--send', action='store_true') _StoreTrueAction(option_strings=['--send'], dest='send', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None) >>> parser.parse_args(['--se']) usage: [-h] [--send] : error: unrecognized arguments: --se 

Una palabra de precaución

El método _get_option_tuples tiene el prefijo _ , que normalmente significa un método privado en python. Y no es una buena idea anular un privado.

Otra forma para Python 2.7. ¡Vamos a emborracharnos! Digamos que quieres reconocer --dog sin abreviatura.

 p = argparse.ArgumentParser() p.add_argument('--dog') p.add_argument('--dox', help=argparse.SUPPRESS, metavar='IGNORE') 

Al agregar un segundo argumento --dox que difiere del argumento que quiere solo en la tercera letra, --d y --do vuelven ambiguos. Por lo tanto, el analizador se negará a reconocerlos. Necesitaría agregar código para capturar la excepción resultante y procesarla de acuerdo con el contexto en el que está llamando a parse_args . Es posible que también deba suprimir / modificar el texto de ayuda.

La help=... mantiene el argumento fuera de la lista de opciones en el mensaje de ayuda predeterminado (por esto ), y metavar='IGNORE' es solo para aclarar que realmente no está haciendo nada con esta opción :).