Skip to content

Commit f9d337b

Browse files
committed
Support SkipParse decorator
1 parent 37c4305 commit f9d337b

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

fire/core.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,18 @@ def _MakeParseFn(fn, metadata):
722722
required_kwonly = set(fn_spec.kwonlyargs) - set(fn_spec.kwonlydefaults)
723723

724724
def _ParseFn(args):
725-
"""Parses the list of `args` into (varargs, kwargs), remaining_args."""
725+
"""Parses the list of `args` into (varargs, kwargs), consumed_args, remaining_args."""
726+
727+
skip_parse = metadata.get(decorators.SKIP_PARSE, False)
728+
729+
if skip_parse:
730+
kwargs = {}
731+
remaining_kwargs = []
732+
remaining_args = []
733+
varargs = consumed_args = args[:]
734+
capacity = False
735+
return (varargs, kwargs), consumed_args, remaining_args, capacity
736+
726737
kwargs, remaining_kwargs, remaining_args = _ParseKeywordArgs(args, fn_spec)
727738

728739
# Note: _ParseArgs modifies kwargs.
@@ -754,8 +765,16 @@ def _ParseFn(args):
754765
varargs = parsed_args + varargs
755766
remaining_args += remaining_kwargs
756767

757-
consumed_args = args[:len(args) - len(remaining_args)]
758-
return (varargs, kwargs), consumed_args, remaining_args, capacity
768+
sorted_remaining_args = []
769+
consumed_args = []
770+
for arg in args:
771+
if arg in remaining_args:
772+
sorted_remaining_args.append(arg)
773+
remaining_args.remove(arg)
774+
else:
775+
consumed_args.append(arg)
776+
777+
return (varargs, kwargs), consumed_args, sorted_remaining_args, capacity
759778

760779
return _ParseFn
761780

@@ -989,4 +1008,4 @@ def _ParseValue(value, index, arg, metadata):
9891008
elif default is not None:
9901009
parse_fn = default
9911010

992-
return parse_fn(value)
1011+
return parse_fn(value)

fire/decorators.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
FIRE_METADATA = 'FIRE_METADATA'
2828
FIRE_PARSE_FNS = 'FIRE_PARSE_FNS'
2929
ACCEPTS_POSITIONAL_ARGS = 'ACCEPTS_POSITIONAL_ARGS'
30+
SKIP_PARSE = 'SKIP_PARSE'
31+
32+
33+
def SkipParse(fn):
34+
"""Set a flag to tell Fire to pass original args to decorated fn.
35+
"""
36+
_SetMetadata(fn, SKIP_PARSE, True)
37+
return fn
3038

3139

3240
def SetParseFn(fn, *arguments):

fire/decorators_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ def example7(self, arg1, arg2=None, *varargs, **kwargs): # pylint: disable=keyw
9090
return arg1, arg2, varargs, kwargs
9191

9292

93+
class SkipParseArgs(object):
94+
95+
@decorators.SkipParse
96+
def example8(self, *args):
97+
return args
98+
99+
93100
class FireDecoratorsTest(testutils.BaseTestCase):
94101

95102
def testSetParseFnsNamedArgs(self):
@@ -169,6 +176,11 @@ def testSetParseFn(self):
169176
command=['example7', '1', '--arg2=2', '3', '4', '--kwarg=5']),
170177
('1', '2', ('3', '4'), {'kwarg': '5'}))
171178

179+
def testSkipParse(self):
180+
command = ['example8', 'test', '1', '--arg2=2', '3', '4', '--kwarg=5', '--flag']
181+
self.assertEqual(
182+
core.Fire(SkipParseArgs, command=command), tuple(command[1:]))
183+
172184

173185
if __name__ == '__main__':
174186
testutils.main()

0 commit comments

Comments
 (0)