Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

optparse - why the last char of the option can be ignored? With `--file` it behaves same as `--fil`

Here is simple example of code:

from optparse import OptionParser

parser = OptionParser()
parser.add_option("-f", "--file", dest="filename")

(options, args) = parser.parse_args()
print options

I have saved it to file and run. It works:

$ python script.py --file some_name
{'filename': 'some_name'}

But here is the trick:

$ python script.py --fil some_name
{'filename': 'some_name'}

It also works with undeclared option fil. Why it behaves in that way?

like image 882
dimadvk Avatar asked Apr 05 '16 14:04

dimadvk


1 Answers

You can see how optparse works by opening the optparse.py file in your python install.

On windows this was:

C:\Python27\Lib\optparse.py

The _match_abbrev function is on line 1675:

def _match_abbrev(s, wordmap):
    """_match_abbrev(s : string, wordmap : {string : Option}) -> string

    Return the string key in 'wordmap' for which 's' is an unambiguous
    abbreviation.  If 's' is found to be ambiguous or doesn't match any of
    'words', raise BadOptionError.
    """
    # Is there an exact match?
    if s in wordmap:
        return s
    else:
        # Isolate all words with s as a prefix.
        possibilities = [word for word in wordmap.keys()
                         if word.startswith(s)]
        # No exact match, so there had better be just one possibility.
        if len(possibilities) == 1:
            return possibilities[0]
        elif not possibilities:
            raise BadOptionError(s)
        else:
            # More than one possible completion: ambiguous prefix.
            possibilities.sort()
            raise AmbiguousOptionError(s, possibilities)

Which is called by _match_long_opt which is called by _process_long_opt

This appears to be documented in this section of the documentation:

opt_str

is the option string seen on the command-line that’s triggering the callback. (If an abbreviated long option was used, opt_str will be the full, canonical option string—e.g. if the user puts --foo on the command-line as an abbreviation for --foobar, then opt_str will be "--foobar".)

If we changed the example you have provided to:

from optparse import OptionParser

parser = OptionParser()
parser.disable_interspersed_args()
parser.add_option("-f", "--file", dest="filename")
parser.add_option("-z", "--film", dest="filmname")

(options, args) = parser.parse_args()
print options

With the test case of --fil, you get an error:

error: ambiguous option: --fil (--file, --film?)

So its ok to use shorter names but if there is any ambiguity optparse will stop.

like image 102
Noelkd Avatar answered Sep 30 '22 09:09

Noelkd