[issue14156] argparse.FileType for '-' doesn't work for a mode of 'rb'

2014-03-31 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14156
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue20970] contradictory documentation for prog option of argparse

2014-03-19 Thread paul j3

paul j3 added the comment:

Cross reference for sys.argv[0] is

http://docs.python.org/3.4/library/sys.html

 ___


--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue20970
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue20970] contradictory documentation for prog option of argparse

2014-03-18 Thread paul j3

paul j3 added the comment:

Yes, the documentation is accurate but a bit vague.  It doesn't say how 'it 
uses sys.arg[0]'.  The example implies it uses 'basename'. So the question is, 
whether that implementation detail should be more explicit?

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue20970
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue20970] contradictory documentation for prog option of argparse

2014-03-18 Thread paul j3

paul j3 added the comment:

The relevant code is:

prog = _os.path.basename(_sys.argv[0])

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue20970
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11588] Add necessarily inclusive groups to argparse

2014-03-04 Thread paul j3

paul j3 added the comment:

A couple more thoughts on an expanded argument testing mechanism:

- do we need both 'seen_actions' and 'seen_non_default_actions'?  

'seen_actions' is used only to test whether all required actions have been 
seen.  These 2 sets differ in how positionals with '?*' are categorized.  
Positionals like this are always 'seen', even if they just get the default 
value.  But they are not required (the case of a '*' positional without default 
needs to be revisited.)

- If 'seen_non_default_actions' is changed to a list (currently its a set), 
users could test for repeated use on an optional, or even the order of 
arguments.  

- One way to make this testing mechanism more user-friendly is to provide 
convenience functions via a decorator.  

For example the decorator could wrap the 'seen_non_default_actions' argument in 
a 'seen' function.  Such a function could accept either an Action or a 'dest' 
string, it could accept a single Action, or a list of them, etc.  There could 
be other functions like 'count', 'unique', 'mutually_exclusive', 'inclusive', 
etc.

def testwfnc(func):
# decorator to register function and provide 'seen'
name = func.__name__
def wrapped(parser, seen_actions, *args):
def seen(*args):
actions = seen_actions
if isinstance(args[0], str):
actions = [a.dest for a in actions]
if len(args)1:
return [a in actions for a in args]
else:
return args[0] in actions
return func(parser, seen)
parser.register('cross_tests', name, wrapped)
return wrapped

#@testwfnc
def test(parser, seen, *args):
if seen(a_file):
print(seen(a_dir, a_pat, a_suf))
cnt = sum(seen(a_dir, a_pat, a_suf))
if cnt0:
parser.error('FILE cannot have DIR, PATTERN or SUFFIX')
...

The attached script experiments with several versions of decorators.  Some sort 
of testing Class is probably the way to go if we want to provide many 
convenience methods.

--
Added file: http://bugs.python.org/file34285/issue11588_4.py

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11588
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2014-03-03 Thread paul j3

paul j3 added the comment:

I need to tweak the last patch so 'using_default' is also set when an 
nargs='*' positional is set to the '[]' default.

 if action.default is not None:
 value = action.default
+using_default = True
 else:
 value = arg_strings
+using_default = True  # tweak

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2014-02-28 Thread paul j3

paul j3 added the comment:

In http://bugs.python.org/issue11588 (Add necessarily inclusive groups to 
argparse) I propose a generalization to these testing groups that would solve 
your 'conflicter' case as follows:

usage = 'prog [ --conflicter | [ --opt1 ] [ --opt2 ] ]'
parser = argparse.ArgumentParser(usage=usage)
conflicter = parser.add_argument(--conflicter, action='store_true')
opt1 = parser.add_argument(--opt1, action='store_true')
opt2 = parser.add_argument(--opt2, action='store_true')

@parser.crosstest
def test(parser, seen_actions, *args):
if conflicter in seen_actions:
if 0len(seen_actions.intersection([opt1, opt2])):
parser.error('--conflicter cannot be used with --opt1 or 
--opt2')

Groups, as currently defined, cannot handle nesting, and as a consequence 
cannot handle complex logic.  My proposal is to replace groups with user 
defined conflict tests that would be run near the end of 'parse_args'.  

This example shows, I think, that the proposal is powerful enough.  I'm not 
sure about ease of use and logical transparency.

Formatting the usage line is a different issue, though the 
MultiGroupHelpFormatter that I propose here is a step in the right direction.  
For now a user written 'usage' is the simplest solution.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11588] Add necessarily inclusive groups to argparse

2014-02-25 Thread paul j3

paul j3 added the comment:

The addition of a simple decorator to the 'ArgumentParser' class, would 
simplify registering the tests:

def crosstest(self, func):
# decorator to facilitate adding these functions
name = func.__name__
self.register('cross_tests', name, func)

which would be used as:

@parser.crosstest
def pat_or_suf(parser, seen_actions, *args):
if 2==len(seen_actions.intersection([a_pat, a_suf])):
parser.error('only one of PATTERN and SUFFIX allowed')

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11588
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11588] Add necessarily inclusive groups to argparse

2014-02-22 Thread paul j3

paul j3 added the comment:

This is an example of using 'patch_w_mxg2.diff' to handle the inclusive group 
case proposed by the OP.

Since 'seen_non_default_actions' (and 'seen_actions') is a set of 'Actions', it 
is convenient to use 'set' methods with pointers to the actions that a 
collected during setup.  Tests could also be done with the 'dest' or other 
action attributes.

In this example I wrote 3 simple tests corresponding to the 3 proposed groups, 
but they could also have been written as one test.

a_file= parser.add_argument(-o, --outfile, metavar='FILE')
a_dir = parser.add_argument(-O, --outdir, metavar='DIR')
a_pat = parser.add_argument(-p, --outpattern, metavar='PATTERN')
a_suf = parser.add_argument(-s, --outsuffix, metavar='SUFFIX')
...
def dir_inclusive(parser, seen_actions, *args):
if a_dir in seen_actions:
if 0==len(seen_actions.intersection([a_pat, a_suf])):
parser.error('DIR requires PATTERN or SUFFIX')
parser.register('cross_tests', 'dir_inclusive', dir_inclusive)
...

In theory tests like this could be generated from groups as proposed by the OP. 
There is one case in 'test_argparse.py' where a mutually_exclusive_group is 
nested in an argument_group.  But the current groups do not implement nesting.  
A (plain) argument_group does not share its '_group_actions' list with its 
'container'.  A mutually_exclusive_group shares its '_group_actions' but the 
result is a flat list (no nesting).

For now I think it is more useful to give users tools to write custom 
'cross_tests' than to generalize the 'group' classes.

--
Added file: http://bugs.python.org/file34193/example1.py

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11588
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11588] Add necessarily inclusive groups to argparse

2014-02-21 Thread paul j3

paul j3 added the comment:

This patch uses:

tests = self._registries['cross_tests'].values()

to get a list of functions to run at the end of '_parse_known_args'.

I replaced all of the mutually_exclusive_group tests (3 places) in the 
ArgumentParser with a static function defined in class _MutuallyExclusiveGroup, 
and registered this function.  This refactoring should make it easier to add 
other specialized groups (e.g. inclusive) in the future.

I'm using the _registries because they are already being shared among groups.  

A user can also register a custom testing function.  For example:

def inclusive_test(parser, seen, *args):
# require an argument from one of the 2 groups, g0 and g1
g0seen = seen.intersection(g0._group_actions)
g1seen = seen.intersection(g1._group_actions)
if len(g0seen.union(g1seen))==0:
parser.error('one of the 2 groups is required')
parser.register('cross_tests','inclusive', inclusive_test)

This patched 'argparse.py' runs 'test_argparse.py' without error.

This patch does not include the issue18943 changes, which make setting 
'seen_non_default_actions' more reliable.

--
keywords: +patch
Added file: http://bugs.python.org/file34176/patch_w_mxg2.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11588
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2014-02-14 Thread paul j3

paul j3 added the comment:

This patch corrects the handling of `seen_non_default_action` in another case - 
a positional with '?' and `type=int` (or other conversion).

if

parser.add_argument('badger', type=int, nargs='?', default=2) # or '2'

and the original test 'seen_non_default_actions' is:

if argument_values is not action.default

'argument_values' will be an 'int' regardless of the default.  But it will pass 
the 'is' test with the (small) int default but not the string default.

With the patch proposed here, both defaults behave the same - 'badger' will not 
appear in 'seen_non_default_actions' if it did not occur in the 
argument_strings (i.e. match an empty string).

I may add case like this to `test_argparse.py` for this patch.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11588] Add necessarily inclusive groups to argparse

2014-02-14 Thread paul j3

paul j3 added the comment:

The suggestion in this issue is to add a 'mutually_inclusive_group' mechanism, 
one that would let users specify that certain sets of arguments must occur 
together.  Furthermore there was mention of allowing some sort of nesting.

Modeling it on the mutually_exclusive_group would be straight forward.  But 
should it affect the usage and help display?mutually_exclusive_groups add a 
messy layer to the usage formatting.

The only place such a group would act would be at the end of 
'_parse_known_args', where the current code checks for things like required 
actions (and mxgroups). A test at this point could use 'namespace', 
'seen_actions' and 'seen_non_default_actions' to check whether the required 
group actions were seen.

