diff --git a/fire/core.py b/fire/core.py index 8e23e76b..234554ab 100644 --- a/fire/core.py +++ b/fire/core.py @@ -103,7 +103,14 @@ 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]) + if not name: + script_name = sys.argv[0] + if os.path.basename(script_name) == '__main__.py': + # If invoked via `python -m package`, use the package name rather than + # the generic `__main__.py` filename. + name = os.path.basename(os.path.dirname(os.path.abspath(script_name))) + else: + name = os.path.basename(script_name) # Get args as a list. if isinstance(command, str): diff --git a/fire/fire_test.py b/fire/fire_test.py index 99b4a7c6..263f60cb 100644 --- a/fire/fire_test.py +++ b/fire/fire_test.py @@ -57,6 +57,17 @@ def testFireDefaultName(self): stderr=None): fire.Fire(tc.Empty) + def testFireDefaultNameDunderMain(self): + # When invoked as `python -m package`, sys.argv[0] is the path to the + # package's __main__.py file. The package name should be used instead of + # `__main__.py` in the usage output. + with mock.patch.object(sys, 'argv', + [os.path.join('python-fire', 'fire', 'mypackage', + '__main__.py')]): + with self.assertOutputMatches(stdout='SYNOPSIS.*mypackage', + stderr=None): + fire.Fire(tc.Empty) + def testFireNoArgs(self): self.assertEqual(fire.Fire(tc.MixedDefaults, command=['ten']), 10)