detection of program name when run with `python -m`
See original GitHub issueThe program name (referred to as prog_name
or info_name
) is the name Click uses in usage help text. If it’s not specified, Click tries to detect it by looking at sys.argv[0]
.
This works when the CLI is run as a script, either directly, or indirectly as an entry point, or as a module when the program is a single file, but fails when the program is a package and run with python -m
. In that case, Python converts the -m name
to the Python file within the package that would be executed. (The use of __file__
there is also incorrect, as that will always point to click/core.py
. There should never be a case where sys.argv
is empty. make_str
is probably not needed either.)
This leads to the following names:
python example.py
, executing a script directly -example.py
python -m example
, the single file moduleexample.py
-example.py
python -m example
, a package likeexample/__main__.py
-__main__.py
python -m example.cli
, a submodule likeexample/cli.py
-cli.py
example
, an entry point, with any of the layouts above -example
What’s usually expected is that executing a script will print the Python file name (example.py
), executing an entry point will print the entry point name (example
), and executing a module or package will print the Python command (python -m example
, python -m example.cli
)
This leads to projects that expect to be run as either an entry point or -m
writing their own wrapper around the CLI to control what name gets used. For example, Flask uses a wrapper that the entry point will call with no args, while __main__.py
or __name__ == "__main__"
will pass as_module=True
.
def main(as_module=False):
cli.main(prog_name="python -m flask" if as_module else None)
Unfortunately, detecting whether python -m
was used is really, really complicated. Luckily, I did the work already in Werkzeug’s reloader: https://github.com/pallets/werkzeug/blob/102bcda52176db448d383a9ef1ccf7e406a379eb/src/werkzeug/_reloader.py#L59. It won’t be quite the same in Click because we’re not concerned with the exact path to the python
command or script file, or with arguments, but that should be a good start. Write a function detect_program_name()
to detect this and call it in place of the existing code.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (5 by maintainers)
Here’s a simple project to test out the commands with. example.tar.gz
Now you can do different commands and changes you make to your click repo will be reflected. The command echos the detected program name.
@ovezovs thanks! @kbanc set up a windows VM and got it done 😃