zenlotus / argparse

Automatically exported from code.google.com/p/argparse
Other
0 stars 0 forks source link

More robust arguments from files #32

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I changed line 1941 from this: 
arg_strings = args_file.read().splitlines()

to this: arg_strings = args_file.read().strip().split()

Using my approach you have much more flexibility when specifying arguments and 
options in the 
file.

Original issue reported on code.google.com by frigoli...@gmail.com on 15 Sep 2009 at 7:56

GoogleCodeExporter commented 9 years ago
But then how do you specify an argument that contains strings?

Original comment by steven.b...@gmail.com on 16 Sep 2009 at 8:33

GoogleCodeExporter commented 9 years ago
s/strings/spaces

Original comment by steven.b...@gmail.com on 16 Sep 2009 at 8:34

GoogleCodeExporter commented 9 years ago
Ok. In that case it will not work. Is it stablished that strings are specified 
between " " ?

If that is the case, I think I can write a more complex parser that handles 
that as well...

Original comment by frigoli...@gmail.com on 17 Sep 2009 at 6:45

GoogleCodeExporter commented 9 years ago
I'm not really 100% sure what the standard here is. See issue16 where the 
feature was
proposed.

Java implements this feature slightly differently:

http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html#commandline
argfile

There aren't really clear specs there, but after playing around with javac for 
a bit,
I think the Java rules are:
* Arguments are split up by whitespace
* Except that you can quote things with ""

But adopting that behavior for argparse would be backwards incompatible with the
current behavior. So we'd have to go through a deprecation cycle before 
changing it.

I'd definitely like to see feedback from zhirsch, who created the original 
feature
request before moving forward on this issue.

Original comment by steven.b...@gmail.com on 17 Sep 2009 at 7:34

GoogleCodeExporter commented 9 years ago

I think quoting strings is the way to go. 

What I do not like of the current implementation is that if you happen to not 
have a perfect formated file with 
parameters, such as having a space at the beginning or the end of the file, you 
get all kind of weird errors...

In any case, making possible to specify strings in the argument file without 
quotes is not really consistent with 
the command line interface, since you cannot use unquoted strings without 
getting errors...

Original comment by frigoli...@gmail.com on 17 Sep 2009 at 7:43

GoogleCodeExporter commented 9 years ago
The argument against quotes is that it's only your shell that's allowing quotes 
-- if
you worked directly within Python, you wouldn't put quotes around anything.

That said, I'm open to changing things given:
* we get some feedback from others saying that they think this is the right 
thing to
do, and
* we go through the usual deprecation process, which means:
  * argparse 1.1: 
    * introduce quoting mechanism
    * issue DeprecationWarning for lines with spaces but no quotes
  * argparse 1.2:
    * turn warning into error - spaces only allowed with quotes
  * argparse 1.3:
    * start treating all whitespace as separators - i.e. call .split()

Original comment by steven.b...@gmail.com on 17 Sep 2009 at 9:11

GoogleCodeExporter commented 9 years ago
How about adding an (optional) argument that takes a callable that gets passed 
each 
line from an argument file?  Then the parsing would use the return value of 
that 
function call as the actual line.  The default would be the current behavior 
(taking 
each line literally).

I've found the need for such a feature myself, for skipping blank lines and 
lines 
that start with a # (comments).

I've attached a patch that implements this.

Original comment by zhir...@gmail.com on 18 Sep 2009 at 5:04

Attachments:

GoogleCodeExporter commented 9 years ago
Seems like for the skipping comments you really want to override the entire file
reading and parsing process

Maybe we should add a ``fromfile_read_args`` keyword argument, defaulting to::

    def read_args(path):
        return open(path).read().splitlines()

And then for the particular use case above you could override it with::

    def read_lines(path):
        for line in open(path):
            if not line.startswith("#"):
                for item in line.split():
                    yield item

Original comment by steven.b...@gmail.com on 18 Sep 2009 at 7:10

GoogleCodeExporter commented 9 years ago
Yea, that works.  An alternative would be to make it a "public" method of the 
ArgumentParser class and have to subclass in order to override it (which would 
reduce 
the number of keyword arguments to the constructor).

Original comment by zhir...@gmail.com on 19 Sep 2009 at 4:19

GoogleCodeExporter commented 9 years ago
Yeah, I thought about that too. Either one would probably be okay.

Original comment by steven.b...@gmail.com on 19 Sep 2009 at 6:06

GoogleCodeExporter commented 9 years ago
Here's a patch that adds a method to the ArgumentParser class that can be 
overridden in 
a subclass.

Original comment by zhir...@gmail.com on 28 Dec 2009 at 9:02

Attachments:

GoogleCodeExporter commented 9 years ago
Thanks for the excellent patch. Committed with minor modifications in r80.

Original comment by steven.b...@gmail.com on 7 Jan 2010 at 5:30