But the only thing that the argument_group contributes to this test is a list 
of argument names ('dest'?).  Why not provide this list directly?  And what if 
the user wants A to occur together with either B or C, but not both?  Or make 
the inclusivity conditional on the value of A?

Currently users can define argument interactions in a couple of ways.  They can 
define custom Actions. In test_argparse.py there's a custom Actions test that 
does something like this (using '--spam' and 'badger').  But tests in Actions 
depend on the order in which arguments are given.

An alternative is to test for interactions of arguments after `parse_args`.  
However the only information that the user has at this point is the args 
namespace.  Reliably distinguishing between non-occurrence of arguments and 
default values can be difficult.

I am proposing 'cross_test' mechanism that would give the user access to the 
'seen_actions' and 'seen_non_default_actions' sets that 
'mutually_exclusive_groups' use.  Specifically an optional function can be 
called at the end of '_parse_known_args' that has access to these sets as well 
as the parser and the namespace.

The core of the change would be adding

cross_test = getattr(self, 'cross_test', None)
if cross_test:
cross_test(self, namespace, extras, seen_actions, 
seen_non_default_actions)

at the end of 'parser._parse_known_args'.  In addition 'cross_test' (or some 
other name) could be added to the 'ArgumentParser.__init__' arguments.

The feature could be used by defining such a 'cross_test' function and adding 
it to the parser (either instance or subclass)

def foobar(self, namespace, extras, seen_actions, seen_non_default_actions):
...
(raise self.error(...))

parser.cross_test = foobar

The patch proposed http://bugs.python.org/issue18943 should be included
with any changes here since it refines the setting of 
'seen_non_default_actions'.

I am working on tests and examples of such functionality.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11588
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11588] Add necessarily inclusive groups to argparse

2014-02-14 Thread paul j3

paul j3 added the comment:

Regarding a usage line like:

(-o FILE | (-O DIR  (-p PATTERN | -s SUFFIX))

The simplest option is to just a custom written 'usage' parameter.

With the existing HelpFormatter, a nested grouping like this is next to 
impossible.  It formats the arguments (e.g.'-O DIR'), interleaves the group 
symbols, and then trims out the excess spaces and symbols.

http://bugs.python.org/issue10984  is a request to allow overlapping 
mutually_exclusive_groups.  It loops on the groups, formatting each.  It would 
be easier with that to format several different types of groups, and to handle 
nested ones.

What would it take to convert a usage string like that into a logical 
expression that tests for the proper occurrence (or non-occurrence) of the 
various arguments.  It might, for example be converted to

exc(file, inc(dir, exc(pattern, suffix)))

where 'exc' and 'inc' are exclusive and inclusive tests, and 'file','dir' etc 
are booleans.  And what would be the error message(s) if this expression fails?

I can imagine a factory function that would take usage line (or other 
expression of groupings), and produce a function that would implement a 
cross_test (as outlined in my previous post).  It would be, in effect, a 
micro-language compiler.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11588
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9694] argparse required arguments displayed under optional arguments

2014-02-13 Thread paul j3

paul j3 added the comment:

The attached file shows how the default argument groups could be redefined, 
using 'required' as the criteria.

I've implemented it as a method that is added to a subclass of ArgumentParser.  
This method is invoked after arguments are defined, prior to generating the 
help.

The help looks something like this:

usage: alt_grouping.py [-h] [-f FOO] -g GOO pos [baz]

required:
  posrequired positional
  -g GOO, --goo GOO  required optional

optional:
  -h, --help show this help message and exit
  -f FOO, --foo FOO  optional
  bazoptional positional

I was thinking of implementing this as a formatter subclass, but given the way 
the help is assembled, invoking this method from the parser is simpler.

--
Added file: http://bugs.python.org/file34065/alt_grouping.py

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9694
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9694] argparse required arguments displayed under optional arguments

2014-02-13 Thread paul j3

paul j3 added the comment:

