shiv icon indicating copy to clipboard operation
shiv copied to clipboard

Entrypoint resolution issue

Open ipmb opened this issue 7 years ago • 2 comments

$ shiv -o glances.pyz -e glances:main glances
$ ./glances.pyz
Traceback (most recent call last):
  File "./glances.pyz/_bootstrap/__init__.py", line 125, in bootstrap
TypeError: 'module' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "./glances.pyz/__main__.py", line 3, in <module>
  File "./glances.pyz/_bootstrap/__init__.py", line 130, in bootstrap
AttributeError: module 'glances.main' has no attribute 'main'

Glances (strangely enough) has a module named main as well as a function named main. These work:

import glances.main; glances.main()
import glances; getattr(glances, "main")()

This (shiv's technique) does not:

from importlib import import_module
import_module("glances.main")()

ipmb avatar Oct 12 '18 03:10 ipmb

hey @ipmb,

I took a look at the glances project and it seems to rely on __main__.py/runpy style execution. So something like python3 -m glances works. Unfortunately this makes things slightly complicated for shiv's import_string function, but if you specify the exact namespace of the main function it works as expected:

darwin ~ $ shiv -e glances.__init__:main glances -o glances.pyz -q
darwin ~ $ ./glances.pyz --version
Glances v3.0.2 with psutil v5.4.7

(note the __init__ being explicitly included)

I toyed around with a third entry point specifier (in addition to -e and -c) for module execution (-m?). The implementation would be pretty easy (since module execution is as simple as import runpy;runpy.run_module('glances', run_name='__main__')), so that's something we could potentially add in the future.

lorencarvalho avatar Oct 12 '18 17:10 lorencarvalho

This works:

import pydoc
pydoc.locate('glances.main')()

I'm using that for a "pluggable backend" type of solution and got the inspiration here. Unfortunately it does not seem like it's documented so it might not be a viable solution.

antonagestam avatar Oct 16 '18 14:10 antonagestam