rcmdnk's blog

An Illustrated Book of Bad Arguments

There was a messy point in my Python script: Brew-file, related with ArgumentParser.

In this post, the problem and how I addressed are written.

Sponsored Links

parse_known_args in ArgumentParser

ArguentParser is a module to analyze arguments, like this:

1
2
3
4
5
6
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument("-a", "--aaa", action="store", dest="aaa")
>>> ns = parser.parse_args(['-a', 'test'])
>>> print ns
Namespace(aaa='test')

In the script, if it is called without argument, it returns the arguments to the script in the form of Namespace object.

If other values than what are defined by add_argument, it gives an error:

1
2
3
>>> ns = parser.parse_args(['-a', 'test', '-b'])
usage: [-h] [-a AAA]
: error: unrecognized arguments: -b

If you want to give such file names, and want to use variadic arguments, use parse_known_args instead of parse_args.

1
2
3
4
5
>>> (ns, args) = parser.parse_known_args(['-a', 'test', '-b'])
Namespace(aaa='test')
>>> print args
['-b']
>>>

parse_known_args returns the analyzed results and remaining arguments as an array.

ArgumentParser’s subparsers

ArgumentParser has a function of subparsers.

1
2
3
4
5
6
7
8
9
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument("-a", "--aaa", action="store", dest="aaa")
>>> subparsers = parser.add_subparsers()
>>> subparser0 = subparsers.add_parser("bbb")
>>> subparser0.add_argument("-c", "--ccc", action="store", dest="ccc")
>>> ns = parser.parse_args(['bbb', '-c', 'subparsertest'])
>>> print ns
Namespace(aaa=None, ccc='subparsertest')

Like this, if it finds subperser, it starts child parsing for bbb.

Here, in Python 2.7.7 and later, if unknown arguments are given, parse_known_args can analyze as above.

But for Python 2.7.6 and earlier, it shows an error:

1
2
3
>>> (ns, args) = parser.parse_known_args(['bbb', '-c', 'subparsertest', 'X'])
usage: [-h] [-a AAA] {bbb} ...
: error: unrecognized arguments: X

The problem is that OS X Yosemite’s default Python is 2.7.6. And Brew-file’s brew command uses this function.

Therefore, if you want to use brew file brew command, you need to install Python 2.7.7 or later, or Python 3.X.

Fix at Brew-file

Actually, it affects only on brew command in Brew-file. Therefore, I ignore it for now in Brew-file. (It will give an error if you use brew command with Python 2.7.6.)

In addition, /etc/brew-wrap wraps default brew command. For such brew install command, it wraps as brew file brew install ....

It should not be used with Python 2.7.6, therefore the wrapper function was modified for that it wraps only when newer Python is available.

updated brew-wrap: avoid to use wrap for python 2.7.6 (OSX default) or … · 64693b2 · rcmdnk/homebrew-file

Sponsored Links
Sponsored Links

« Many duplicated directories appear in Dock's Home pop-up Brew-file update: completion, wrapper commands »