summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsteven.bethard <devnull@localhost>2010-02-28 08:04:33 +0000
committersteven.bethard <devnull@localhost>2010-02-28 08:04:33 +0000
commitf34cf60cfcb22c8929543411c15fe662849e4a6a (patch)
tree547faf1668ffccad95edbb76ab41f1dd6aed70d8
parent22948d838fa22c160682419b4be9be7f421c5e39 (diff)
downloadargparse-f34cf60cfcb22c8929543411c15fe662849e4a6a.tar.gz
Allow single character options, e.g. '-' and '+'.
-rw-r--r--NEWS.txt1
-rw-r--r--argparse.py29
-rw-r--r--test/test_argparse.py20
3 files changed, 31 insertions, 19 deletions
diff --git a/NEWS.txt b/NEWS.txt
index c4859b5..98c7139 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -8,6 +8,7 @@ What's New in argparse 1.1
- Issue #38: Better error messages when 'dest' occurs twice for positional arguments.
- Issue #39: Better error messages for invalid actions.
- Issue #43: Deprecate ArgumentParser(..., version=XXX, ...) and friends.
+- Issue #46: Allow single character options, e.g. '-' and '+'.
- Namespace objects now support "in" (i.e. __contains__).
- Usage and help (but not version) messages are written to stdout, not stderr.
diff --git a/argparse.py b/argparse.py
index fd21104..c89618b 100644
--- a/argparse.py
+++ b/argparse.py
@@ -1394,12 +1394,6 @@ class _ActionsContainer(object):
option_strings = []
long_option_strings = []
for option_string in args:
- # error on one-or-fewer-character option strings
- if len(option_string) < 2:
- msg = _('invalid option string %r: '
- 'must be at least two characters long')
- raise ValueError(msg % option_string)
-
# error on strings that don't start with an appropriate prefix
if not option_string[0] in self.prefix_chars:
msg = _('invalid option string %r: '
@@ -1407,18 +1401,12 @@ class _ActionsContainer(object):
tup = option_string, self.prefix_chars
raise ValueError(msg % tup)
- # error on strings that are all prefix characters
- if not (_set(option_string) - _set(self.prefix_chars)):
- msg = _('invalid option string %r: '
- 'must contain characters other than %r')
- tup = option_string, self.prefix_chars
- raise ValueError(msg % tup)
-
# strings starting with two prefix characters are long options
option_strings.append(option_string)
if option_string[0] in self.prefix_chars:
- if option_string[1] in self.prefix_chars:
- long_option_strings.append(option_string)
+ if len(option_string) > 1:
+ if option_string[1] in self.prefix_chars:
+ long_option_strings.append(option_string)
# infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
dest = kwargs.pop('dest', None)
@@ -1428,6 +1416,9 @@ class _ActionsContainer(object):
else:
dest_option_string = option_strings[0]
dest = dest_option_string.lstrip(self.prefix_chars)
+ if not dest:
+ msg = _('dest= is required for options like %r')
+ raise ValueError(msg % option_string)
dest = dest.replace('-', '_')
# return the updated keyword arguments
@@ -2043,15 +2034,15 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
if not arg_string[0] in self.prefix_chars:
return None
- # if it's just dashes, it was meant to be positional
- if not arg_string.strip('-'):
- return None
-
# if the option string is present in the parser, return the action
if arg_string in self._option_string_actions:
action = self._option_string_actions[arg_string]
return action, arg_string, None
+ # if it's just a single character, it was meant to be positional
+ if len(arg_string) == 1:
+ return None
+
# if the option string before the "=" is present, return the action
if '=' in arg_string:
option_string, explicit_arg = arg_string.split('=', 1)
diff --git a/test/test_argparse.py b/test/test_argparse.py
index 290b5e9..968843c 100644
--- a/test/test_argparse.py
+++ b/test/test_argparse.py
@@ -125,6 +125,7 @@ class NS(object):
class ArgumentParserError(Exception):
def __init__(self, message, stdout=None, stderr=None, error_code=None):
+ Exception.__init__(self, message, stdout, stderr)
self.message = message
self.stdout = stdout
self.stderr = stderr
@@ -1204,6 +1205,25 @@ class TestEmptyAndSpaceContainingArguments(ParserTestCase):
]
+class TestPrefixCharacterOnlyArguments(ParserTestCase):
+
+ parser_signature = Sig(prefix_chars='-+')
+ argument_signatures = [
+ Sig('-', dest='x', nargs='?', const='badger'),
+ Sig('+', dest='y', type=int, default=42),
+ Sig('-+-', dest='z', action='store_true'),
+ ]
+ failures = ['-y', '+ -']
+ successes = [
+ ('', NS(x=None, y=42, z=False)),
+ ('-', NS(x='badger', y=42, z=False)),
+ ('- X', NS(x='X', y=42, z=False)),
+ ('+ -3', NS(x=None, y=-3, z=False)),
+ ('-+-', NS(x=None, y=42, z=True)),
+ ('- ===', NS(x='===', y=42, z=False)),
+ ]
+
+
class TestNargsZeroOrMore(ParserTestCase):
"""Tests specifying an args for an Optional that accepts zero or more"""