Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The relevant Python bug is <a href="http://bugs.python.org/issue15112" rel="noreferrer">Issue 15112</a>.</p> <blockquote> <p><code>argparse: nargs='*'</code> positional argument doesn't accept any items if preceded by an option and another positional</p> </blockquote> <p>When argparse parses <code>['1', '2', '--spam', '8', '8', '9']</code> it first tries to match <code>['1','2']</code> with as many of the positional arguments as possible. With your arguments the pattern matching string is <code>AAA*</code>: 1 argument each for <code>pos</code> and <code>foo</code>, and zero arguments for <code>vars</code> (remember <code>*</code> means ZERO_OR_MORE). </p> <p><code>['--spam','8']</code> are handled by your <code>--spam</code> argument. Since <code>vars</code> has already been set to <code>[]</code>, there is nothing left to handle <code>['8','9']</code>.</p> <p>The programming change to <code>argparse</code> checks for the case where <code>0</code> argument strings is satisfying the pattern, but there are still <code>optionals</code> to be parsed. It then defers the handling of that <code>*</code> argument.</p> <p>You might be able to get around this by first parsing the input with <a href="https://docs.python.org/3.6/library/argparse.html#argparse.ArgumentParser.parse_known_args" rel="noreferrer"><code>parse_known_args</code></a>, and then handling the <code>remainder</code> with another call to <a href="https://docs.python.org/3.6/library/argparse.html#argparse.ArgumentParser.parse_args" rel="noreferrer"><code>parse_args</code></a>.</p> <p>To have complete freedom in interspersing optionals among positionals, in <a href="http://bugs.python.org/issue14191" rel="noreferrer">issue 14191</a>, I propose using <code>parse_known_args</code> with just the <code>optionals</code>, followed by a <code>parse_args</code> that only knows about the positionals. The <code>parse_intermixed_args</code> function that I posted there could be implemented in an <code>ArgumentParser</code> subclass, without modifying the <code>argparse.py</code> code itself.</p> <hr> <p>Here's a way of handling subparsers. I've taken the <a href="http://bugs.python.org/file30422/intermixed.patch" rel="noreferrer"><code>parse_known_intermixed_args</code></a> function, simplified it for presentation sake, and then made it the <code>parse_known_args</code> function of a Parser subclass. I had to take an extra step to avoid recursion. </p> <p>Finally I changed the <code>_parser_class</code> of the subparsers Action, so each subparser uses this alternative <code>parse_known_args</code>. An alternative would be to subclass <code>_SubParsersAction</code>, possibly modifying its <code>__call__</code>.</p> <pre><code>from argparse import ArgumentParser def parse_known_intermixed_args(self, args=None, namespace=None): # self - argparse parser # simplified from http://bugs.python.org/file30204/test_intermixed.py parsefn = super(SubParser, self).parse_known_args # avoid recursion positionals = self._get_positional_actions() for action in positionals: # deactivate positionals action.save_nargs = action.nargs action.nargs = 0 namespace, remaining_args = parsefn(args, namespace) for action in positionals: # remove the empty positional values from namespace if hasattr(namespace, action.dest): delattr(namespace, action.dest) for action in positionals: action.nargs = action.save_nargs # parse positionals namespace, extras = parsefn(remaining_args, namespace) return namespace, extras class SubParser(ArgumentParser): parse_known_args = parse_known_intermixed_args parser = ArgumentParser() parser.add_argument('foo') sp = parser.add_subparsers(dest='cmd') sp._parser_class = SubParser # use different parser class for subparsers spp1 = sp.add_parser('cmd1') spp1.add_argument('-x') spp1.add_argument('bar') spp1.add_argument('vars',nargs='*') print parser.parse_args('foo cmd1 bar -x one 8 9'.split()) # Namespace(bar='bar', cmd='cmd1', foo='foo', vars=['8', '9'], x='one') </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload