From a0590993ec3e82b96d92a77815d426f1dec32965 Mon Sep 17 00:00:00 2001 From: meowmeow Date: Fri, 23 Dec 2022 11:26:11 +0000 Subject: [PATCH 1/2] Support case-insensitive usage --- fire/core.py | 19 +++++++++++++++++++ fire/fire_test.py | 12 ++++++++++++ fire/test_components.py | 7 +++++++ 3 files changed, 38 insertions(+) diff --git a/fire/core.py b/fire/core.py index c1e97367..8e7a5c8b 100644 --- a/fire/core.py +++ b/fire/core.py @@ -515,12 +515,27 @@ def _Fire(component, args, parsed_flag_args, context, name=None): else: component_dict = component + lowered_component_dict = dict((str(k).lower(), str(v).lower()) + for k,v in component_dict.items()) + if target in component_dict: component = component_dict[target] handled = True elif target.replace('-', '_') in component_dict: component = component_dict[target.replace('-', '_')] handled = True + elif target in lowered_component_dict: + for key, value in component_dict.items(): + if target == str(key).lower(): + component = component_dict[key] + handled = True + break + elif (target.lower() + in lowered_component_dict) and target != target.lower(): + print('NOTE: Consider using the correct capitalization for {}'.format( + target)) + error = FireError('Ambiguous member access:', target) + candidate_errors.append((error, initial_args)) else: # The target isn't present in the dict as a string key, but maybe it is # a key as another type. @@ -652,6 +667,10 @@ def _GetMember(component, args): for arg_name in arg_names: if arg_name in members: return getattr(component, arg_name), [arg], args[1:] + else: + for member in members: + if arg_name == member.lower(): + return getattr(component, member), [arg], args[1:] raise FireError('Could not consume arg:', arg) diff --git a/fire/fire_test.py b/fire/fire_test.py index 8b904c29..a501da96 100644 --- a/fire/fire_test.py +++ b/fire/fire_test.py @@ -503,6 +503,18 @@ def testSingleCharFlagParsingCapitalLetter(self): fire.Fire(tc.CapitalizedArgNames, command=['sum', '-D', '5', '-G', '10']), 15) + def testCaseInsensitiveUsage(self): + self.assertEqual( + fire.Fire(tc.CapitalizedFunctionNames, command=['alpha']), 'alpha') + self.assertEqual( + fire.Fire(tc.CapitalizedFunctionNames, command=['Alpha']), 'Alpha') + self.assertEqual( + fire.Fire(tc.CapitalizedFunctionNames, + command=['beta']), 'Beta') + with self.assertRaisesFireExit(2): + # Ambiguous member access + fire.Fire(tc.CapitalizedFunctionNames, command=['ALPHA']) + def testBoolParsingWithNo(self): # In these examples --nothing always refers to the nothing argument: def fn1(thing, nothing): diff --git a/fire/test_components.py b/fire/test_components.py index 5fcb056e..7cfb98f3 100644 --- a/fire/test_components.py +++ b/fire/test_components.py @@ -148,6 +148,13 @@ class CapitalizedArgNames(object): def sum(self, Delta=1.0, Gamma=2.0): # pylint: disable=invalid-name return Delta + Gamma +class CapitalizedFunctionNames(object): + def alpha(self): + return 'alpha' + def Alpha(self): + return 'Alpha' + def Beta(self): + return 'Beta' class Annotations(object): From 71c46c67e81ffbf12ef8e07c2d6d978857646655 Mon Sep 17 00:00:00 2001 From: meowmeow Date: Fri, 23 Dec 2022 13:17:11 +0000 Subject: [PATCH 2/2] Support case-insensitive usage --- fire/core.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fire/core.py b/fire/core.py index 8e7a5c8b..3cf7cc35 100644 --- a/fire/core.py +++ b/fire/core.py @@ -534,7 +534,7 @@ def _Fire(component, args, parsed_flag_args, context, name=None): in lowered_component_dict) and target != target.lower(): print('NOTE: Consider using the correct capitalization for {}'.format( target)) - error = FireError('Ambiguous member access:', target) + error = FireError('Ambiguous component access:', target) candidate_errors.append((error, initial_args)) else: # The target isn't present in the dict as a string key, but maybe it is @@ -671,6 +671,11 @@ def _GetMember(component, args): for member in members: if arg_name == member.lower(): return getattr(component, member), [arg], args[1:] + # The member exists, but the capitalization is incorrect. + elif arg_name.lower() == member.lower(): + print('NOTE: Consider using the correct capitalization for {}'.format( + arg_name)) + raise FireError('Ambiguous member access:', arg_name) raise FireError('Could not consume arg:', arg)