Skip to content

Commit fa57593

Browse files
greenmoon55dbieber
authored andcommitted
Do not treat arguments that start with '--' as string. (#99)
* Do not treat arguments that start with '--' as strings / values.
1 parent aff56bb commit fa57593

File tree

2 files changed

+69
-54
lines changed

2 files changed

+69
-54
lines changed

fire/core.py

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,8 @@ def _MakeParseFn(fn):
565565

566566
def _ParseFn(args):
567567
"""Parses the list of `args` into (varargs, kwargs), remaining_args."""
568-
kwargs, remaining_args = _ParseKeywordArgs(args, all_args, fn_spec.varkw)
568+
kwargs, remaining_kwargs, remaining_args = \
569+
_ParseKeywordArgs(args, all_args, fn_spec.varkw)
569570

570571
# Note: _ParseArgs modifies kwargs.
571572
parsed_args, kwargs, remaining_args, capacity = _ParseArgs(
@@ -594,6 +595,7 @@ def _ParseFn(args):
594595
varargs[index] = _ParseValue(value, None, None, metadata)
595596

596597
varargs = parsed_args + varargs
598+
remaining_args += remaining_kwargs
597599

598600
consumed_args = args[:len(args) - len(remaining_args)]
599601
return (varargs, kwargs), consumed_args, remaining_args, capacity
@@ -681,64 +683,72 @@ def _ParseKeywordArgs(args, fn_args, fn_keywords):
681683
fn_keywords: The argument name for **kwargs, or None if **kwargs not used
682684
Returns:
683685
kwargs: A dictionary mapping keywords to values.
686+
remaining_kwargs: A list of the unused kwargs from the original args.
684687
remaining_args: A list of the unused arguments from the original args.
685688
"""
686689
kwargs = {}
687-
if args:
688-
remaining_args = []
689-
skip_argument = False
690-
691-
for index, argument in enumerate(args):
692-
if skip_argument:
693-
skip_argument = False
694-
continue
695-
696-
arg_consumed = False
697-
if argument.startswith('--'):
698-
# This is a named argument; get its value from this arg or the next.
699-
got_argument = False
700-
701-
keyword = argument[2:]
702-
contains_equals = '=' in keyword
703-
is_bool_syntax = (
704-
not contains_equals and
705-
(index + 1 == len(args) or args[index + 1].startswith('--')))
706-
if contains_equals:
707-
keyword, value = keyword.split('=', 1)
708-
got_argument = True
709-
elif is_bool_syntax:
710-
# Since there's no next arg or the next arg is a Flag, we consider
711-
# this flag to be a boolean.
712-
got_argument = True
713-
if keyword in fn_args:
714-
value = 'True'
715-
elif keyword.startswith('no'):
716-
keyword = keyword[2:]
717-
value = 'False'
718-
else:
719-
value = 'True'
690+
remaining_kwargs = []
691+
remaining_args = []
692+
693+
if not args:
694+
return kwargs, remaining_kwargs, remaining_args
695+
696+
skip_argument = False
697+
698+
for index, argument in enumerate(args):
699+
if skip_argument:
700+
skip_argument = False
701+
continue
702+
703+
arg_consumed = False
704+
if argument.startswith('--'):
705+
# This is a named argument; get its value from this arg or the next.
706+
got_argument = False
707+
708+
keyword = argument[2:]
709+
contains_equals = '=' in keyword
710+
is_bool_syntax = (
711+
not contains_equals and
712+
(index + 1 == len(args) or args[index + 1].startswith('--')))
713+
if contains_equals:
714+
keyword, value = keyword.split('=', 1)
715+
got_argument = True
716+
elif is_bool_syntax:
717+
# Since there's no next arg or the next arg is a Flag, we consider
718+
# this flag to be a boolean.
719+
got_argument = True
720+
if keyword in fn_args:
721+
value = 'True'
722+
elif keyword.startswith('no'):
723+
keyword = keyword[2:]
724+
value = 'False'
720725
else:
721-
if index + 1 < len(args):
722-
value = args[index + 1]
723-
got_argument = True
726+
value = 'True'
727+
else:
728+
if index + 1 < len(args):
729+
value = args[index + 1]
730+
got_argument = True
724731

725-
keyword = keyword.replace('-', '_')
732+
keyword = keyword.replace('-', '_')
726733

727-
# In order for us to consume the argument as a keyword arg, we either:
728-
# Need to be explicitly expecting the keyword, or we need to be
729-
# accepting **kwargs.
730-
if got_argument and (keyword in fn_args or fn_keywords):
734+
# In order for us to consume the argument as a keyword arg, we either:
735+
# Need to be explicitly expecting the keyword, or we need to be
736+
# accepting **kwargs.
737+
if got_argument:
738+
skip_argument = not contains_equals and not is_bool_syntax
739+
arg_consumed = True
740+
if keyword in fn_args or fn_keywords:
731741
kwargs[keyword] = value
732-
skip_argument = not contains_equals and not is_bool_syntax
733-
arg_consumed = True
742+
else:
743+
remaining_kwargs.append(argument)
744+
if skip_argument:
745+
remaining_kwargs.append(args[index + 1])
734746

735-
if not arg_consumed:
736-
# The argument was not consumed, so it is still a remaining argument.
737-
remaining_args.append(argument)
738-
else:
739-
remaining_args = args
747+
if not arg_consumed:
748+
# The argument was not consumed, so it is still a remaining argument.
749+
remaining_args.append(argument)
740750

741-
return kwargs, remaining_args
751+
return kwargs, remaining_kwargs, remaining_args
742752

743753

744754
def _ParseValue(value, index, arg, metadata):

fire/fire_test.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -368,10 +368,15 @@ def testBoolParsingLessExpectedCases(self):
368368
fire.Fire(tc.MixedDefaults,
369369
command=['identity', 'True', '10']), (True, 10))
370370

371-
# Note: Does not return ('--test', '0').
372-
self.assertEqual(fire.Fire(tc.MixedDefaults,
373-
command=['identity', '--alpha', '--test']),
374-
(True, '--test'))
371+
# Note: Does not return (True, '--test') or ('--test', 0).
372+
with self.assertRaisesFireExit(2):
373+
fire.Fire(tc.MixedDefaults, command=['identity', '--alpha', '--test'])
374+
375+
self.assertEqual(
376+
fire.Fire(
377+
tc.MixedDefaults,
378+
command=['identity', '--alpha', 'True', '"--test"']),
379+
(True, '--test'))
375380
# To get ('--test', '0'), use one of the following:
376381
self.assertEqual(fire.Fire(tc.MixedDefaults,
377382
command=['identity', '--alpha=--test']),

0 commit comments

Comments
 (0)