Export to GitHub

argparse - issue #52

Use-case for disable_interspersed_args


Posted on Dec 28, 2009 by Quick Giraffe

In short, is there a way that I can emulate the disable_interspersed_args behavior from optparse?

Long form:

I've been happily converting my applications from optparse to argpase and have enjoyed the improvements to the interface provided to my users and the clearer and more concise code. However, I've run into a use-case with an application that uses the optparse "disable_interspersed_args" feature to implement "lazy" command-line sub-parsers for a plug-in based architecture.
By "lazy", I mean that the main parser and application has no knowledge of the sub-components and thus cannot instantiate a sub-parser prior to parsing. Also, there are hundreds of sub-parsers and the cost of importing each plug-in and instantiating the sub-parser would be extreme.

Specifically, the launcher app parses some local options:

parser = ... parser.disable_interspersed_args() launcher_options,args = parser.parse_args()

The first positional argument, args[0], is the command designator. For Python plug-ins, it then sets sys.argv[:] to args and then runs the sub- module "main" function, which creates a standalone option parser.

There are several reasons why I cannot easily convert this application to use argparse-style sub-parsers. The most important is that there are dozens of built-in sub-modules and hundreds of user-supplied sub-modules each with a large number of imports and accepting diverse parameters.
Since plug-ins are provided as a package or single-file in a fixed path, my launcher application would have to import each one to obtain a sub-parser.
For a long-running service, this sort of plug-in discovery would be a negligible overhead, but it would add seconds of latency to an interactive process.

Obviously, I can continue to use optparse for the launcher and convert the
built-in modules to argparse. I figured it was worth a try to see if there is a way to emulating disable_interspersed_args, since it would be nice to use one uniform argument parser implementation.

Comment #1

Posted on Jan 7, 2010 by Grumpy Rabbit

Have you tried parser.parse_known_args()?

Another option is an undocumented feature in the repository, argparse.REMAINDER:

parser = argparse.ArgumentParser(prog='PROG') parser.add_argument('command') parser.add_argument('args', nargs=argparse.REMAINDER) print parser.parse_args()

At the command line:

$ prog.py X --foo B Namespace(args=['--foo', 'B'], command='X')

This could become a documented feature if it solves your problem cleanly. Let me know.

Comment #2

Posted on Feb 28, 2010 by Grumpy Rabbit

(No comment was entered for this change.)

Comment #3

Posted on Jul 23, 2010 by Grumpy Rabbit

(No comment was entered for this change.)

Comment #4

Posted on Jul 12, 2011 by Grumpy Ox

I had the same problem and used the argparse.REMAINDER solution and it worked great. Adding this to the documentation would be very helpful.

Status: Invalid

Labels:
Type-Enhancement Priority-Medium