I am trying to run a packaged cli, which does dynamic imports. When I run the code through the main cli script it works as expected. However after I package the code up using setup.py sdist
and then install the dist tar with pip. The cli itself gives an import error ImportError: No module named
. All of the modules are in the same folder as the cli.py
file.
This is how I have created my main called cli.py
def main():
args = docopt(__doc__, version="1.0")
argv = [args['<command>']] + args['<args>']
module = importlib.import_module(args['<command>'])
print(docopt(module.__doc__, argv=argv))
if __name__ == '__main__':
main()
And my setup.py looks like this
from setuptools import setup
setup(
name='testing-cli',
version='0.0.1',
packages=['testing']
entry_points = {
'console_scripts': ['testing-cli = testing.cli:main'],
}
)
Any ideas as to why when packaged I get an import error when it is packaged but when running like ./cli.py <arg>
it imports fine?
The script will import modules from its directory, not from your current directory. That means that if you run /some/directory/cli.py module
, it will look for module
in /some/directory/module.py
.
I presume that you're running cli.py
from the directory with the other modules, but when it gets installed, testing-cli
goes to some /usr/local/bin
which doesn't contain the other modules. They are instead stored in a testing
package on sys.path
. So you actually need to do this:
importlib.import_module("testing." + args['<command>'])
or possibly through a relative import:
importlib.import_module("." + args['<command>'], package="testing")
This will mean that your script will stop working when you run it from the build directory, unless you installed the package. To fix that, use python setup.py develop
, which will mock-install the package onto sys.path
.
(Or more straightforward, export PYTHONPATH=.
That will put your current directory on sys.path
and make the testing
subdir visible as a package)