Re: Gathering unknown option data without quitting
Allan Crooks <[email protected]> Sat, 06 May 2006 21:40:08 +0100
| Newsgroups | gmane.comp.python.optik.user |
|---|---|
| Message-ID | <[email protected]> |
Greg Ward wrote:
> On 03 May 2006, Allan Crooks said:
>
>>I would like to do something like this:
>>
>>def setup(func):
>> configure parser
>> options, args, unknown_options = parser.parse_args()
>> environment.handle(options)
>> func(environment, unknown_options)
>>
>>At the moment, you can't pass any options intended for the func
>>function, since it is rejected as an unknown option for the parser
>>created by the setup function.
>>
>>Has anyone written something to extend optik to do this?
>
> Not me! I added a smart-ass remark to the docs years ago to the effect
> that "if you don't like the fact that Optik terminates your process on
> error, you'll need to subclass OptionParser and override error()". I
> think you're the first person to actually take me up on this.
Yes, I remember reading that. :)
>>I think I could
>>probably write something to get what I want, but I'm just wondering
>>whether I could reuse existing code rather than writing something myself.
>
> On reflection, and looking at the code again, I think I would start by
> overriding _process_args() rather than error(). You want to call the
> real _process_args(), but catch BadOptionError. (You probably want to
> let OptionValueError pass up and be handled by the "except" clause in
> parse_args().) Then accumulate the bad options in a list somewhere. Or
> put them in the parser's 'largs' variable, if you don't need to
> distinguish between leftover positional args and bad options.
This is what I came up with - I decided to just store the values in
largs. It seemed quite straight-forward to do actually - though it
interacted with a few too many subclass values.
--
class UnknownOptionParser(OptionParser):
def _process_long_opt(self, rargs, values):
option, remaining_args = rargs[0], rargs[1:]
try:
OptionParser._process_long_opt(self, rargs, values)
except BadOptionError, error:
# OptionParser may actually leave rargs in a mangled state (at the
# time of writing) - what we will do is restore rargs.
self.largs.append(option)
self.rargs[:] = remaining_args
def _process_short_opts (self, rargs, values):
first_option = rargs[0][:2]
if self._short_opt.get(first_option):
# We'll assume the short options will be valid options for this
# parser.
OptionParser._process_short_opts(self, rargs, values)
else:
# We'll assume that the short options should be left unresolved.
self.largs.append(rargs.pop(0))
--
> I thikn what's going to make this difficult is dealing with "-ffoo" or
> "--file=foo" where "foo" is the argument to -f/--file. Good luck, and
> don't forget: Use The Source, Luke.
This code deals with handling double underscores. As for dealing short
options - that's too awkward (impossible, really). There are two
compromises I could go with.
1) We assume that we won't get several short options together like this:
-abcd (otherwise, we can't reliable distinguish between being provided a
short option with a value, or multiple short options (last one with a
value), or multiple short options (with no value)).
2) We assume we won't get a mixture of known short options and unknown
short options - which is what I've done here.
Allan.
-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642