Here's another possible solution: add a `help_groups` parameter to 
ArgumentParser.  It is a list of base argument group names.  
`parser.add_argument(...)' places the action in one of those groups.

This is a generalization of the current code which creates two groups titled 
'positional arguments' and 'optional arguments', and assigns actions based on 
'optional strings' (e.g. '-f','--foo').

'help_groups' could have 1, 2, or 3 items.  

1 - just one argument group

2 - the current postional/optional split, but with user chosen names

3 - a 'positional', 'required', and 'optional' split.  

A 4 way split that distinguishes splits positionals between those that allow 0 
values and 1 or more, is possible, but probably not that useful.

The changes are in the ArgumentParser.__init__ and _add_action methods.

'subparsers' do not inherit this parameter.  I have not explored how it plays 
out with 'parents'. 'test_argparse.py' runs fine.

--
keywords: +patch
Added file: http://bugs.python.org/file34073/helpgroups.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9694
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9694] argparse required arguments displayed under optional arguments

2014-02-13 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


Added file: http://bugs.python.org/file34074/alt_grouping2.py

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9694
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9694] argparse required arguments displayed under optional arguments

2014-02-12 Thread paul j3

paul j3 added the comment:

As Steven pointed out, the existing `add_argument_group` mechanism can be used 
to group required arguments.  For example

- temp.py --
parser = argparse.ArgumentParser(description = 'Do something')
group1 = parser.add_argument_group('required arguments')
group1.add_argument('--reqarg', '-r', required=True)
parser.add_argument('--optarg','-o')
parser.add_argument('foo')
parser.print_help()

usage: ipython [-h] --reqarg REQARG [--optarg OPTARG] foo
Do something
positional arguments:
  foo
optional arguments:
  -h, --helpshow this help message and exit
  --optarg OPTARG, -o OPTARG
required arguments:
  --reqarg REQARG, -r REQARG

Positional 'foo' can also be put in the 'required' group:

group1.add_argument('foo')

required arguments:
  --reqarg REQARG, -r REQARG
  foo

The distinction between 'positionals' and 'optionals' (or flagged) is essential 
to the parsing, but it is not necessary for Help Formatting.

I can imagine grouping arguments by 'required/not-required' properties.  It 
might be worth constructing an alternative HelpFormatter class that regroups 
the arguments in this way.  Subclassing the HelpFormatter is the established 
way of adding features to the help display.

The existing HelpFormatter flags 'required' arguments in the usage line with 
'[]'.  There it is has the added task of flagging Mutually Exclusive Groups in 
the same way.

It's worth keeping in mind that whether an argument is 'required' or not is 
determined in 2 different ways.  There is an optional 'required' flag (default 
False).  But this flag is not allowed for 'positionals'.  Instead with those 
'argparse' looks at 'nargs' ('?*' are not required).

The 'required' attribute of an argument (Action) is ignored during 'parse_args' 
until the end.  At that time it makes an inventory of 'required' arguments that 
have not been seen, and potentially raises an error.  That testing was changed 
in a relatively recent patch, and produced an unintended change in whether 
'subparsers' were required or not. (I could look up those issues in needed).

I'll think about creating the alternative HelpFormatter.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9694
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue20039] Missing documentation for argparse.ArgumentTypeError

2013-12-21 Thread paul j3

paul j3 added the comment:

In argparse.py the status of ArgumentTypeError is ambiguous.

ArgumentError is listed as a public class, ArgumentTypeError is not.  It also 
says 'All other classes in this module are considered implementation details.'

ArgumentTypeError is a subclass of Exception (with no added functionality).

ArgumentTypeError is raised only once, in the FileType class (which is both a 
scripting convenience and example of a custom type).  As you note it is also 
used in the documentation example.  There is also one such example in 
test_argparse.py.

It is caught once, where it is converted into an ArgumentError.  It is handled 
much like a ValueError or TypeError - except that its message is passed through 
unchanged.  

In http://bugs.python.org/issue13824 I use it several times in the FileContext 
class for just this reason.  

In fact ArgumentTypeError could be documented as a footnote to the `type` 
block, saying to the effect: 'An ArgumentTypeError may be raised (instead of a 
ValueError or TypeError) to produce a custom error message.'

Normally an ArgumentTypeError is not passed back to the user code, consistent 
with the claim that it is not public.

--

Along the same line, should ArgumentError be documented better?  Currently it 
is just mentioned at the end, as a replacement for an optparse error class.

As best I can tell, the user code will only see an ArgumentError if the 
ArgumentParser.error method is customized.  Otherwise that error is caught and 
converted into a system exit.  Maybe the `error` paragraph in the documentation 
should get a sentence about ArgumentError.

In test_argparse.py, ArgumentError is used extensively (with a custom error 
method).

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue20039
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue19959] argparse.FileType does not expand tilde ~

2013-12-18 Thread paul j3

paul j3 added the comment:

Normally the unix shell takes care of this expansion.  If I call a simple 
script that prints sys.argv and runs a simple parser, I get:

2135:~/mypy$ python2.7 filetypetest.py ~/mypy/test.txt
['filetypetest.py', '/home/paul/mypy/test.txt']
Namespace(file=open file '/home/paul/mypy/test.txt', mode 'r'...)

I have to quote the argument '~/mypy/test.blog' to bypass this expansion.

This is under Linux (bash).  Is Windows or Mac different?

My impression is that `FileType` has been provided as an example of a custom 
`type`, as opposed to a comprehensive file handler.  But I can't quote a 
developer on this.  

http://bugs.python.org/issue13824 is a bug report that worries that 
'argparse.FileType opens a file and never closes it'.  There are some comments 
there about whether it is appropriate to expand on the capabilities of FileType.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue19959
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11354] argparse: nargs could accept range of options count

2013-11-29 Thread paul j3

paul j3 added the comment:

With a minor tweak to `argparse._is_mnrep()`, `nargs='{3}'` would also work.  
This means the same as `nargs=3`, so it isn't needed.  But it is consistent 
with the idea of accepting Regular Expression syntax where it makes sense.  
`nargs='{2,3}?'` also works, though I think that's just the same as `nargs=2`.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11354
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue19814] Document prefix matching behavior of argparse, particularly for parse_known_args

2013-11-28 Thread paul j3

paul j3 added the comment:

`parse_args` just calls `parse_known_args`, and then raises an error if `rest` 
is not empty.  So it is `parse_known_args` that is doing the abbreviation 
matching.  

Abbreviation matching is done relatively early, when `_parse_known_args` first 
loops through the strings, trying to decide which are arguments ('A') and which 
are options ('O').  This matching is done  in `_parse_optional`.  It's not 
something it does at the end on the 'leftovers'.

http://bugs.python.org/issue14910, a disable abbreviation option, might be a 
better solution.  Your example is an argument in favor of implementing that 
feature.

Unless a reader has your example in mind, the proposed documentation warning 
might be more confusing than helpful.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue19814
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14910] argparse: disable abbreviation

2013-11-28 Thread paul j3

paul j3 added the comment:

For a programmer who needs to turn off this abbreviation matching now, a simple 
solution is to subclass ArgumentParser:

class MyParser(ArgumentParser):
def _get_option_tuples(self, option_string):
return []

This could be the place to implement more specialized matching (e.g. do not 
match on strings like '--sync').

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14910
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17204] argparser's subparsers.add_parser() should accept an ArgumentParser

2013-11-25 Thread paul j3

paul j3 added the comment:

http://stackoverflow.com/a/20167038/901925
is an example of using `_parser_class` to produce different behavior in the 
subparsers.

parser = ArgumentParser()
parser.add_argument('foo')
sp = parser.add_subparsers(dest='cmd')
sp._parser_class = SubParser # use different parser class for subparsers
spp1 = sp.add_parser('cmd1')
spp1.add_argument('-x')
spp1.add_argument('bar')
spp1.add_argument('vars',nargs='*')

In this case the SubParser class implements a `parse_intermixed_known_args` 
method that handles that `nargs='*'` argument.

http://bugs.python.org/issue14191

It shouldn't be hard to add `parser_class` as a documented optional argument to 
`add_subparsers`.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue17204
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue19462] Add remove_argument() method to argparse.ArgumentParser

2013-11-20 Thread paul j3

paul j3 added the comment:

f.nargs = '?'
f.default = argparse.SUPPRESS
f.help = argparse.SUPPRESS

may be best set of tweaks to a positional Action `f`.  In quick tests it 
removes `f` from the help, suppresses any complaints about a missing string, 
and does not put anything in the namespace.

But if there is a string in the input that could match this positional, it will 
be use.

f.nargs = 0

is another option.  This puts a `[]` (empty list) in the namespace, since 
'nothing' matches `f`.  If there is an input string that might have matched it 
before, you will not get an 'unrecognized argument' error.  `parse_known_args` 
can be used to get around that issue.

I should stress, though, that fiddling with `nargs` like this is not part of 
the API.  Tweak this at your own risk.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue19462
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue19462] Add remove_argument() method to argparse.ArgumentParser

2013-11-13 Thread paul j3

paul j3 added the comment:

`argparse.SUPPRESS` should do the trick.  According to the documentation it can 
be used with `default` and `help` parameters.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue19462
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue19462] Add remove_argument() method to argparse.ArgumentParser

2013-11-01 Thread paul j3

paul j3 added the comment:

When you add an argument, argparse creates an `Action`, and returns it.  It 
also places that action in various lists (e.g. parse._actions) and 
dictionaries.  A `remove_argument` function would have to trace and remove all 
of those links.  That's a non-trivial task.  However modifying an argument (or 
Action) is much easier, since there is only one instance.  Obviously some 
modifications will be safer than others.

For example:

parser = ArgumentParser()
a = parser.add_argument('--foo')
print a

produces:

_StoreAction(option_strings=['--foo'], dest='foo', nargs=None,
const=None, default=None, type=None, choices=None, help=None, metavar=None)

`vars(a)` gives a somewhat longer list of attributes.  Within reason, those 
attributes can be changed directly.  I think the 'dest', 'help', 'nargs', 
'metavar' could all be changed without hidden effects.  There's also a 
'required' attribute that could be changed for optionals.  Changing the 
'option_strings' might be problematic, since the parser has a dictionary using 
those strings as keys.

The constant `argparse.SUPPRESS` is used in several places to alter actions.  
For example, to suppress the help, or to suppress default values in the 
Namespace.  So it might be possible to 'hide' arguments in the subclass, even 
if you can't remove them.

In http://bugs.python.org/issue14191 I explored a couple of ways of temporarily 
'deactivating' certain groups of arguments, so as to parse the optionals and 
positionals separately.  It's an advance issue, but might still give some 
ideas. 

Another possibility is to use 'parent' parsers to define clusters of arguments. 
 Your base class could create a parser with one set of parents, and the 
subclass could use a different set.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue19462
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue19462] Add remove_argument() method to argparse.ArgumentParser

2013-11-01 Thread paul j3

paul j3 added the comment:

Just hang on the Action object that the `add_argument` returned, and change its 
`help` attribute.

a = parser.add_argument('--foo', help='initial help')

a.help = 'new help'

If using a custom parser class and subclass, I'd do something like:

self.changeablearg = self.parser.add_argument...

in the class, and

self.changeablearg.help = 'new help'

in the subclass

You can test the help message with

print parser.format_help()

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue19462
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9338] argparse optionals with nargs='?', '*' or '+' can't be followed by positionals

2013-10-21 Thread paul j3

paul j3 added the comment:

parse_args() would see ['-foo', 'bar1,bar2,bar3', 'pos1', 'pos2'].  The 
splitting on space is done by the shell.  So having your own code split 
'bar1,bar2,bar3' is simplest.  But that would be messed up if the user entered 
'bar1, bar2, bar3...'.  You could also ask the user to use quotes - bar1, 
bar2, bar3.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9338
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15613] argparse ArgumentDefaultsHelpFormatter interacts badly with --arg and nargs=+

2013-10-14 Thread paul j3

paul j3 added the comment:

Looks like this behavior is intentional.  This subclass adds a '%(default)s' 
string to the help lines if:

if '%(default)' not in action.help:
if action.default is not SUPPRESS:
defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
if action.option_strings or action.nargs in defaulting_nargs:
help += ' (default: %(default)s)'

So it adds the default if it is an `optional`, or a `positional` with '*' or 
'?'.  

A `default` value for a required positional (including '+') does not make 
sense, since the user input always overwrites the default.  

(I recommend closing this issue).

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15613
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14365] argparse: subparsers, argument abbreviations and ambiguous option

2013-09-28 Thread paul j3

paul j3 added the comment:

I think the correction to the problem that I noted in the previous post is to 
return 'None, arg_string, None', rather than 'action, arg_string, None' in the 
case where the action is found in a subparser.

This is what '_parse_optional' does at the end:

# it was meant to be an optional but there is no such option
# in this parser (though it might be a valid option in a subparser)
return None, arg_string, None

An input like '--foo baz' would then produce an 'invalid choice' error.  Since 
'--foo' is an optional that the primary parser does not recognize, 'baz' in 
interpreted as a positional, in this case an invalid subparser choice.

I'm working on cleaning up a test script.

--
Added file: http://bugs.python.org/file31888/subparser_patch.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14365
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14365] argparse: subparsers, argument abbreviations and ambiguous option

2013-09-28 Thread paul j3

paul j3 added the comment:

In the last patch, 'parser.scan = True' is needed to activate this fix.  I left 
that switch in for testing convenience.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14365
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14365] argparse: subparsers, argument abbreviations and ambiguous option

2013-09-28 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


Removed file: http://bugs.python.org/file31888/subparser_patch.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14365
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14365] argparse: subparsers, argument abbreviations and ambiguous option

2013-09-28 Thread paul j3

paul j3 added the comment:

This the argparse patch as described in the previous post, along with 
test_argparse tests.  

For now the tests handle both subparser required cases and not required ones ( 
http://bugs.python.org/issue9253 ).  While error messages can differ based on 
this requirement, it does not affect the 'ambiguity' that underlies the current 
issue.

--
Added file: http://bugs.python.org/file31901/subparser_patch.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14365
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14365] argparse: subparsers, argument abbreviations and ambiguous option

2013-09-26 Thread paul j3

paul j3 added the comment:

Steven's patch (subparse_optionals.diff) run with jakub's test case 
(argparse_subparses_ambiguous_bug.py) works.  But if the input string is 

print(parser.parse_args('--foo baz'.split()))

produces

Namespace(cmd=None, foo='baz', foo1=None, foo2=None)

(I added the 'cmd' subparse 'dest').  

Two things seem to be going on now: 

1) '--foo' is being parsed even though its subparser is not invoked, 

2) and the subparser is not required.

The issue of whether subparsers are required or not is another issue.  They 
used to be required, but the testing for 'required' was changed, and subparsers 
fell through the crack.

I suspect that if the missing subparser error were raised, the first issue 
wouldn't be apparent.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14365
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue13824] argparse.FileType opens a file and never closes it

2013-09-25 Thread paul j3

paul j3 added the comment:

An alternative way to delay the file opening, is to return an instance that has 
a `filename` attribute, and has an `open` method.  This can be compactly added 
to the `FileContext` that I defined in the previous patch.  The `FileContext` 
provides the `_ostest` function (testing using os.access), and wrapper for 
stdin/out.


class FileOpener(argparse.FileContext):
# delayed FileType; alt to use of partial()
# sample use:
# with args.input.open() as f: f.read()
def __call__(self, string):
string = self._ostest(string)
self.filename = string
return self
def open(self):
return self.__delay_call__(self.filename)()
file =  property(open, None, None, 'open file property')

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue13824
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue13824] argparse.FileType opens a file and never closes it

2013-09-23 Thread paul j3

paul j3 added the comment:

In this patch I implement a FileContext class.  It differs from FileType
in 2 key areas:

- it returns a 'partial(open, filename, ...)'
- it wraps '-' (stdin/out) in a dummy context protecting the file from closure.

The resulting argument is meant to be used as:

with args.input() as f:
f.read()
etc

The file is not opened until value is called, and it will be closed after the 
block.  stdin/out can also be used in this context, but without closing.

The signature for this class is the same as for FileType, with one added 
parameter, 'style'. (alternative name suggestions welcomed).

class argparse.FileContext(mode='r', bufsize=-1, encoding=None, errors=None, 
style='delayed')

The default behavior, style='delayed', is as described above.

style='evaluate' immediately calls the partial, returning an opened file.  
This is essentially the same as FileType, except for the stdin/out context 
wrapping.

style='osaccess', adds os.acccess testing to determine whether the 'delayed' 
file can be read or written.  It attempts to catch the same sort of OS errors 
that  FileType would, but without actually opening or creating the file.

Most of the added tests in test_argparse.py copy the FileType tests.  I had to 
make some modifications to the testing framework to handle the
added levels of indirection.

I have not written the documentation changes yet.

A sample use case is:

import argparse, sys
p = argparse.ArgumentParser()
p.add_argument('-d','--delayed', type=argparse.FileContext('r'))
p.add_argument('-e','--evaluated', type=argparse.FileContext('r', 
style='evaluate'))
p.add_argument('-t','--test', dest='delayed', 
type=argparse.FileContext('r', style='osaccess'))
p.add_argument('-o','--output', type=argparse.FileContext('w', 
style='osaccess'), default='-')
p.add_argument('--unused', type=argparse.FileContext('w', 
style='osaccess'),help='unused write file')
args = p.parse_args()

with args.output() as o:
if args.delayed:
with args.delayed() as f:
print(f.read(), file=o)
if args.evaluated:
with args.evaluated as f:
print(f.read(), file=o)
# f and o will be closed if regular files
# but not if stdin/out
# the file referenced by args.unused will not be created

--
keywords: +patch
Added file: http://bugs.python.org/file31852/patch_3.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue13824
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16878] argparse: positional args with nargs='*' defaults to []

2013-09-18 Thread paul j3

paul j3 added the comment:

On a related point, the 'action.required' value is set differently for '?' and 
'*' positionals.  

if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
kwargs['required'] = True
if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
kwargs['required'] = True

OPTIONAL is always not required, ZERO_OR_MORE is not required if it has a 
default.  But for reasons discussed here, that 'required' value makes little 
difference.  

`parse_args` checks that all 'required' arguments have been seen, but a 
ZERO_OR_MORE positional is always seen (i.e. it matches an empty string).  

Usage formatting always uses '[%s [%s ...]]' with ZERO_OR_MORE, regardless of 
the 'required' attribute.

The only place where this 'required' value seems to matter is when adding such 
an argument to a mutually exclusive group.  But if an unused '*' positional is 
going to get a '[]' value anyways, why should it be excluded from such a use?

If I remove the 

if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:

test, test_argparse.py still runs fine.

http://bugs.python.org/issue18943 is a possibly related issue, involving  a 'is 
not action.default' test in a mutually exclusive group.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16878
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11708] argparse: suggestion for formatting optional positional args

2013-09-18 Thread paul j3

paul j3 added the comment:

This is a HelpFormatter function that takes a list of formatted actions, and 
groups contiguous blocks of optional positional actions.  It accounts for 
optionals (via prefix_chars) and mutually exclusive groups.

Since it assumes 'parts' is a list, rather than string, it works best with the 
'_format_actions_usage' method in the patch that I submitted to 
http://bugs.python.org/issue11874 

def _positionals_regroup(self, parts):
# change '[arg1] [arg2]' to '[arg1 [arg2]]'
# apply to a list of formatted arguments
# don't apply to optionals (with prefix chars) or groups
chars = getattr(self, 'prefix_chars',set('-'))
R = _re.compile(r'\] \[(.*)\]')
result = []
text = None
while  parts:
part = parts.pop()
if part:
if part[0]=='[' and part[1] not in chars and '|' not in part:
if text:
text = ' '.join([part, text])
else:
text = part
if R.search(text):
text = R.sub(' [\g1]]',text)
else:
if text:
result.insert(0,text)
text = None
result.insert(0,part)
if text:
result.insert(0,text)
return result

To avoid compatibility issues it could implemented in a subclassed 
HelpFormatter.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11708
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11708] argparse: suggestion for formatting optional positional args

2013-09-16 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11708
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue13824] argparse.FileType opens a file and never closes it

2013-09-16 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue13824
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14365] argparse: subparsers, argument abbreviations and ambiguous option

2013-09-16 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14365
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9694] argparse required arguments displayed under optional arguments

2013-09-16 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9694
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2013-09-16 Thread paul j3

paul j3 added the comment:

Another situation in which this MultiGroupHelpFormatter helps is when one or 
more of the groups includes an optional positional.  

The regular formatter moves all the positionals to the end, after the 
optionals.  This move could easily break up a mutually exclusive group, and 
make formatting it impossible.  But the MultiGroupHelpFormatter gives the group 
order priority.

Thus for example:

p=argparse.ArgumentParser()
# (formatter_class=argparse.MultiGroupHelpFormatter)
g=p.add_mutually_exclusive_group()
g.add_argument('-f')
g.add_argument('foo',nargs='?')
g=p.add_mutually_exclusive_group()
g.add_argument('-b')
g.add_argument('-c')
g.add_argument('bar',nargs='*',default='X')
print(p.format_usage())

produces (positionals at end, no group markings)

usage: PROG [-h] [-f F] [-b B] [-c C] [foo] [bar [bar ...]]

But the MultiGroupHelpFormatter produces:

usage: PROG [-h] [-f F | foo] [-b B | -c C | bar [bar ...]]

In this last case, the positionals are listed with their respective groups, and 
the groups are ordered by the relative ordering of the positionals.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-09 Thread paul j3

paul j3 added the comment:

At the very least the `is not action.default` needs to be changed.  Else where 
in argparse `is` is only used with `None` or constant like `SUPPRESS`.  So 
using it with a user defined parameter is definitely not a good idea.

Possible variations on how `is` behaves across implementations (pypy, 
ironpython) only complicates the issue.  I'm also familiar with a Javascript 
translation of argparse (that uses its `!==` in this context).

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-09 Thread paul j3

paul j3 added the comment:

This patch uses a narrow criteria - if `_get_values()` sets the value to 
`action.default`, then argument counts as 'not present'.  I am setting a 
`using_default` flag in `_get_values`, and return it for use by `take_action`.

In effect, the only change from previous behavior is that small ints (257) now 
behave like large ints, strings and other objects.

It removes the nonstandard 'is not action.default' test, and should behave 
consistently across all platforms (including pypy).

--
keywords: +patch
Added file: http://bugs.python.org/file31704/patch_1.diff

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-08 Thread paul j3

paul j3 added the comment:

Changing the test from

if argument_values is not action.default:

to 

if argument_values is not action.default and \
(action.default is None or argument_values != action.default):

makes the behavior more consistent.  Strings and large ints behave like small 
ints, matching the default and not counting as present

Simply using `argument_values != action.default` was not sufficient, since it 
raised errors in existing test cases (such as ones involving Nones).

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-08 Thread paul j3

paul j3 added the comment:

A possibly unintended consequence to this `seen_non_default_actions` testing is 
that default values do not qualify as 'present' when testing for a required 
mutually exclusive group.

p=argparse.ArgumentParser()
g=p.add_mutually_exclusive_group(required=True)
g.add_argument('--foo',default='test')
g.add_argument('--bar',type=int,default=42)
p.parse_args('--bar 42'.split())

raises an `error: one of the arguments --foo --bar is required`

In the original code

p.parse_args('--foo test'.split())

does not raise an error because 'test' does not qualify as default.  But with 
the change I proposed, it does raise the error.

This issue may require adding a `failures_when_required` category to the 
test_argparse.py MEMixin class.  Currently nothing in test_argparse.py tests 
for this issue.

Note that this contrasts with the handling of ordinarily required arguments.

p.add_argument('--baz',type=int,default=42,required=True)

'--baz 42' does not raise an error.  It is 'present' regardless of whether its 
value matches the default or not.

This argues against tightening the `seen_non_default_actions` test.  Because 
the current testing only catches a few defaults (None and small ints) it is 
likely that no user has come across the required group issue.  There might 
actually be fewer compatibility issues if we simply drop the default test (or 
limit it to the case where the default=None).

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-08 Thread paul j3

paul j3 added the comment:

I should add that defaults with required arguments (or groups?) doesn't make 
much sense.  Still there's nothing in the code that prevents it.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-08 Thread paul j3

paul j3 added the comment:

This `argument_values` comes from `_get_values()`.  Most of the time is derived 
from the `argument_strings`.  But in a few cases it is set to `action.default`, 
specifically when the action is an optional postional with an empty 
`argument_strings`.

test_argparse.TestMutuallyExclusiveOptionalAndPositional is such a case.  
`badger` is an optional positional in a mutually exclusive group.  As such it 
can be 'present' without really being there (tricky).  Positionals are always 
processed - otherwise it raises an error.

If this is the case, what we need is a more reliable way of knowing whether 
`_get_values()` is doing this, one that isn't fooled by this small int caching.

We could rewrite the `is not` test as:

if not argument_strings and action.nargs in ['*','?'] and  argument_values 
is action.default:
pass # _get_values() has set: argument_values=action.default
else:
seen_non_default_actions.add(action)
...

is a little better, but still feels like a kludge.  Having `_get_values` return 
a flag that says I am actually returning action.default would be clearer, 
but, I think, too big of a change.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-06 Thread paul j3

paul j3 added the comment:

The patch isn't a good unittest case because it produces an Error, not a 
Failure.  It does, though, raise a valid question about how a 
Mutually_exclusive_group tests for the use of its arguments.

As you note, argparse does use the `is` test: `argument_values is not 
action.default`.  argument_values is the result of passing an argument_string 
through its 'type' function.

This reworks your test case a bit:

group = parser.add_mutually_exclusive_group()
group.add_argument('--foo', default='test')
group.add_argument('--bar', type=int, default=256)
group.add_argument('--baz', type=int, default=257)

'--foo test --baz 257' will give the `argument --foo: not allowed with argument 
--baz` error message, but '--foo test --baz 256' does not.

So which is right?  Should it complain because 2 exclusive arguments are being 
used?  Or should it be excused from complaining because the values match their 
defaults?

The other issue is whether the values really match the defaults or not.  With 
an `is` test, the `id`s must match. The ids for small integers match all the 
time, while ones 256 differ.

Strings might have the same id or not, depending on how they are created.  If I 
create `x='test'`, and `y='--foo test'.split()[1]`.  `x==y` is True, but `x is 
y` is False.  So '--foo test' argument_value does not match the 'foo.default'.

So large integers (256) behave like strings when used as defaults in this 
situation.  It's the small integers that have unique ids, and hence don't 
trigger mutually_exclusive_group errors when they should.

This mutually_exclusive_group 'is' test might not be ideal (free from all 
ambiguities), but I'm not sure it needs to be changed.  Maybe there needs to be 
a warning in the docs about mutually_exclusive_groups and defaults other than 
None.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18943] argparse: default args in mutually exclusive groups

2013-09-06 Thread paul j3

paul j3 added the comment:

A further complication on this.  With the arguments I defined in the previous 
post

p.parse_args('--foo test --baz 257'.split())

gives the mutually exclusive error message.  `sys.argv` does the same.

p.parse_args(['--foo', 'test', '--baz', '257'])

does not give an error, because here the 'test' argument string is the same as 
the default 'test'.  So the m_x_g test thinks `--foo' is the default, and does 
not count as an input.

