diff --git a/fire/core.py b/fire/core.py index 8e23e76b..22a03fba 100644 --- a/fire/core.py +++ b/fire/core.py @@ -103,7 +103,7 @@ def Fire(component=None, command=None, name=None, serialize=None): code 2. When used with the help or trace flags, Fire will raise a FireExit with code 0 if successful. """ - name = name or os.path.basename(sys.argv[0]) + name = name or _InferCommandName() # Get args as a list. if isinstance(command, str): @@ -275,6 +275,18 @@ def _PrintResult(component_trace, verbose=False, serialize=None): Display(output, out=sys.stdout) +def _InferCommandName(): + """Return a sensible CLI name when Fire is invoked via python -m package.""" + argv0 = sys.argv[0] + base = os.path.basename(argv0) + if base == '__main__.py': + package = sys.modules['__main__'].__package__ # pylint: disable=no-member + if package: + return package + return os.path.basename(os.path.dirname(os.path.abspath(argv0))) + return base + + def _DisplayError(component_trace): """Prints the Fire trace and the error to stdout.""" result = component_trace.GetResult() diff --git a/fire/fire_test.py b/fire/fire_test.py index 99b4a7c6..0b458d7b 100644 --- a/fire/fire_test.py +++ b/fire/fire_test.py @@ -21,6 +21,7 @@ import fire from fire import test_components as tc from fire import testutils +from fire.core import _InferCommandName class FireTest(testutils.BaseTestCase): @@ -57,6 +58,15 @@ def testFireDefaultName(self): stderr=None): fire.Fire(tc.Empty) + def testInferCommandNameForMainModule(self): + with mock.patch.object(sys, 'argv', ['sample/__main__.py']): + with mock.patch.object(sys.modules['__main__'], '__package__', 'sample'): + self.assertEqual(_InferCommandName(), 'sample') + + def testInferCommandNameForScript(self): + with mock.patch.object(sys, 'argv', ['sample/cli.py']): + self.assertEqual(_InferCommandName(), 'cli.py') + def testFireNoArgs(self): self.assertEqual(fire.Fire(tc.MixedDefaults, command=['ten']), 10)