Tadek Kijkowski <tkijkow...@gmail.com> added the comment:

> So in the big picture, the purpose of this change is to treat the inputs like 
> a kind of state-machine.

Not necessarily that. Simple parsers should be easy to write, complicated 
parsers should be _possible_ to write. Users should be able to do whatever they 
wish by providing custom actions. Like writing Conway's Life in Excel or 
building Turing Machine using bricks and conveyors. Problem with positional 
parameter is a blocker. Fact that you can: 1. mix positional parameters with 
options in general, 2. have unlimited number of positional parameters, but 3. 
can't have 1 and 2 at the same time, makes great number of things impossible. 
For me that looks like a bug, not a feature.

Capture actions are second priority for me, because if this PR goes through, 
user will be able to write his own actions.

> While the proposed change to the core parser is (apparently) minor, it does 
> occur at the center of the action. That is not the place we want any (new) 
> bugs or backward incompatibility.

The core change is apparently minor, and also actually minor. It boils out to 
this:

@@ -2010,17 +2020,23 @@ def consume_positionals(start_index):
             match_partial = self._match_arguments_partial
             selected_pattern = arg_strings_pattern[start_index:]
             arg_counts = match_partial(positionals, selected_pattern)
+            action_index = 0

             # slice off the appropriate arg strings for each Positional
             # and add the Positional and its args to the list
-            for action, arg_count in zip(positionals, arg_counts):
+            for arg_count in arg_counts:
+                action = positionals[action_index]
                 args = arg_strings[start_index: start_index + arg_count]
                 start_index += arg_count
                 take_action(action, args)
+                # if positional action nargs is '**',
+                # never remove it from actions list
+                if action.nargs != AS_MANY_AS_POSSIBLE:
+                    action_index += 1

             # slice off the Positionals that we just parsed and return the
             # index at which the Positionals' string args stopped
-            positionals[:] = positionals[len(arg_counts):]
+            positionals[:] = positionals[action_index:]
             return start_index

It's not hard to determine that if all action.nargs != AS_MANY_AS_POSSIBLE, old 
and new code do exactly the same.
Besides that's what tests and code review is for. As for backward 
compatibility, nargs='**' was illegal until now,
and for all parameters with nargs!='**' the code behaves exactly as before.

> And the full implementation requires a new Action subclass that is quite 
> different from existing ones.

No, that's an extra. That's why it's separate issue and separate PR. This issue 
is about giving users ability to write their own actions.

> Given how different this is from the normal argparse parsing (and the POSIX 
> parsing argparse seeks to emulate), I question the wisdom of adding this, in 
> part or whole, to the stock distribution.  It could certainly be published as 
> a pypi.  That already has a number of  parsers, some built on argparse, 
> others stand alone.
>
> I also wonder whether it would be simpler to do this kind of parsing directly 
> from sys.argv.  Just step through that list, consuming the values and flags 
> in sequence.

In other words, "if argparse doesn't meet your requirements, you can write your 
own parser". I don't think that's the way to go.

Both GNU getopt and GNU argp_parse allow mixing options with positional 
arguments without reordering. For getopt it's: options argument string begins 
with a hyphen, for argp_parse it's ARGP_IN_ORDER flag. I don't see why argparse 
wouldn't allow that. Original POSIX getopt didn't even have longopts.

> Sorry to sound like a wet blanket, but I've seen too many seemingly innocent 
> patches that caused unforeseen problems down the line.

Yeah, that can be said about any project at any time - changes can introduce 
bugs, so let's just keep it as it is. I appreciate your ideas, but your 
criticism does sound unsubstantiated: "POSIX getopts didn't have it", "it can 
be done on pypi", "enhancements introduce bugs".

I think this change should be applied, because it is small change in code which 
removes significant obstacle in writing advanced option parsers.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue42973>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to