2

MacOSX launchd passes the -psn... parameter to applications. How can I tell argparse how to parse the parameter? It's basically -psn_([0-9]+)_([0-9]+) but I'm fine if it just parses -psn(\S*). Is that possible at all?

(See here for some documentation about the Process Serial Number (PSN). And here is my question about what to do with the parameter.)

Community
  • 1
  • 1
Albert
  • 65,406
  • 61
  • 242
  • 386
  • Since it's deprecated, according to the documents, a clean way to handle it would be to ignore it, IMHO. What do you need to handle about the PSN, exactly? – Sven Oct 29 '13 at 15:55
  • @Sven: Well, the minimum handling would be to tell `argparse` somehow to ignore it but I even don't know how to do that (I'm not sure if this is possible at all). The next step would be to tell `argparse` to get the part after `-psn_` as the argument of this parameter. Then, the question about what to do with it, is [another one](http://stackoverflow.com/questions/19661637/psn-parameter-by-macosx-launchd-what-can-i-do-with-it). – Albert Oct 29 '13 at 18:22

2 Answers2

2

I don't know what other arguments you need (I use Linux), but how about this (from an interactive Ipython session):

In [3]: parser.add_argument('-p')
Out[3]: _StoreAction(option_strings=['-p'], dest='p', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

In [4]: parser.parse_args('-psn_123_455'.split())
Out[4]: Namespace(p='sn_123_455')

Then you can parse args.p as needed.

You can't use parser.add_argument('-psn') because only single letter options can have contiguous arguments. ('-psn _123_455','-psn=_123_455' work, but not '-psn_123_455').

If there are other uses for the -p flag, this would not work.


You can use a custom type to parse the argument, e.g.

def psntype(x):
    ret = re.match('sn_([0-9]+)_([0-9]+)',x)
    if ret is None:
        raise ValueError('bad -psn argument')
    return ret.groups()

parser=argparse.ArgumentParser()
parser.add_argument('-p',type=psntype)
print parser.parse_args('-psn_123_455'.split())
# Namespace(p=('123', '455'))
parser.parse_args('-psn_12355'.split())
# usage: ipython [-h] [-p P]
# error: argument -p: invalid psntype value: 'sn_12355'

the main advantage to doing the parsing with type is that argparse can raise an informative error (with usage). But your own post-argparse code can raise the same error (parser.error('bad -psn argument').

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Well, of course you can do that, but this is a hack and I don't like to not use `-p` for other things because of this. – Albert Nov 05 '13 at 12:33
  • Is it any less hacky if I define a `type` that can parse the argument? – hpaulj Nov 05 '13 at 16:55
  • 1
    I don't know about Mac tradition, but in Unix, having both a `-p` option (e.g. a print flag), and a `-psn` option would be confusing. Normally it would be parsed as `['-p','-s','-n',]`, where `p` and `s` are flags that don't take arguments, and `n` takes an argument. – hpaulj Nov 05 '13 at 16:55
1

Looking at the structure of the psn argument, it's not possible to parse it with argparse without interfering with a possible "-p" argument (see @hpaulj's answer). So, I'd recommend to use partial parsing, and extract it from the list of remainders.

Sven
  • 1,748
  • 1
  • 14
  • 14
  • So, you are basically saying that `argparse` is not able to parse it? Right now, I'm stripping out the parameter in advance because I want the normal `argparse` behavior in case there is an unknown parameter. – Albert Oct 30 '13 at 13:13
  • Yes. It looks like one cannot feed regular expressions or somesuch to argparse for argument matching, so stripping **psn** out before or after the parsing seems to be the only viable solution. – Sven Oct 30 '13 at 13:17
  • So, to answer my original question: It is not possible via `argparse`, I have to handle it somewhere else? – Albert Nov 05 '13 at 18:49
  • The answer by @hpaulj is IMHO a very nice way to handle it via argparse. However, there's nothing useful to do with the PSN anyway... – Sven Nov 06 '13 at 10:19
  • Well, not so much for me because it makes `-p` unusable for other purpose, only to have such a hackish solution. Anyway, the simple answer seems to be that it is not possible via `argparse` (that's a bit wrong in your answer: "it'll be annoying to parse" <- it's not annoying, it's not possible). You should make that clear, then I'll accept your answer. – Albert Nov 06 '13 at 10:41
  • @Albert I clarified my answer a little. – Sven Nov 07 '13 at 16:44