Discussion:
gnulib-tool.py argument parsing
(too old to reply)
Bruno Haible
2017-09-08 21:44:41 UTC
Permalink
Raw Message
Hi Dmitry,

I'm banging my head against this:

$ ./gnulib-tool.py --test dirent
<works, creates a temporary directory>

$ ./gnulib-tool.py --test --destdir=../testdir-dirent dirent
usage: gnulib-tool.py --help
./gnulib-tool.py: error: unrecognized arguments: dirent

The argument parsing conventions for POSIX/GNU programs distinguish
* option with 0 or 1 arguments,
* non-option arguments.
In strict POSIX and in gnulib-tool, the non-option arguments come last,
that is, the user is not allowed to write

$ ./gnulib-tool.py dirent --test --destdir=../testdir-dirent
or
$ ./gnulib-tool.py --test dirent --destdir=../testdir-dirent

I'm fine with argument reordering, that is, to *allow* different ways
of specifying the arguments. But gnulib-tool.py is currently *forcing*
a specific argument order which is
1. invalid for gnulib-tool
2. not according to strict POSIX.
Namely, it *forces* the syntax
$ ./gnulib-tool.py --test dirent --destdir=../testdir-dirent
or
$ ./gnulib-tool.py --destdir=../testdir-dirent --test dirent


This "unrecognized arguments" error is explained in
https://stackoverflow.com/questions/12818146/

So, I think the fix will be to

1) replace the line
cmdargs = parser.parse_args()
with
cmdargs, nonoption_args = parser.parse_known_args()

2) Revisit all uses of nargs='+' and nargs='*'.

Bruno
Dmitry Selyutin
2017-09-09 10:21:52 UTC
Permalink
Raw Message
Hi Bruno,

to be honest, the command-line parsing in the gnulib-tool.py certainly
sucks.
I'm creating a new command-line parser from the scratch, and it works like
charm.
For example, it is much easier to avoid the error you described.
I'll take a look on how to fix the current parser and try to come up with
patch.
I guess there will be a lot of such errors until we switch to a new parser
though.

P.S. Frankly some of this errors are caused by the original solution.
I mean that some of the options (e.g. "modes", like --list, --import, etc.)
are not really options.
It was quite difficult to teach arparse to understand which options can be
combined and which not.

2017-09-09 0:44 GMT+03:00 Bruno Haible <***@clisp.org>:

> Hi Dmitry,
>
> I'm banging my head against this:
>
> $ ./gnulib-tool.py --test dirent
> <works, creates a temporary directory>
>
> $ ./gnulib-tool.py --test --destdir=../testdir-dirent dirent
> usage: gnulib-tool.py --help
> ./gnulib-tool.py: error: unrecognized arguments: dirent
>
> The argument parsing conventions for POSIX/GNU programs distinguish
> * option with 0 or 1 arguments,
> * non-option arguments.
> In strict POSIX and in gnulib-tool, the non-option arguments come last,
> that is, the user is not allowed to write
>
> $ ./gnulib-tool.py dirent --test --destdir=../testdir-dirent
> or
> $ ./gnulib-tool.py --test dirent --destdir=../testdir-dirent
>
> I'm fine with argument reordering, that is, to *allow* different ways
> of specifying the arguments. But gnulib-tool.py is currently *forcing*
> a specific argument order which is
> 1. invalid for gnulib-tool
> 2. not according to strict POSIX.
> Namely, it *forces* the syntax
> $ ./gnulib-tool.py --test dirent --destdir=../testdir-dirent
> or
> $ ./gnulib-tool.py --destdir=../testdir-dirent --test dirent
>
>
> This "unrecognized arguments" error is explained in
> https://stackoverflow.com/questions/12818146/
>
> So, I think the fix will be to
>
> 1) replace the line
> cmdargs = parser.parse_args()
> with
> cmdargs, nonoption_args = parser.parse_known_args()
>
> 2) Revisit all uses of nargs='+' and nargs='*'.
>
> Bruno
>
>


--
With best regards,
Dmitry Selyutin
Loading...