parser argumentparser arg_parser add_argument python optparse

python - argumentparser - ¿Cómo puedo hacer que el OptionParser de optparse ignore las opciones no válidas?



arguments parser python (5)

Aquí hay una forma de agregar argumentos desconocidos a los argumentos de resultado de OptionParser.parse_args , con una subclase simple.

from optparse import (OptionParser,BadOptionError,AmbiguousOptionError) class PassThroughOptionParser(OptionParser): """ An unknown option pass-through implementation of OptionParser. When unknown arguments are encountered, bundle with largs and try again, until rargs is depleted. sys.exit(status) will still be called if a known argument is passed incorrectly (e.g. missing arguments or bad argument types, etc.) """ def _process_args(self, largs, rargs, values): while rargs: try: OptionParser._process_args(self,largs,rargs,values) except (BadOptionError,AmbiguousOptionError), e: largs.append(e.opt_str)

Y aquí hay un fragmento para mostrar que funciona:

# Show that the pass-through option parser works. if __name__ == "__main__": #pragma: no cover parser = PassThroughOptionParser() parser.add_option(''-k'', ''--known-arg'',dest=''known_arg'',nargs=1, type=''int'') (options,args) = parser.parse_args([''--shazbot'',''--known-arg=1'']) assert args[0] == ''--shazbot'' assert options.known_arg == 1 (options,args) = parser.parse_args([''--k'',''4'',''--batman-and-robin'']) assert args[0] == ''--batman-and-robin'' assert options.known_arg == 4

En el OptionParser de python, ¿cómo puedo indicarle que ignore las opciones no definidas proporcionadas al método parse_args ?

p.ej
Solo he definido la opción --foo para mi instancia de OptionParser , pero llamo a parse_args con list
[ ''--foo'', ''--bar'' ]

EDITAR:
No me importa si los filtra fuera de la lista original. Solo quiero que se ignoren las opciones indefinidas.

La razón por la que hago esto es porque estoy usando la interfaz AddOption de SCons para agregar opciones de compilación personalizadas. Sin embargo, algunas de esas opciones guían la declaración de los objetivos. Por lo tanto, necesito analizarlos fuera de sys.argv en diferentes puntos del script sin tener acceso a todas las opciones. Al final, el nivel superior OptionParser de Scons capturará todas las opciones no definidas en la línea de comandos.


De forma predeterminada, no hay forma de modificar el comportamiento de la llamada a error() que se genera cuando se pasa una opción no definida. De la documentación al final de la sección sobre cómo optparse maneja los errores :

Si el comportamiento predeterminado de manejo de errores de optparse no se adapta a sus necesidades, deberá subclasificar OptionParser y anular sus métodos de salida () y / o error ().

El ejemplo más simple de esto sería:

class MyOptionParser(OptionParser): def error(self, msg): pass

Esto simplemente haría que todas las llamadas a error() no hagan nada. Por supuesto, esto no es ideal, pero creo que esto ilustra lo que tendrías que hacer. Tenga en cuenta la cadena de documentación de error() y debería estar listo para continuar a medida que avanza:

Imprima un mensaje de uso que incorpore ''msg'' a stderr y salga. Si reemplaza esto en una subclase, no debería regresar, debe salir o generar una excepción.


Este es el ejemplo de pass_through.py de la distribución de Optik .

#!/usr/bin/env python # "Pass-through" option parsing -- an OptionParser that ignores # unknown options and lets them pile up in the leftover argument # list. Useful for programs that pass unknown options through # to a sub-program. from optparse import OptionParser, BadOptionError class PassThroughOptionParser(OptionParser): def _process_long_opt(self, rargs, values): try: OptionParser._process_long_opt(self, rargs, values) except BadOptionError, err: self.largs.append(err.opt_str) def _process_short_opts(self, rargs, values): try: OptionParser._process_short_opts(self, rargs, values) except BadOptionError, err: self.largs.append(err.opt_str) def main(): parser = PassThroughOptionParser() parser.add_option("-a", help="some option") parser.add_option("-b", help="some other option") parser.add_option("--other", action=''store_true'', help="long option that takes no arg") parser.add_option("--value", help="long option that takes an arg") (options, args) = parser.parse_args() print "options:", options print "args:", args main()



Según la solicitud de synack en los comentarios de otra respuesta, estoy publicando mi truco de una solución que desinfecta las entradas antes de pasarlas al OptionParser principal:

import optparse import re import copy import SCons class NoErrOptionParser(optparse.OptionParser): def __init__(self,*args,**kwargs): self.valid_args_cre_list = [] optparse.OptionParser.__init__(self, *args, **kwargs) def error(self,msg): pass def add_option(self,*args,**kwargs): self.valid_args_cre_list.append(re.compile(''^''+args[0]+''='')) optparse.OptionParser.add_option(self, *args, **kwargs) def parse_args(self,*args,**kwargs): # filter out invalid options args_to_parse = args[0] new_args_to_parse = [] for a in args_to_parse: for cre in self.valid_args_cre_list: if cre.match(a): new_args_to_parse.append(a) # nuke old values and insert the new while len(args_to_parse) > 0: args_to_parse.pop() for a in new_args_to_parse: args_to_parse.append(a) return optparse.OptionParser.parse_args(self,*args,**kwargs) def AddOption_and_get_NoErrOptionParser( *args, **kwargs): apply( SCons.Script.AddOption, args, kwargs) no_err_optparser = NoErrOptionParser(optparse.SUPPRESS_USAGE) apply(no_err_optparser.add_option, args, kwargs) return no_err_optpars