Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #45326 > unrolled thread

Determine actually given command line arguments

Started byHenry Leyh <henry.leyh@ipp.mpg.de>
First post2013-05-15 08:34 +0200
Last post2013-05-16 09:29 +0200
Articles 16 — 9 participants

Back to article view | Back to comp.lang.python


Contents

  Determine actually given command line arguments Henry Leyh <henry.leyh@ipp.mpg.de> - 2013-05-15 08:34 +0200
    Re: Determine actually given command line arguments "Colin J. Williams" <cjw@ncf.ca> - 2013-05-15 08:03 -0400
      Re: Determine actually given command line arguments Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-05-15 15:51 +0300
    Re: Determine actually given command line arguments Roy Smith <roy@panix.com> - 2013-05-15 08:24 -0400
      Re: Determine actually given command line arguments Dave Angel <davea@davea.name> - 2013-05-15 08:51 -0400
      Re: Determine actually given command line arguments Henry Leyh <henry.leyh@ipp.mpg.de> - 2013-05-15 14:52 +0200
        Re: Determine actually given command line arguments Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2013-05-15 14:00 +0100
          Re: Determine actually given command line arguments Henry Leyh <henry.leyh@ipp.mpg.de> - 2013-05-15 15:50 +0200
            Re: Determine actually given command line arguments Skip Montanaro <skip@pobox.com> - 2013-05-15 09:08 -0500
              Re: Determine actually given command line arguments Henry Leyh <henry.leyh@ipp.mpg.de> - 2013-05-15 16:39 +0200
                Re: Determine actually given command line arguments Skip Montanaro <skip@pobox.com> - 2013-05-15 09:51 -0500
            Re: Determine actually given command line arguments Wayne Werner <wayne@waynewerner.com> - 2013-05-15 09:16 -0500
        Re: Determine actually given command line arguments roy@panix.com (Roy Smith) - 2013-05-15 11:29 -0400
          Re: Determine actually given command line arguments Henry Leyh <henry.leyh@ipp.mpg.de> - 2013-05-16 07:43 +0200
            Re: Determine actually given command line arguments Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2013-05-16 09:08 +0300
              Re: Determine actually given command line arguments Henry Leyh <henry.leyh@ipp.mpg.de> - 2013-05-16 09:29 +0200

#45326 — Determine actually given command line arguments

FromHenry Leyh <henry.leyh@ipp.mpg.de>
Date2013-05-15 08:34 +0200
SubjectDetermine actually given command line arguments
Message-ID<kmva9j$1hbk$1@gwdu112.gwdg.de>
Hello,
I am writing a program that gets its parameters from a combination of 
config file (using configparser) and command line arguments (using 
argparse).  Now I would also like the program to be able to _write_ a 
configparser config file that contains only the parameters actually 
given on the commandline.  Is there a simple way to determine which 
command line arguments were actually given on the commandline, i.e. does 
argparse.ArgumentParser() know which of its namespace members were 
actually hit during parse_args().

I have tried giving the arguments default values and then looking for 
those having a non-default value but this is really awkward, especially 
if it comes to non-string arguments.  Also, parsing sys.argv looks 
clumsy because you have to keep track of short and long options with and 
without argument etc. i.e. all things that I got argparse for in the 
first place.

Thanks && Greetings,
Henry

[toc] | [next] | [standalone]


#45332

From"Colin J. Williams" <cjw@ncf.ca>
Date2013-05-15 08:03 -0400
Message-ID<kmvtj0$gbq$1@theodyn.ncf.ca>
In reply to#45326
On 15/05/2013 2:34 AM, Henry Leyh wrote:
> Hello,
> I am writing a program that gets its parameters from a combination of
> config file (using configparser) and command line arguments (using
> argparse).  Now I would also like the program to be able to _write_ a
> configparser config file that contains only the parameters actually
> given on the commandline.  Is there a simple way to determine which
> command line arguments were actually given on the commandline, i.e. does
> argparse.ArgumentParser() know which of its namespace members were
> actually hit during parse_args().
>
> I have tried giving the arguments default values and then looking for
> those having a non-default value but this is really awkward, especially
> if it comes to non-string arguments.  Also, parsing sys.argv looks
> clumsy because you have to keep track of short and long options with and
> without argument etc. i.e. all things that I got argparse for in the
> first place.
>
> Thanks && Greetings,
> Henry
Try sys.argv

Colin W.

[toc] | [prev] | [next] | [standalone]


#45337

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2013-05-15 15:51 +0300
Message-ID<qothai42yp2.fsf@ruuvi.it.helsinki.fi>
In reply to#45332
Colin J. Williams writes:

> On 15/05/2013 2:34 AM, Henry Leyh wrote:
> > Hello,

> > I am writing a program that gets its parameters from a combination
> > of config file (using configparser) and command line arguments
> > (using argparse).  Now I would also like the program to be able to
> > _write_ a configparser config file that contains only the
> > parameters actually given on the commandline.  Is there a simple
> > way to determine which command line arguments were actually given
> > on the commandline, i.e. does argparse.ArgumentParser() know which
> > of its namespace members were actually hit during parse_args().
> >
> > I have tried giving the arguments default values and then looking
> > for those having a non-default value but this is really awkward,
> > especially if it comes to non-string arguments.  Also, parsing
> > sys.argv looks clumsy because you have to keep track of short and
> > long options with and without argument etc. i.e. all things that I
> > got argparse for in the first place.
> >
> > Thanks && Greetings,
> > Henry

> Try sys.argv

You people should read what you quote, or what you don't quote when
you cut the relevant portion.

Q. ... parsing sys.argv looks clumsy because  ...
A. Try sys.argv

I mean, huh?

[toc] | [prev] | [next] | [standalone]


#45336

FromRoy Smith <roy@panix.com>
Date2013-05-15 08:24 -0400
Message-ID<roy-C8F8F4.08245415052013@news.panix.com>
In reply to#45326
In article <kmva9j$1hbk$1@gwdu112.gwdg.de>,
 Henry Leyh <henry.leyh@ipp.mpg.de> wrote:

> Is there a simple way to determine which 
> command line arguments were actually given on the commandline, i.e. does 
> argparse.ArgumentParser() know which of its namespace members were 
> actually hit during parse_args().

I think what you're looking for is sys.argv:

$ cat argv.py
import sys
print sys.argv

$ python argv.py foo bar
['argv.py', 'foo', 'bar']

[toc] | [prev] | [next] | [standalone]


#45338

FromDave Angel <davea@davea.name>
Date2013-05-15 08:51 -0400
Message-ID<mailman.1696.1368622312.3114.python-list@python.org>
In reply to#45336
On 05/15/2013 08:24 AM, Roy Smith wrote:
> In article <kmva9j$1hbk$1@gwdu112.gwdg.de>,
>   Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
>
>> Is there a simple way to determine which
>> command line arguments were actually given on the commandline, i.e. does
>> argparse.ArgumentParser() know which of its namespace members were
>> actually hit during parse_args().
>
> I think what you're looking for is sys.argv:
>
> $ cat argv.py
> import sys
> print sys.argv
>
> $ python argv.py foo bar
> ['argv.py', 'foo', 'bar']
>

Colin & Roy:
The OP mentioned sys.argv in his original query.

-- 
DaveA

[toc] | [prev] | [next] | [standalone]


#45339

FromHenry Leyh <henry.leyh@ipp.mpg.de>
Date2013-05-15 14:52 +0200
Message-ID<kn00fb$8kc$1@gwdu112.gwdg.de>
In reply to#45336
On 15.05.2013 14:24, Roy Smith wrote:
> In article <kmva9j$1hbk$1@gwdu112.gwdg.de>,
>   Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
>
>> Is there a simple way to determine which
>> command line arguments were actually given on the commandline, i.e. does
>> argparse.ArgumentParser() know which of its namespace members were
>> actually hit during parse_args().
>
> I think what you're looking for is sys.argv:
>
> $ cat argv.py
> import sys
> print sys.argv
>
> $ python argv.py foo bar
> ['argv.py', 'foo', 'bar']

Thanks, but as I wrote in my first posting I am aware of sys.argv and 
was hoping to _avoid_ using it because I'd then have to kind of 
re-implement a lot of the stuff already there in argparse, e.g. parsing 
sys.argv for short/long options, flag/parameter options etc.

I was thinking of maybe some sort of flag that argparse sets on those 
optional arguments created with add_argument() that are really given on 
the command line, i.e. those that it stumbles upon them during parse_args().

Regards,
Henry

[toc] | [prev] | [next] | [standalone]


#45340

