Skip to content

Commit a172e32

Browse files
committed
Support SkipParse decorator
1 parent 8a41c91 commit a172e32

File tree

3 files changed

+43
-4
lines changed

3 files changed

+43
-4
lines changed

fire/core.py

+23-4
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,18 @@ def _MakeParseFn(fn, metadata):
725725
required_kwonly = set(fn_spec.kwonlyargs) - set(fn_spec.kwonlydefaults)
726726

727727
def _ParseFn(args):
728-
"""Parses the list of `args` into (varargs, kwargs), remaining_args."""
728+
"""Parses the list of `args` into (varargs, kwargs), consumed_args, remaining_args."""
729+
730+
skip_parse = metadata.get(decorators.SKIP_PARSE, False)
731+
732+
if skip_parse:
733+
kwargs = {}
734+
remaining_kwargs = []
735+
remaining_args = []
736+
varargs = consumed_args = args[:]
737+
capacity = False
738+
return (varargs, kwargs), consumed_args, remaining_args, capacity
739+
729740
kwargs, remaining_kwargs, remaining_args = _ParseKeywordArgs(args, fn_spec)
730741

731742
# Note: _ParseArgs modifies kwargs.
@@ -757,8 +768,16 @@ def _ParseFn(args):
757768
varargs = parsed_args + varargs
758769
remaining_args += remaining_kwargs
759770

760-
consumed_args = args[:len(args) - len(remaining_args)]
761-
return (varargs, kwargs), consumed_args, remaining_args, capacity
771+
sorted_remaining_args = []
772+
consumed_args = []
773+
for arg in args:
774+
if arg in remaining_args:
775+
sorted_remaining_args.append(arg)
776+
remaining_args.remove(arg)
777+
else:
778+
consumed_args.append(arg)
779+
780+
return (varargs, kwargs), consumed_args, sorted_remaining_args, capacity
762781

763782
return _ParseFn
764783

@@ -992,4 +1011,4 @@ def _ParseValue(value, index, arg, metadata):
9921011
elif default is not None:
9931012
parse_fn = default
9941013

995-
return parse_fn(value)
1014+
return parse_fn(value)

fire/decorators.py

+8
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

+12
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)