Usually in testing an argparse setup I use the list and split arguments 
interchangeably, but this shows they are not equivalent.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18943
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2013-09-01 Thread paul j3

paul j3 added the comment:

A possible further tweak is, in take_action(), test for conflicts before adding 
the action to 'seen_non_default_actions'

if argument_values is not action.default:
#seen_non_default_actions.add(action)
for conflict_action in action_conflicts.get(action, []):
if conflict_action in seen_non_default_actions:
   ...
seen_non_default_actions.add(action)

This does not cause problems with any existing tests, but makes it possible to 
add an action twice to a group.  Why do that?  To prevent an action from 
occurring more than once.  For some actions like 'count' and 'append' repeated 
use is expected, but for others it isn't expected, and may sometimes be a 
nuisance (the last occurrence is the one that sticks). 

An example use would be:

parser = argparse.ArgumentParser(prog=PROG,
formatter_class=argparse.MultiGroupHelpFormatter)
action = parser.add_argument('--arg', help='use this argument only once')
group1 = parser.add_mutually_exclusive_group(action, action)
args  = parser.parse_args()

calling this with:

python3 test_once.py --arg test --arg next

would produce this error message:

usage: PROG [-h] [--arg ARG | --arg ARG]
PROG: error: argument --arg: not allowed with argument --arg

