Skip to content

Fix version detection when invoked with python -m <package>#1531

Closed
cjolowicz wants to merge 2 commits into
pallets:7.xfrom
cjolowicz:fix-version-python-m-package
Closed

Fix version detection when invoked with python -m <package>#1531
cjolowicz wants to merge 2 commits into
pallets:7.xfrom
cjolowicz:fix-version-python-m-package

Conversation

@cjolowicz

Copy link
Copy Markdown

click.version_option attempts to determine the version using pkg_resources when no version is passed. This fails when the program was invoked with python -m <package>.

Traceback
  Traceback (most recent call last):
    File ".../3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
      "__main__", mod_spec)
    File ".../3.7/lib/python3.7/runpy.py", line 85, in _run_code
      exec(code, run_globals)
    File ".../foobar/__main__.py", line 11, in <module>
      main()
    File ".../venv/lib/python3.7/site-packages/click/core.py", line 891, in __call__
      return self.main(*args, **kwargs)
    File ".../venv/lib/python3.7/site-packages/click/core.py", line 843, in main
      with self.make_context(prog_name, args, **extra) as ctx:
    File ".../venv/lib/python3.7/site-packages/click/core.py", line 762, in make_context
      self.parse_args(ctx, args)
    File ".../venv/lib/python3.7/site-packages/click/core.py", line 1115, in parse_args
      value, args = param.handle_parse_result(ctx, opts, args)
    File ".../venv/lib/python3.7/site-packages/click/core.py", line 1705, in handle_parse_result
      value = invoke_param_callback(self.callback, ctx, self, value)
    File ".../venv/lib/python3.7/site-packages/click/core.py", line 123, in invoke_param_callback
      return callback(ctx, param, value)
    File ".../venv/lib/python3.7/site-packages/click/decorators.py", line 295, in callback
      raise RuntimeError("Could not determine version")
  RuntimeError: Could not determine version

The reason version detection fails is that __name__ in the calling module is "__main__", while entry_point.module_name is "<package>.__main__":

if version is None:
if hasattr(sys, "_getframe"):
module = sys._getframe(1).f_globals.get("__name__")
else:
module = ""

for dist in pkg_resources.working_set:
scripts = dist.get_entry_map().get("console_scripts") or {}
for _, entry_point in iteritems(scripts):
if entry_point.module_name == module:
ver = dist.version
break

This PR fixes the issue by prefixing the module name with __package__ from the calling module, if it was "__main__" to begin with.


Minimal reproducible example:

.
├── foobar
│   ├── __init__.py
│   └── __main__.py
├── setup.cfg
└── setup.py

1 directory, 4 files
# setup.py
import setuptools
setuptools.setup()
# setup.cfg
[metadata]
name = foobar
version = 0.1.0

[options]
packages = find:
install_requires =
    click

[options.entry_points]
console_scripts =
    foobar = foobar.__main__:main
# foobar/__init__.py (empty)
# foobar/__main__.py
import click


@click.command()
@click.version_option()
def main() -> None:
    """foobar"""


if __name__ == "__main__":
    main(prog_name="foobar")

@cjolowicz cjolowicz force-pushed the fix-version-python-m-package branch from ab99870 to 58d3932 Compare April 21, 2020 03:37
@cjolowicz cjolowicz changed the base branch from master to 7.x April 21, 2020 03:37
@cjolowicz

Copy link
Copy Markdown
Author

Rebased against 7.x and added changelog.

Claudio Jolowicz added 2 commits April 28, 2020 07:08
When the program is invoked with `python -m <package>`, click.version_option
fails to determine the version using pkg_resources. The reason it fails is that
__name__ in the calling module is "__main__", while entry_point.module_name is
"<package>.__main__".

Fix this issue by retrieving __package__ from the calling module and prefixing
the module name with it, if __name__ is "__main__".
@cjolowicz cjolowicz force-pushed the fix-version-python-m-package branch from 58d3932 to cfd710f Compare April 28, 2020 05:09
@cjolowicz

Copy link
Copy Markdown
Author

Rebased to resolve conflicts in CHANGES.rst due to the release of 7.1.2.

@jcrotts

jcrotts commented Jun 15, 2020

Copy link
Copy Markdown
Contributor

Thanks for the PR. There is a new PR for replacing pkg_resources with importlib_metadata, so this probably won't be added to master. This might still be relevant for 7.x though.

#1582

@davidism

davidism commented Jun 24, 2020

Copy link
Copy Markdown
Member

This PR won't apply after #1582, but the issue still happens. I've added a commit to that PR based on this fix and listed you as co-author.

@cjolowicz

Copy link
Copy Markdown
Author

Thanks for incorporating it 🚀

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants