Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know if optparse option was passed in the command line or as a default

Using python optparse.py, is there a way to work out whether a specific option value was set from the command line or from the default value.

Ideally I would like to have a dict just like defaults, but containing the options actually supplied from command line

I know that you could compare the value for each option with defaults, but this wouldn't distinguish a value was passed through command line which matched the default.

Thanks!


EDIT

Sorry my original phrasing wasn't very clear.

I have a large number of scripts which are called from batch files. For audit purposes, I would like to report on the options being passed, and whether they are passed from command line, default, or some other means, to a log file.

Using defaults you can tell whether an option matches a default value, but that still doesn't tell you whether it was actually supplied from command line. This can be relevant: if an option is passed from command line and agrees with the default, if you then change the default in the code the script will still get the same value.

To me it would feel quite natural to have an equivalent to defaults, containing the values actually supplied.

To make the question concrete, in this example:

>>> sys.argv = ['myscript.py','-a','xxx']
>>> import optparse
>>> parser = optparse.OptionParser()
>>> parser.add_option('-a', default = 'xxx')
>>> parser.add_option('-b', default = 'yyy')

How do I know that option a was passed from command line. Is the only way to parse the command line manually?

(I know this is a fairly minor point, but I thought it would be worth asking in case I'm missing smthing on optparse)

Thanks again

like image 323
user265454 Avatar asked Apr 07 '10 14:04

user265454


2 Answers

Instead of the below boilerplate code:

opts, args = parser.parse_args()

if you use the below code, you will have an additional values object opts_no_defaults with options that were explicitly specified by the user:

opts_no_defaults = optparse.Values()
__, args = parser.parse_args(values=opts_no_defaults)
opts = Values(parser.get_default_values().__dict__)
opts._update_careful(opts_no_defaults.__dict__)

At the end, opts should be identical as in the initial boilerplate code.

print opts_no_defaults.__dict__
print opts.__dict__
for opt in parser._get_all_options():
    if opt.dest:
        print "Value of %s: %s" % (opt._long_opts[0], getattr(opts, opt.dest))
        print "Is %s specified by user? %s" % (opt._long_opts[0], hasattr(opt_no_defaults, opt.dest))
like image 65
Bruno Lenzi Avatar answered Sep 21 '22 14:09

Bruno Lenzi


Not knowing you code is impossible to give the better answer, but...

  1. simply don't pass defaults to the parser and check for None values. A None value is a default for optparse lib so you can retrieve your own default and act as usually;

  2. extend optparse to specialize it.

I don't know your program but usually it is not a good design changing behavior when the configuration is the same.

like image 37
mg. Avatar answered Sep 20 '22 14:09

mg.