From a172e3212aab737f079243868a3ad5f394b1c8dd Mon Sep 17 00:00:00 2001 From: "weihong.xu" Date: Sun, 25 Sep 2022 23:58:08 +0800 Subject: [PATCH 1/3] Support SkipParse decorator --- fire/core.py | 27 +++++++++++++++++++++++---- fire/decorators.py | 8 ++++++++ fire/decorators_test.py | 12 ++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/fire/core.py b/fire/core.py index 6367262d..eb25fbe8 100644 --- a/fire/core.py +++ b/fire/core.py @@ -725,7 +725,18 @@ def _MakeParseFn(fn, metadata): required_kwonly = set(fn_spec.kwonlyargs) - set(fn_spec.kwonlydefaults) def _ParseFn(args): - """Parses the list of `args` into (varargs, kwargs), remaining_args.""" + """Parses the list of `args` into (varargs, kwargs), consumed_args, remaining_args.""" + + skip_parse = metadata.get(decorators.SKIP_PARSE, False) + + if skip_parse: + kwargs = {} + remaining_kwargs = [] + remaining_args = [] + varargs = consumed_args = args[:] + capacity = False + return (varargs, kwargs), consumed_args, remaining_args, capacity + kwargs, remaining_kwargs, remaining_args = _ParseKeywordArgs(args, fn_spec) # Note: _ParseArgs modifies kwargs. @@ -757,8 +768,16 @@ def _ParseFn(args): varargs = parsed_args + varargs remaining_args += remaining_kwargs - consumed_args = args[:len(args) - len(remaining_args)] - return (varargs, kwargs), consumed_args, remaining_args, capacity + sorted_remaining_args = [] + consumed_args = [] + for arg in args: + if arg in remaining_args: + sorted_remaining_args.append(arg) + remaining_args.remove(arg) + else: + consumed_args.append(arg) + + return (varargs, kwargs), consumed_args, sorted_remaining_args, capacity return _ParseFn @@ -992,4 +1011,4 @@ def _ParseValue(value, index, arg, metadata): elif default is not None: parse_fn = default - return parse_fn(value) + return parse_fn(value) \ No newline at end of file diff --git a/fire/decorators.py b/fire/decorators.py index b2e9b322..75fba391 100644 --- a/fire/decorators.py +++ b/fire/decorators.py @@ -27,6 +27,14 @@ FIRE_METADATA = 'FIRE_METADATA' FIRE_PARSE_FNS = 'FIRE_PARSE_FNS' ACCEPTS_POSITIONAL_ARGS = 'ACCEPTS_POSITIONAL_ARGS' +SKIP_PARSE = 'SKIP_PARSE' + + +def SkipParse(fn): + """Set a flag to tell Fire to pass original args to decorated fn. + """ + _SetMetadata(fn, SKIP_PARSE, True) + return fn def SetParseFn(fn, *arguments): diff --git a/fire/decorators_test.py b/fire/decorators_test.py index cc7d6203..4867687b 100644 --- a/fire/decorators_test.py +++ b/fire/decorators_test.py @@ -90,6 +90,13 @@ def example7(self, arg1, arg2=None, *varargs, **kwargs): # pylint: disable=keyw return arg1, arg2, varargs, kwargs +class SkipParseArgs(object): + + @decorators.SkipParse + def example8(self, *args): + return args + + class FireDecoratorsTest(testutils.BaseTestCase): def testSetParseFnsNamedArgs(self): @@ -169,6 +176,11 @@ def testSetParseFn(self): command=['example7', '1', '--arg2=2', '3', '4', '--kwarg=5']), ('1', '2', ('3', '4'), {'kwarg': '5'})) + def testSkipParse(self): + command = ['example8', 'test', '1', '--arg2=2', '3', '4', '--kwarg=5', '--flag'] + self.assertEqual( + core.Fire(SkipParseArgs, command=command), tuple(command[1:])) + if __name__ == '__main__': testutils.main() From e4a3e08afdb8d723f9984da96d2566433b964dd7 Mon Sep 17 00:00:00 2001 From: "weihong.xu" Date: Fri, 29 Mar 2024 14:10:30 +0800 Subject: [PATCH 2/3] rename SkipParse to PassThrough --- fire/decorators.py | 2 +- fire/decorators_test.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fire/decorators.py b/fire/decorators.py index 75fba391..b80d0329 100644 --- a/fire/decorators.py +++ b/fire/decorators.py @@ -30,7 +30,7 @@ SKIP_PARSE = 'SKIP_PARSE' -def SkipParse(fn): +def PassThrough(fn): """Set a flag to tell Fire to pass original args to decorated fn. """ _SetMetadata(fn, SKIP_PARSE, True) diff --git a/fire/decorators_test.py b/fire/decorators_test.py index 4867687b..40066b2e 100644 --- a/fire/decorators_test.py +++ b/fire/decorators_test.py @@ -90,9 +90,9 @@ def example7(self, arg1, arg2=None, *varargs, **kwargs): # pylint: disable=keyw return arg1, arg2, varargs, kwargs -class SkipParseArgs(object): +class PassThroughArgs(object): - @decorators.SkipParse + @decorators.PassThrough def example8(self, *args): return args @@ -176,10 +176,10 @@ def testSetParseFn(self): command=['example7', '1', '--arg2=2', '3', '4', '--kwarg=5']), ('1', '2', ('3', '4'), {'kwarg': '5'})) - def testSkipParse(self): + def testPassThrough(self): command = ['example8', 'test', '1', '--arg2=2', '3', '4', '--kwarg=5', '--flag'] self.assertEqual( - core.Fire(SkipParseArgs, command=command), tuple(command[1:])) + core.Fire(PassThroughArgs, command=command), tuple(command[1:])) if __name__ == '__main__': From 6925163b547d2f3a1c85d8c38382276083296de8 Mon Sep 17 00:00:00 2001 From: "weihong.xu" Date: Fri, 29 Mar 2024 14:14:38 +0800 Subject: [PATCH 3/3] rename SkipParse to PassThrough --- fire/core.py | 2 +- fire/decorators.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fire/core.py b/fire/core.py index eb25fbe8..820f57f4 100644 --- a/fire/core.py +++ b/fire/core.py @@ -727,7 +727,7 @@ def _MakeParseFn(fn, metadata): def _ParseFn(args): """Parses the list of `args` into (varargs, kwargs), consumed_args, remaining_args.""" - skip_parse = metadata.get(decorators.SKIP_PARSE, False) + skip_parse = metadata.get(decorators.PASS_THROUGH, False) if skip_parse: kwargs = {} diff --git a/fire/decorators.py b/fire/decorators.py index b80d0329..dccb31e2 100644 --- a/fire/decorators.py +++ b/fire/decorators.py @@ -27,13 +27,13 @@ FIRE_METADATA = 'FIRE_METADATA' FIRE_PARSE_FNS = 'FIRE_PARSE_FNS' ACCEPTS_POSITIONAL_ARGS = 'ACCEPTS_POSITIONAL_ARGS' -SKIP_PARSE = 'SKIP_PARSE' +PASS_THROUGH = 'PASS_THROUGH' def PassThrough(fn): """Set a flag to tell Fire to pass original args to decorated fn. """ - _SetMetadata(fn, SKIP_PARSE, True) + _SetMetadata(fn, PASS_THROUGH, True) return fn