The usage and error message aren't as clear as they might be if this feature 
was added 'from scratch'.  But for a minor change like this, that may be an 
acceptable price.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15112] argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional

2013-08-28 Thread paul j3

paul j3 added the comment:

These three changes end up testing for the same thing. The initial 'if' catches 
different test cases.  'subparsers' or 'remainder' might 'confuse' the 'O' 
test.  The zero-width test ends up weeding out everything but the test cases 
added for this issue.

# if we haven't hit the end of the command line strings,
if start_index + sum(arg_counts) != len(arg_strings_pattern):
while arg_counts and arg_counts[-1] == 0: 
arg_counts.pop()

# same test using selected_pattern (= arg_strings_pattern[start_index:])
if len(selected_pattern) != sum(arg_counts):
while arg_counts and arg_counts[-1] == 0: 
arg_counts.pop()

# alt test: test for optional in the remaining pattern
if 'O' in selected_pattern:
while arg_counts and arg_counts[-1] == 0: 
arg_counts.pop()

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15112
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15112] argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional

2013-08-24 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15112
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14191] argparse doesn't allow optionals within positionals

2013-08-24 Thread paul j3

paul j3 added the comment:

Above in
http://bugs.python.org/issue14191#msg187051
I proposed a patch that is quite close to bethard's patch in 
http://bugs.python.org/issue15112#msg166173

Both modify the same place, doing the same (pop items off arg_counts).  The 
logic is a little different.  I'd have to look at them more carefully to see 
whether one is more robust.  Thanks for linking that issue.

The main issue here is different, allowing for complete intermixing of 
optionals and positionals.  Over at 15112 the issue is intermixing of optionals 
and 'whole' positionals.  My 187051 patch belongs over there.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14191
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14191] argparse doesn't allow optionals within positionals

2013-08-24 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


Added file: http://bugs.python.org/file29880/mixed.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14191
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15112] argparse: nargs='*' positional argument doesn't accept any items if preceded by an option and another positional

2013-08-24 Thread paul j3

paul j3 added the comment:

I originally posted this on http://bugs.python.org/issue14191, but I think it 
belongs here.  The patch I proposed is similar to berthard's, popping items off 
the end of 'args_counts'.  I intend to check whether the logic is equivalent.


copy from http://bugs.python.org/msg187051

This patch permits the mixing of optionals with positionals, with the caveat 
that a particular positional cannot be split up.

If:

parser = ArgumentParser()
parser.add_argument('-f','--foo')
parser.add_argument('cmd')
parser.add_argument('rest', nargs='*')

'-f1 cmd 1 2 3', 
'cmd -f1 1 2 3', 
'cmd 1 2 3 -f1' 

all give {cmd='cmd', rest=['1','2','3'], foo='1'}.  

But 'cmd 1 -f1 2 3', does not recognize ['2','3'].

Previously 'cmd -f1 1 2 3' would return rest=[], and not recognize 
['1','2','3'].  With this change the nargs='*' behaves more like nargs='+', 
surviving to parse the 2nd group of positional strings.

The trick is to modify arg_counts in consume_positionals(), removing matches 
that don't do anything (don't consume argument strings). 

if 'O' in arg_strings_pattern[start_index:]:
# if there is an optional after this, remove
# 'empty' positionals from the current match
while len(arg_counts)1 and arg_counts[-1]==0:
arg_counts = arg_counts[:-1]

This change passes all of the existing test_argparse.py tests.  It also passes 
the optparse tests that I added in http://bugs.python.org/issue9334#msg184987
I added 4 cases to illustrate this change.

--
Added file: http://bugs.python.org/file31457/mixed.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15112
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14191] argparse doesn't allow optionals within positionals

2013-08-24 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


Removed file: http://bugs.python.org/file29880/mixed.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14191
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14191] argparse doesn't allow optionals within positionals

2013-08-20 Thread paul j3

paul j3 added the comment:

It's everything I intend to add.  Now I'm just waiting for a committer to act, 
either with suggested changes, or a merge.  I'm watching more than a dozen 
argparse patches.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14191
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15428] add Name Collision section to argparse docs

2013-08-14 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue15428
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue13280] argparse should use the new Formatter class

2013-08-09 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue13280
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue12806] argparse: Hybrid help text formatter

2013-08-08 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue12806
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9253] argparse: optional subparsers

2013-07-30 Thread paul j3

paul j3 added the comment:

msg113512 - (view) Author: Steven Bethard (bethard) 
Seems like there's minimally the bug that argparse should currently throw an 
error if you add an argument after subparsers (since that argument will never 
be parsed under the current semantics).

This isn't quite right.  If the main usage signature is:

usage: PROG [-h] foo {one,two} ... baz

the parser._match_arguments_partial() method will allocate the 1st string to 
'foo', the last to 'baz', and pass the rest to the subparser(s).  It doesn't 
know how many the subparsers can use, but it knows that 'baz' requires one.  
From the standpoint of matching argument strings and arguments, a subparser is 
essentially a '+' positional.

On the other hand if 'baz' (the positional after the subparser) was '*' or '?' 
it would not get any strings.

If it is possible that subparser(s) doesn't need all the strings passed to it, 
the user could use 'parse_known_args', and deal with the unparsed strings 
themselves (possibly with another parser).

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9253
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11955] 3.3 : test_argparse.py fails 'make test'

2013-07-30 Thread paul j3

paul j3 added the comment:

The test names are:

FAIL: test_failures_many_groups_listargs (__main__.TestFileTypeW) 
FAIL: test_failures_many_groups_sysargs (__main__.TestFileTypeW)  
FAIL: test_failures_no_groups_listargs (__main__.TestFileTypeW)   
FAIL: test_failures_no_groups_sysargs (__main__.TestFileTypeW)
FAIL: test_failures_one_group_listargs (__main__.TestFileTypeW)   
FAIL: test_failures_one_group_sysargs (__main__.TestFileTypeW)

So they differ by [many_groups, no_groups, one_group] and [listargs, sysargs]

There are about 170 tests in test_argparse that get multiplied by 6 in this 
way.  If this replication was removed it would cut the number of tests and time 
to nearly a third.

This replication is not useful.  listargs and sysargs differ only in how a list 
of arguments is passed to parse_args, either directly, or via sys.argv.  It 
should be sufficient to test these alternatives once, not 170 times.

'one group' creates an argument group, and adds all arguments to that.  'many 
groups' creates an argument group for each added argument.  But argument groups 
are not used for 'parse_args'.  They are only used when formatting help.  By 
default all the arguments of parser are already put into one of two groups, 
'optional arguments' or 'positional arguments'.

There are tests for the help formatting, but they don't use this 
ParserTesterMetaclass.  

I would recommend removing this test replication.  It is both unnecessary and a 
source of confusion.  The simplest would be to change the end of the 
ParserTesterMetaclass.  

class ParserTesterMetaclass
def __init__()

for add_arguments in [no_groups]:
for parse_args in [listargs]:
AddTests(cls, add_arguments, parse_args)

I suspect there is some confusion among users and developers as to what 
argument groups do.  

As for the TestFileTypeW error, I suspect it has to do with file writing 
privileges.  I haven't encountered it, but I running tests in my own directory.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11955
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14074] argparse allows nargs1 for positional arguments but doesn't allow metavar to be a tuple

2013-07-26 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14074
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16360] argparse: comma in metavar causes assertion failure when formatting long usage message

2013-07-26 Thread paul j3

paul j3 added the comment:

My rewrite of _format_actions_usage in http://bugs.python.org/issue11874 should 
take care of this issue.  It keeps the groups and actions separate until the 
final formatting step, bypassing the regular expression parsing.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16360
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14074] argparse allows nargs1 for positional arguments but doesn't allow metavar to be a tuple

2013-07-26 Thread paul j3

paul j3 added the comment:

This patch fixes the problem by joining the metavar terms with '|'.  So the 
help for the test case (adapted from an existing tuple test) looks like:

usage: PROG [-h] W1 [W2 ...] [X1 [X2 ...]] Y1 Y2 Y3 [Z1]
positional arguments:
  W1|W2   w
  X1|X2   x
  Y1|Y2|Y3y
  Z1  z

Alternatives include:
- use ',',' ',or '/' instead of '|'
- use just the 1st item of the tuple
- use the default (non-tuple) metavar in the help line
These all pass existing tests.

The last alternative would use:

#metavar = '|'.join(metavar)
if len(metavar)1:
metavar = default
else:
metavar = metavar[0]

--
keywords: +patch
Added file: http://bugs.python.org/file31042/issue14074.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue14074
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18467] argparse - problematic 'default' behavior

2013-07-19 Thread paul j3

paul j3 added the comment:

Since parse_args takes an optional Namespace argument, you can set the its 
initial value to almost anything.  For example, with the functions defined 
previously:

parser = argparse.ArgumentParser()
parser.add_argument('-a','--algorithm', choices=['Q','S'], 
action=FooAction, type=bar)
NS = parser.parse_args(['-a','S'])
args = parser.parse_args(None, NS)

The first parse_args uses FooAction to create a default Namespace, which is 
then passed to the second.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18467
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2013-07-16 Thread paul j3

paul j3 added the comment:

This patch produces the same usage as before, but I have rewritten 
_format_actions_usage() for both HelpFormatter and MultiGroupFormater.

The original HelpFormatter._format_actions_usage() formats the actions, splices 
in group markings, cleans up the text, if needed, tries to break it down into 
parts.  But this is fragile, as shown here and in issues 11874, 18349).

Now _format_group_usage() and _format_just_actions_usage() format groups and 
actions directly, without the splice and divide steps.  _format_actions_usage() 
for both classes call these to build a list of usage parts.

This change also solves http://bugs.python.org/issue11874 and 
http://bugs.python.org/issue18349, since it does not have to break up a 
formatted text line (and in the process get confused by [] and ()).

--
Added file: http://bugs.python.org/file30940/multigroup_4.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11874] argparse assertion failure with brackets in metavars

2013-07-16 Thread paul j3

paul j3 added the comment:

Here's a patch that takes a different approach - rewrite 
_format_actions_usage() so it formats groups (and unattached actions) directly. 
 

It uses the same logic to determine when to format a group, but then it calls 
_format_group_usage() to format the group, without the error prone insert and 
cleanup business.  And by keeping a list of the parts, it avoids the 
complications of parsing the text.  The only cleanup regex removes () from 
single element groups.

In the nested get_lines function, I added 'line and' to 

   if line and line_len + 1 + len(part)  text_width:

so it does not create a blank line before an extra long entry (e.g. 'c'*76).

I'm using the _format_group_usage() and _format_just_actions_usage() in the 
Issue 10984 MultiGroupFormatter, just rearranging the logic in its 
_format_actions_usage() method.  That patch could be rewritten to depend on 
this one.

This patch also fixes http://bugs.python.org/issue18349, since the metavar is 
never parsed.

--
Added file: http://bugs.python.org/file30941/format_usage.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11874
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18349] argparse usage should preserve () in metavars such as range(20)

2013-07-16 Thread paul j3

paul j3 added the comment:

I just submitted at patch to http://bugs.python.org/issue11874 that takes care 
of this issue as well.

I rewrote _format_actions_usage() so it formats the parts directly, so there is 
no need cleanup or parse the full text string.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18349
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16468] argparse only supports iterable choices

2013-07-16 Thread paul j3

paul j3 added the comment:

I just submitted a patch to http://bugs.python.org/issue11874 which rewrites 
_format_actions_usage().  It now formats the groups and actions directly, 
keeping a list of these parts.  It no longer has to cleanup or split a usage 
line into parts.  So it is not sensitive to special characters (space, [] or () 
 ) in the choices metavar.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16468
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17890] argparse: mutually exclusive groups full of suppressed args can cause AssertionErrors

2013-07-16 Thread paul j3

paul j3 added the comment:

I just submitted a patch to http://bugs.python.org/issue11874 that 
substantially rewrites _format_actions_usage().  It generates the group and 
action parts separately, and does not do the kind of cleanup that produces this 
issue.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue17890
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18467] argparse - problematic 'default' behavior

2013-07-16 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18467
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18467] argparse - problematic 'default' behavior

2013-07-16 Thread paul j3

paul j3 added the comment:

I think this example illustrates your issue:

class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, 
option_string = None):
if values=='Q':
setattr(namespace, self.dest, 
{'type':values, 'quick':True, 'slow':False})
else:
setattr(namespace, self.dest, 
{'type':values, 'quick':False, 'slow':True})

def bar(string):
return string.upper()[0]

parser = argparse.ArgumentParser()
parser.add_argument('-a','--algorithm', choices=['Q','S'],
default='s', action=FooAction, type=bar)
parser.add_argument('foo', choices=['Q','S'],
default='s', action=FooAction, nargs='?', type=bar)
print(parser.parse_args([]))
# Namespace(algorithm='S',
#   foo={'slow': True, 'type': 'S', 'quick': False})

For both the optional and positional, the lower case default is converted into 
an upper case letter.

For the positional with nargs='?', the action is called with the converted 
default value.

But for the optional, the converted default is assigned to the dest
   algorithm='S'
but action is not called, which would have assigned
   algorithm={'type': 'S', 'quick': False, 'slow': True}

That is consistent with what I remember from the code.  A next function 
'take_action' is called only if there is an appropriate argument string.  For 
this optional that would be '-a' (or the likes).  For the '?' positional and 
empty argument list enough.

There is a relatively recent change that delayed when a default was converted 
by type (so a filetype wouldn't be opened unnecessarily).  But I can't think 
anyway that the action would be invoked on the default in the absence of '-a'.

In this example, would it be possible shift code from the custom action to the 
custom type?

--
Added file: http://bugs.python.org/file30944/issue18467.py

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18467
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18349] argparse usage should preserve () in metavars such as range(20)

2013-07-15 Thread paul j3

paul j3 added the comment:

This issue should also preserve a metavar like: '(one)two', i.e. '(' at the 
start.  

In http://bugs.python.org/issue10984 these _re replacements are applied to 
individual action strings as well as the whole usage line.  So if () are to be 
removed from '[-h] (-y)', they should also be removed from '(-y)'.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18349
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11874] argparse assertion failure with brackets in metavars

2013-07-14 Thread paul j3

paul j3 added the comment:

If the arg_parts are passed through the same cleanup as the 'text' (and empty 
strings removed), then 

text = ' '.join(arg_parts)

In that case there would be no need to return both (text, arg_parts).

Parenthesis in the metavar could also create the problem addressed in this 
thread, except as noted in http://bugs.python.org/issue18349 that 'text' 
cleanup removes them.

nargs='*' or '+' or integer is another way in which [] could be introduced into 
the metavar.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11874
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2013-07-14 Thread paul j3

paul j3 added the comment:

This patch adds a MultiGroupHelpFormatter that formats groups even if they 
share actions or the actions are not in the same order as in the parse._actions 
list.  It sorts the groups so positional actions, if any appear in the correct 
order.

A long test case generates this help:

usage: PROG [-h] [-a A | -c C] [-a A | -d D] [-a A | -b B] [-b B | -d D]
[-d D | x] foo [-b B | y]

positional arguments:
  x   x help
  foo foo help
  y   y help

optional arguments:
  -h, --help  show this help message and exit
  -a Aa help
  -b Bb help
  -c Cc help
  -d Dd help

In the 2nd usage line, the 2 groups, and action foo, are shown in the order in 
which x, foo, y were defined (and hence will be parsed), even though the groups 
were not defined in that order.

The default formatter could not format these groups, generating '[-h] [-a A] 
[-b B] ... x foo y' instead.

I have included the latest patch from http://bugs.python.org/issue11874.  This 
splits the usage line generated by _format_actions_usage into parts that are 
groups or independent actions.  The goal there is to correctly split long usage 
lines into multiple lines.  Here it makes it easier to format groups and 
actions in new order.

If existing actions are added to new group as in the original patch for this 
issue, that group gets a no_usage = True attribute.  The default formatter then 
will not attempt to format this group. The MultiGroupHelpFormatter ignores this 
attribute.

This patch needs better documentation. Test cases also need refinement, 
improving the names, and eliminating redundancies.  Some of the new tests are 
copies of existing ones, but using the new formatter.

--
Added file: http://bugs.python.org/file30921/multigroup_1.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11874] argparse assertion failure with brackets in metavars

2013-07-14 Thread paul j3

paul j3 added the comment:

I just filed a patch with http://bugs.python.org/issue10984 (argparse 
add_mutually_exclusive_group should accept existing arguments to register 
conflicts) that includes the latest patch from this issue.  I tweaked it so 
_format_actions_usage only returns arg_parts.  The block of _re. statements (# 
clean up separators for mutually exclusive groups) are in a nested function so 
it can be applied to each of the parts.

In that issue I wrote a custom formatter that handles groups even if they share 
actions, or the action order does not match definition order.  For that it is 
easier to work with the arg_parts as generated here rather than the whole usage 
line.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11874
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue11874] argparse assertion failure with brackets in metavars

2013-07-13 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue11874
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2013-07-12 Thread paul j3

paul j3 added the comment:

While playing with some examples, I found that exclusive group formatting has 
another failure case.  If the usage line is long enough to wrap, optionals and 
positionals are formatted separately, with positionals appearing on a separate 
line(s).  That means that if a group includes a positional, it will not be 
marked.

So (shortening lines for convenience sake), instead of:

usage: [-h] ... (-a | -b | x)

we get

usage: [-h] ... [-a] [-b]
   x

This is true even if arguments are added to the group in the normal way.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2013-07-11 Thread paul j3

paul j3 added the comment:

One usage option is to make a subclass of HelpFormatter (the accepted way of 
customizing a formatter), and write a function that formats each group 
independently.  For the example case, the resulting format might be:

   usage: PROG [-h] [-b] [-a | -c] [-a | -d]

-h and -b are not part of any group.  These are followed by the two groups.  -a 
is repeated because it appears in both groups.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue10984] argparse add_mutually_exclusive_group should accept existing arguments to register conflicts

2013-07-09 Thread paul j3

paul j3 added the comment:

This approach of simply adding the existing actions to the group's 
_group_actions works fine, at least when it comes catching the error.

It may be difficult to get a useful usage line.  In usage, arguments appear in 
the order in which they were created, optionals first, positionals after.  
Group notation is added if the subset of the arguments appear in its list in 
the same order.

In the patch .rst, 

usage: PROG [-h] (--foo | --bar) [--baz]

the foo,bar group is marked correctly; the foo,baz group is not contiguous and 
is omited.

In bethard's example neither group will be marked
(class TestMutuallyExclusiveGroupWithExistingArguments)

But the problem isn't just with adding existing arguments.

class TestMutuallyExclusiveOptionalsMixed illustrates this with a case where 
group and parser arguments overlap.

In class TestMutuallyExclusiveOptionalsAndPositionalsMixed, the mix of 
optionals and positionals makes group marking impossible.

If the groups are in order, but overlap, usage can be a confusing mix

Groups ab, bc, cd, produce: 
[-a A | [-b B | [-c C | -d D]

But if created in a different order, the usage can be: 
[-a A | [-b B | -c C] -d D]

So there are 2 issues
   - if groups are not continuous or overlap, what is a meaningful usage?
   - any choice is likely to require a major reworking of the formatting logic.

Since confusing group markings are worse than none, a first step might be to 
flag a group added via this patch as 'do not mark'.  Also add a note to the 
documentation that user may need to write their own grouping  instructions (in 
usage, description or epilog).

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue10984
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16468] argparse only supports iterable choices

2013-07-08 Thread paul j3

paul j3 added the comment:

This patch generally deals with the choices option, and specifically the
problems with formatting long lists, or objects that have __contains__
but not __iter__.  But it also incorporates issues 9849 (better add_argument 
testing) and 9625 (choices with *).  It may be too broad for this issue, but 
the changes all relate to 'choices'.

As noted by other posters, there are 3 places where choices is formatted with a 
comprehension.  I have refactored these into one _format_choices function.

_format_choices() is a utility function that formats the choices by
iteration, and failing that using repr().  It raises an error if choices does 
not even have a __contains__.  It also has a summarize option 
({1,2,3,...,19,20}). I did not make this an action method because it only uses 
the choices object.

_metavar_formatter() - calls _format_choices for Usage with the default compact 
form.  Its use of metavar gives the user full control of the choices display.

_expand_help() - calls _format_choices with the looser format.  This form is 
used only if the user puts '%(choices)s' in the help string.  This is not 
documented, and only appears a few times in the test file.  Again the user has 
ultimate control over the contents.

_check_value() - calls _format_choices with a 'summarize=15' option.  Normally 
this error message appears with the usage message.  So it does not need to use 
the metavar.  

The MetavarTypeHelpFormatter subclass is an example of how formats can be 
customized without changing normal behavior.  Such a subclass could even be 
used to set custom parameters, or modify any of the above methods.


other changes:

formatter _format_actions_usage() - I tweaked the regex that trims excess 
notation from mutually exclusive groups.  This removed '()' from other parts of 
the usage line, for example a metavar like 'range(20)'.  Issue 18349.

formatter _format_args() - I included issue 9849 changes which improve
testing for nargs, and array metavars.  This calls the _metavar_formatter.  
Thus any errors in formatting choices pass back through this.

Issue 9849 also changes container add_argument() to call the parser
_check_argument().  This in turn calls _format_args() to test action
options like nargs, metavars, and now choices.  If there are problems
it raises an ArgumentError.

parser _get_values() - issue 9625 changes this to correctly handle choices when 
nargs='*'.

parser _check_value() - I rewrote this to give better errors if there
are problems with __contains__.  If choices is a string (e.g. 'abc') it
converts it to a list, so __contains__ is more consistent.  For example,
'bc' in 'abc' is True, but 'bc' in ['a','b','c'] is False (issue 16977)

--
test_argparse

change examples with string choices to lists

class TestAddArgumentMetavar
change EXPECTED_MESSAGE and EXPECTED_ERROR to reflect issue 9849 changes

class TestMetavarWithParen
tests 'range(n)' choices
makes sure () in the metavar are preserved
tests that metavar is used in Usage as given
tests summarized list of choices in the error message
tests the %(choices)s help line case

class TestNonIterableChoices
tests a choices container that has __contains__ but not __iter__
tests that repr() is used as needed

class TestBareChoices
tests a class without even __contains__
tests for an add_argument error

class TestStringChoices
tests the expansion of 'abc' to ['a','b','c']

--
Added file: http://bugs.python.org/file30872/choice2.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16468
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16977] argparse: mismatch between choices parsing and usage/error message

2013-07-08 Thread paul j3

paul j3 added the comment:

I just posted a patch to http://bugs.python.org/issue16468 that deals with this 
'bc' in 'abc' issue.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16977
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18349] argparse usage should preserve () in metavars such as range(20)

2013-07-08 Thread paul j3

paul j3 added the comment:

I just posted a patch to http://bugs.python.org/issue16468 that uses (and 
tests) this fix.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18349
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9625] argparse: Problem with defaults for variable nargs when using choices

2013-07-08 Thread paul j3

paul j3 added the comment:

The patch I just posted to http://bugs.python.org/issue16468 uses this fix.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9625
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16418] argparse with many choices can generate absurdly long usage message

2013-07-08 Thread paul j3

paul j3 added the comment:

In the patch I just posted to http://bugs.python.org/issue16468 I address this 
long list issue in several ways:

In the Usage line, the metavar gives the user an alternative

In the expanded help line the user can just omit the '%(choices)s' 

In _check_value(), I implemented a numpy like summarize format for choice lists 
longer than 15   '{1,2,3,...,18,19}'.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16418
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9849] Argparse needs better error handling for nargs

2013-07-08 Thread paul j3

paul j3 added the comment:

I included this patch (with minor changes) in a patch that I just posted to 
http://bugs.python.org/issue16468.  That issue deals with the argument choices 
option, which can be tested along with nargs and metavars.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9849
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16977] argparse: mismatch between choices parsing and usage/error message

2013-07-04 Thread paul j3

paul j3 added the comment:

Changing _check_value from:

def _check_value(self, action, value):
# converted value must be one of the choices (if specified)
if action.choices is not None and value not in action.choices:
...

to

def _check_value(self, action, value):
# converted value must be one of the choices (if specified)
if action.choices is not None:
choices = action.choices
if isinstance(choices, str):
choices = list(choices)
if value not in action.choices:
...

would correct the string search without affecting other types of choices.

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16977
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18349] argparse usage should preserve () in metavars such as range(20)

2013-07-03 Thread paul j3

New submission from paul j3:

As discussed in issue 16468, a metavar may be used to provide an alternative 
representation of a choices option.  However if a metvar like 'range(20)' is 
used, usage formatter strips off the '()'.

 parser.add_argument('foo', type=int, 
choices=range(20), metavar='range(0,20)')
 parser.format_usage()
# expect: 'usage: PROG [-h] range(0,20)\n'
# actual: 'usage: PROG [-h] range0,20\n'

This is done by a line in the help formater that removes excess mutually 
exclusive group notation:

HelpFormatter._format_actions_usage
   ...
   text = _re.sub(r'\(([^|]*)\)', r'\1', text)

A solution is to change this line to distinguish between a case like ' (...)' 
and 'range(...)'

text = _re.sub(r'( )\(([^|]*)\)', r'\1\2', text)

--
files: metaparen.patch
keywords: patch
messages: 19
nosy: paul.j3
priority: normal
severity: normal
status: open
title: argparse usage should preserve () in metavars such as range(20)
Added file: http://bugs.python.org/file30754/metaparen.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18349
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue18349] argparse usage should preserve () in metavars such as range(20)

2013-07-03 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
components: +Library (Lib)
type:  - behavior
versions: +Python 3.4

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue18349
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16933] argparse: remove magic from examples

2013-07-03 Thread paul j3

paul j3 added the comment:

There still is one choices='XYZ' example (16.4.5.1. Sub-commands) but the 
focus isn't on choices.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16933
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16977] argparse: mismatch between choices parsing and usage/error message

2013-07-03 Thread paul j3

paul j3 added the comment:

test_argparse.py has some choices='abc' cases.  

In those should parser.parse_args(['--foo','bc']) be considered a success or 
failure?  

The underlying issue here is that while string iteration behaves like list 
iteration, string __contains__ looks for substrings, not just one character 
that matches.  (String __contains__ also returns a TypeError if its argument is 
not a string.)

But other than removing poor examples in documentation and tests, I'm not sure 
this issue requires a change.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16977
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9625] argparse: Problem with defaults for variable nargs when using choices

2013-07-03 Thread paul j3

paul j3 added the comment:

Change choices='abc' to choices=['a', 'b', 'c'], as discussed in issue 
16977  (use of string choices is a bad example)

--
Added file: http://bugs.python.org/file30762/issue9625_2.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9625
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16468] argparse only supports iterable choices

2013-07-03 Thread paul j3

paul j3 added the comment:

I'd suggest not worrying about the default metavar in the _expand_help() 
method.  The formatted choice string created in that method is only used if the 
help line includes a '%(choices)s' string.  The programmer can easily omit that 
if he isn't happy with the expanded list.

TestHelpVariableExpansion is the only test in test_argparse.py that uses it.

Sig('--foo', choices=['a', 'b', 'c'],
help='foo %(prog)s %(default)s %(choices)s')

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16468
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16468] argparse only supports iterable choices

2013-07-01 Thread paul j3

paul j3 added the comment:

chris.jerdonek wrote:
Also, to answer a previous question, the three places in which the choices 
string is used are: in the usage string (separator=','), in the help string 
when expanding %(choices)s (separator=', '), and in the error message text 
(separator=', ' with repr() instead of str()).

In the usage string, the ',' is used to make a compact representation of the 
choices.  The ', ' separator is used in the help line, where space isn't as 
tight.  

This 'choices formatting' is called during 'add_argument()' simply as a side 
effect of checking for valid parameters, especially 'nargs' (that it, is an 
integer or an acceptable string).  Previously 'nargs' errors were not caught 
until 'parse_args' was used.   This is discussed in

http://bugs.python.org/issue9849  Argparse needs better error handling for nargs

http://bugs.python.org/issue16970  argparse: bad nargs value raises misleading 
message 

On the issue of what error type to raise, my understanding is that 
'ArgumentError' is the preferred choice when it affects a particular argument.  
parse_args() nearly always raises an ArgumentError.  Once add_argument has 
created an action, it too can raise an ArgumentError.  ArgumentError provides a 
standard way of identifying which action is giving the problem.
  
While testing 'metavar=range(0,20)', I discovered that the usage formatter 
strips off parenthesis. A regex expression that removes 
excess 'mutually exclusive group' notation is responsible for this.  The simple 
fix is to modify the regex so it distinguishes between ' (...)' and 
'range(...)'.  I intend to create a new issue for this, since it affects any 
metavar the includes ().

--

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16468
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9938] Documentation for argparse interactive use

2013-07-01 Thread paul j3

paul j3 added the comment:

The exit and error methods are mentioned in the 3.4 documentation, but there 
are no examples of modifying them.

16.4.5.9. Exiting methods
ArgumentParser.exit(status=0, message=None)
ArgumentParser.error(message)

test_argparse.py has a subclass that redefines these methods, though I think it 
is more complex than necessary.

class ErrorRaisingArgumentParser(argparse.ArgumentParser):

In http://bugs.python.org/file30204/test_intermixed.py , part of 
http://bugs.python.org/issue14191 , which creates a parser mode that is closer 
to optparse in style, I simply use:

def error(self, message):
usage = self.format_usage()
raise Exception('%s%s'%(usage, message))
ArgumentParser.error = error

to catch errors.

https://github.com/nodeca/argparse a Javascript port of argparse, adds a 
'debug' option to the ArgumentParser, that effectively redefines this error 
method.  They use that extensively in testing.

Another approach is to trap the sysexit.  Ipython does that when argparse is 
run interactively.

Even the simple try block works, though the SystemExit 2 has no information 
about the error.

try:
args = parser.parse_args('X'.split())
except SystemExit as e:
print(e)

Finally, plac ( https://pypi.python.org/pypi/plac ) is a pypi package that is 
built on argparse.  It has a well developed interactive mode, and integrates 
threads and multiprocessing.

--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9938
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue16418] argparse with many choices can generate absurdly long usage message

2013-06-29 Thread paul j3

Changes by paul j3 ajipa...@gmail.com:


--
nosy: +paul.j3

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue16418
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue9625] argparse: Problem with defaults for variable nargs when using choices

2013-06-27 Thread paul j3

paul j3 added the comment:

I've added 2 more tests, 

one with default='c', which worked before.

one with default=['a','b'], which only works with this change.

http://bugs.python.org/issue16878 is useful reference, since it documents
the differences between nargs=? and nargs=*, and their handling of
their defaults.

--
Added file: http://bugs.python.org/file30709/issue9625_1.patch

___
Python tracker rep...@bugs.python.org
http://bugs.python.org/issue9625
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



<    2   3   4   5   6   7   8   >