Multiple calls to OptionParser.parse_args () within the same python execution

I have the following installation example:

|-- main_script.py `-- module |-- __init__.py `-- submodule.py 

where is the contents of main_script:

 import optparse import module parser = optparse.OptionParser() group = optparse.OptionGroup("submodules options") group.add_option("","--main_script.bar", dest="bar", action="store_true") parser.add_option_group(group) opts,args = parser.parse_args() if opts.bar: print ("Bar") 

and the contents of the submodule .py:

 import optparse parser = optparse.OptionParser() group = optparse.OptionGroup(parser, "submodules options") group.add_option("","--module.submodule.foo", dest="foo", action="store_true") parser.add_option_group(group) opts,args = parser.parse_args() if opts.foo: print ("Foo") 

Since main_script imports the submodule, parse_args from the submodule is callable. Is there a way to combine these instances of OptionParser and throw an error if there are parameter conflicts?

+4
source share
2 answers

The easiest way is to break your logic into functions. First, you should not follow the logic in the global module area, but use the shell construct if name == "__main__" .

You can define the add_options(parser) function for each module that needs to determine the parameters and call it at the root level before calling parse_args :

 import optparse import submodule def add_options(parser): parser.add_option(...) def main(): parser = optparse.OptionParser() add_options(parser) submodule.add_options(parser) opts, args = parser.parse_args() #... if __main__ == "__main__": main() 
+2
source

In an attempt to solve this problem from the outside inside - I have an initial implementation that fixes the optparse module, replacing the OptionParser class with a subclass of OptionParser and overloading the parse_args + method, produces a new delayed_parse_args method. I use fragments from this solution if someone else finds it useful or can improve it.

optparse_patch.py

 import optparse def patch_opt_parser(): optparse.stashed_parsers = {} class OptionParserEx(optparse.OptionParser): def delayed_parse_args(self, callback): optparse.stashed_parsers[self] = callback def parse_args(self, args=None, values=None): for parser, callback in getattr(optparse,"stashed_parsers").items(): # add all the option_list & option_groups from the individual # parsers in stashed_parsers to `self` for parser, callback in getattr(optparse,"stashed_parsers").items(): # update `parser` to inherit the option_lists and option_groups from # self. then .... _o, _a = optparse._OptionParser.parse_args( parser, args, values ) callback( _o, _a t) return getattr(optparse,"_OptionParser").parse_args(self, args, values) optparse._OptionParser = optparse.OptionParser optparse.OptionParser = OptionParserEx patch_opt_parser() 

This allows the submodules to β€œhide” their expected parameters and have command line parameters evaluated at a later stage, when the module client actually provides OptionParser and calls the parse_args method on its own OptionParser. An example of such a use case is the following:

module.py

 import optparse_patch import optparse parser = optparse.OptionParser() group = optparse.OptionGroup(parser, "module options") group.add_option("-f", dest="flip", action="store_true") parser.add_option_group(group) def cli_callback ( opts, args ): if opts.flip: print "flip" opts, args = parser.delayed_parse_args ( cli_callback ) 

main.py

 import module import optparse myparser = optparse.OptionParser() mygroup = optparse.OptionGroup(myparser, "main options") mygroup.add_option("-j", dest="jump", action="store_true") myparser.add_option_group(mygroup) opts, args = myparser.parse_args() if opts.jump: print "jump" 

calling main.py program leads to the following outputs:

python main.py --help

 Usage: main.py [options] Options: -h, --help show this help message and exit module options: -f main options: -j 

python main.py -j -f

 flip jump 
0
source

All Articles