FromOscar Benjamin <oscar.j.benjamin@gmail.com>
Date2013-05-15 14:00 +0100
Message-ID<mailman.1697.1368622878.3114.python-list@python.org>
In reply to#45339
On 15 May 2013 13:52, Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
> On 15.05.2013 14:24, Roy Smith wrote:
>>
>> In article <kmva9j$1hbk$1@gwdu112.gwdg.de>,
>>   Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
>>
>>> Is there a simple way to determine which
>>> command line arguments were actually given on the commandline, i.e. does
>>> argparse.ArgumentParser() know which of its namespace members were
>>> actually hit during parse_args().
>>
>>
>> I think what you're looking for is sys.argv:
>>
>> $ cat argv.py
>> import sys
>> print sys.argv
>>
>> $ python argv.py foo bar
>> ['argv.py', 'foo', 'bar']
>
> Thanks, but as I wrote in my first posting I am aware of sys.argv and was
> hoping to _avoid_ using it because I'd then have to kind of re-implement a
> lot of the stuff already there in argparse, e.g. parsing sys.argv for
> short/long options, flag/parameter options etc.
>
> I was thinking of maybe some sort of flag that argparse sets on those
> optional arguments created with add_argument() that are really given on the
> command line, i.e. those that it stumbles upon them during parse_args().

I don't know about that but I imagine that you could compare values
with their defaults to see which have been changed.


Oscar

[toc] | [prev] | [next] | [standalone]


#45341

FromHenry Leyh <henry.leyh@ipp.mpg.de>
Date2013-05-15 15:50 +0200
Message-ID<kn03rt$d74$1@gwdu112.gwdg.de>
In reply to#45340
On 15.05.2013 15:00, Oscar Benjamin wrote:
> On 15 May 2013 13:52, Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
>> On 15.05.2013 14:24, Roy Smith wrote:
>>>
>>> In article <kmva9j$1hbk$1@gwdu112.gwdg.de>,
>>>    Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
>>>
>>>> Is there a simple way to determine which
>>>> command line arguments were actually given on the commandline, i.e. does
>>>> argparse.ArgumentParser() know which of its namespace members were
>>>> actually hit during parse_args().
>>>
>>>
>>> I think what you're looking for is sys.argv:
>>>
>>> $ cat argv.py
>>> import sys
>>> print sys.argv
>>>
>>> $ python argv.py foo bar
>>> ['argv.py', 'foo', 'bar']
>>
>> Thanks, but as I wrote in my first posting I am aware of sys.argv and was
>> hoping to _avoid_ using it because I'd then have to kind of re-implement a
>> lot of the stuff already there in argparse, e.g. parsing sys.argv for
>> short/long options, flag/parameter options etc.
>>
>> I was thinking of maybe some sort of flag that argparse sets on those
>> optional arguments created with add_argument() that are really given on the
>> command line, i.e. those that it stumbles upon them during parse_args().
>
> I don't know about that but I imagine that you could compare values
> with their defaults to see which have been changed.

Yes, I was trying that and it sort of works with strings if I use 
something sufficiently improbable like "__UNSELECTED__" as default.  But 
it gets difficult with boolean or even number arguments where you just 
may not have valid "improbable" defaults.  You could now say, so what, 
it's the default anyway.  But in my program I would like to distinguish 
between given and not given arguments rather than between default and 
non-default.

Regards,
Henry

[toc] | [prev] | [next] | [standalone]


#45343

FromSkip Montanaro <skip@pobox.com>
Date2013-05-15 09:08 -0500
Message-ID<mailman.1699.1368626900.3114.python-list@python.org>
In reply to#45341
> Yes, I was trying that and it sort of works with strings if I use something sufficiently improbable like "__UNSELECTED__" as default.  But it gets difficult with boolean or even number arguments where you just may not have valid "improbable" defaults.  You could now say, so what, it's the default anyway.  But in my program I would like to distinguish between given and not given arguments rather than between default and non-default.

Initialize all your arg variables to None, then after command line
processing, any which remain as None weren't set on the command line.
At that point, set them to the actual defaults.  I think that's a
pretty common idiom.

Note: I am an old cranky dude and still use getopt.  This idiom is
pretty easy there.  YMMV with argparse or optparse.

Skip

[toc] | [prev] | [next] | [standalone]


#45349

FromHenry Leyh <henry.leyh@ipp.mpg.de>
Date2013-05-15 16:39 +0200
Message-ID<kn06nv$glc$1@gwdu112.gwdg.de>
In reply to#45343
On 15.05.2013 16:08, Skip Montanaro wrote:
>> Yes, I was trying that and it sort of works with strings if I use something sufficiently improbable like "__UNSELECTED__" as default.  But it gets difficult with boolean or even number arguments where you just may not have valid "improbable" defaults.  You could now say, so what, it's the default anyway.  But in my program I would like to distinguish between given and not given arguments rather than between default and non-default.
>
> Initialize all your arg variables to None, then after command line
> processing, any which remain as None weren't set on the command line.
> At that point, set them to the actual defaults.  I think that's a
> pretty common idiom.
>
> Note: I am an old cranky dude and still use getopt.  This idiom is
> pretty easy there.  YMMV with argparse or optparse.

Unfortunately, argparse wants to know the type of the argument and the 
boolean arguments (those with action=store_true) can't be initialized 
with None.

However, maybe I could convert boolean arguments to something like

   parser.add_argument('--foo', type=str, nargs='?', const='True', 
default=None)

I'd then have to check for string 'True' rather than for boolean True, 
though.

Regards,
Henry

[toc] | [prev] | [next] | [standalone]


#45351

FromSkip Montanaro <skip@pobox.com>
Date2013-05-15 09:51 -0500
Message-ID<mailman.1703.1368629512.3114.python-list@python.org>
In reply to#45349
> However, maybe I could ...

... switch to getopt? <wink>

Skip

[toc] | [prev] | [next] | [standalone]


#45345

FromWayne Werner <wayne@waynewerner.com>
Date2013-05-15 09:16 -0500
Message-ID<mailman.1701.1368627442.3114.python-list@python.org>
In reply to#45341
On Wed, 15 May 2013, Henry Leyh wrote:
> Yes, I was trying that and it sort of works with strings if I use something 
> sufficiently improbable like "__UNSELECTED__" as default.  But it gets 
> difficult with boolean or even number arguments where you just may not have 
> valid "improbable" defaults.  You could now say, so what, it's the default 
> anyway.  But in my program I would like to distinguish between given and not 
> given arguments rather than between default and non-default.

Have you looked into docopt? It's pretty awesome, and might really help in 
this case.

HTH,
-W

[toc] | [prev] | [next] | [standalone]


#45353

Fromroy@panix.com (Roy Smith)
Date2013-05-15 11:29 -0400
Message-ID<kn09ke$kkf$1@panix2.panix.com>
In reply to#45339
In article <kn00fb$8kc$1@gwdu112.gwdg.de>,
Henry Leyh  <henry.leyh@ipp.mpg.de> wrote:
>On 15.05.2013 14:24, Roy Smith wrote:
>> In article <kmva9j$1hbk$1@gwdu112.gwdg.de>,
>>   Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
>>
>>> Is there a simple way to determine which
>>> command line arguments were actually given on the commandline, i.e. does
>>> argparse.ArgumentParser() know which of its namespace members were
>>> actually hit during parse_args().
>>
>> I think what you're looking for is sys.argv:
>>
>> $ cat argv.py
>> import sys
>> print sys.argv
>>
>> $ python argv.py foo bar
>> ['argv.py', 'foo', 'bar']
>
>Thanks, but as I wrote in my first posting I am aware of sys.argv and 
>was hoping to _avoid_ using it because I'd then have to kind of 
>re-implement a lot of the stuff already there in argparse, e.g. parsing 
>sys.argv for short/long options, flag/parameter options etc.

Sorry, I missed that.

I'm not clear on exactly what you're trying to do.  You say:

> Now I would also like the program to be able to _write_ a 
> configparser config file that contains only the parameters actually 
> given on the commandline. 

I'm guessing what you're trying to do is parse the command line first,
then anything that was set there can get overridden by a value in the
config file?  That seems backwards.  Usually, the order is:

1) built-in default
2) config file (possibly a system config file, then a per-user one)
3) environment variable
4) command-line argument

It sounds like you're doing it in the reverse order -- allowing the
config file to override the command line.

[toc] | [prev] | [next] | [standalone]


#45401

FromHenry Leyh <henry.leyh@ipp.mpg.de>
Date2013-05-16 07:43 +0200
Message-ID<kn1rme$2cq2$1@gwdu112.gwdg.de>
In reply to#45353
On 15.05.2013 17:29, Roy Smith wrote:
> In article <kn00fb$8kc$1@gwdu112.gwdg.de>,
> Henry Leyh  <henry.leyh@ipp.mpg.de> wrote:
>> On 15.05.2013 14:24, Roy Smith wrote:
>>> In article <kmva9j$1hbk$1@gwdu112.gwdg.de>,
>>>    Henry Leyh <henry.leyh@ipp.mpg.de> wrote:
>>>
>>>> Is there a simple way to determine which
>>>> command line arguments were actually given on the commandline, i.e. does
>>>> argparse.ArgumentParser() know which of its namespace members were
>>>> actually hit during parse_args().
>>>
>>> I think what you're looking for is sys.argv:
>>>
>>> $ cat argv.py
>>> import sys
>>> print sys.argv
>>>
>>> $ python argv.py foo bar
>>> ['argv.py', 'foo', 'bar']
>>
>> Thanks, but as I wrote in my first posting I am aware of sys.argv and
>> was hoping to _avoid_ using it because I'd then have to kind of
>> re-implement a lot of the stuff already there in argparse, e.g. parsing
>> sys.argv for short/long options, flag/parameter options etc.
>
> Sorry, I missed that.
>
> I'm not clear on exactly what you're trying to do.  You say:
>
>> Now I would also like the program to be able to _write_ a
>> configparser config file that contains only the parameters actually
>> given on the commandline.
>
> I'm guessing what you're trying to do is parse the command line first,
> then anything that was set there can get overridden by a value in the
> config file?  That seems backwards.  Usually, the order is:
>
> 1) built-in default
> 2) config file (possibly a system config file, then a per-user one)
> 3) environment variable
> 4) command-line argument
>
> It sounds like you're doing it in the reverse order -- allowing the
> config file to override the command line.

No.  The program reads a general config file in $HOME, something like 
~/.programrc; then parses the command like for '-c FILE' and, if FILE is 
present reads it; then parses the command line remains for more 
arguments which overwrite everything previously set.  (For the record, 
this split parsing is done with two argparse parsers.  The first parses 
for '-c FILE' with parse_known_args().  If there is a FILE, its contents 
is used as defaults for a second parser (using set_options()) which then 
parses the remains that were returned by the first parser's 
parse_known_args().)

But now I would also like to be able to _write_ such a config file FILE 
that can be read in a later run.  And FILE should contain only those 
arguments that were given on the command line.

Say, I tell argparse to look for arguments -s|--sopt STRING, -i|--iopt 
INT, -b|--bopt [BOOL], -C CONFFILE.  Then 'prog -s bla -i 42 -C cfile' 
should produce a confparser compatible cfile which contains

   [my_options]
   sopt = blah
   iopt = 42

and not 'bopt = False' (if False was the program's default for bopt).

Regards,
Henry

[toc] | [prev] | [next] | [standalone]


#45403

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2013-05-16 09:08 +0300
Message-ID<qot7gizmp76.fsf@ruuvi.it.helsinki.fi>
In reply to#45401
Henry Leyh writes:

> But now I would also like to be able to _write_ such a config file
> FILE that can be read in a later run.  And FILE should contain only
> those arguments that were given on the command line.
> 
> Say, I tell argparse to look for arguments -s|--sopt STRING,
> -i|--iopt INT, -b|--bopt [BOOL], -C CONFFILE.  Then 'prog -s bla -i
> 42 -C cfile' should produce a confparser compatible cfile which
> contains
> 
>    [my_options]
>    sopt = blah
>    iopt = 42
> 
> and not 'bopt = False' (if False was the program's default for
> bopt).

Could you instead write those options that differ from the defaults?
You could parse an actual command line and an empty command line, and
work out the difference.

So 'prog -i 3' would not cause 'iopt = 3' to be written if 3 is the
default for iopt, but would that be a problem?

[toc] | [prev] | [next] | [standalone]


#45409

FromHenry Leyh <henry.leyh@ipp.mpg.de>
Date2013-05-16 09:29 +0200
Message-ID<kn21te$2jis$1@gwdu112.gwdg.de>
In reply to#45403
On 16.05.2013 08:08, Jussi Piitulainen wrote:
> Henry Leyh writes:
>
>> But now I would also like to be able to _write_ such a config file
>> FILE that can be read in a later run.  And FILE should contain only
>> those arguments that were given on the command line.
>>
>> Say, I tell argparse to look for arguments -s|--sopt STRING,
>> -i|--iopt INT, -b|--bopt [BOOL], -C CONFFILE.  Then 'prog -s bla -i
>> 42 -C cfile' should produce a confparser compatible cfile which
>> contains
>>
>>     [my_options]
>>     sopt = blah
>>     iopt = 42
>>
>> and not 'bopt = False' (if False was the program's default for
>> bopt).
>
> Could you instead write those options that differ from the defaults?
> You could parse an actual command line and an empty command line, and
> work out the difference.
>
> So 'prog -i 3' would not cause 'iopt = 3' to be written if 3 is the
> default for iopt, but would that be a problem?

That's what the program does at the moment.  However, I'm not quite 
happy with it.  Generally, the user doesn't know what's the default and 
it would be confusing if 'prog -i 3' doesn't make 'iopt = 3' turn up in 
the file at the end.  There may also be the case when the user (for 
whatever reason) _wants_ the default in the file.

I think I will try the opposite instead: the program writes the whole 
set of options to the file.  This would produce a complete and 
consistent configuration which automatically reflects the hierarchy in 
which the options were set.  And the user can sort it out by hand if he 
wants.

Regards,
Henry

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web