I have the following code in setup.py
from setuptools import setup
setup(
name='raas',
version='0.1',
description='Program to test console_scripts\'s\n.',
packages=['raas'],
entry_points={
'console_scripts': ['raas = raas.cli.entry:main',
'raas1 = raas.test:main']
},
zip_safe=True,
)
The package structure is
$ --> ls -lR
total 8
drwxr-xr-x 6 noorul wheel 192 Mar 22 01:37 raas
-rw-r--r-- 1 noorul wheel 349 Mar 22 01:37 setup.py
./raas:
total 16
-rw-r--r-- 1 noorul wheel 0 Mar 22 01:28 __init__.py
-rw-r--r-- 1 noorul wheel 103 Mar 22 01:32 __init__.pyc
drwxr-xr-x 6 noorul wheel 192 Mar 22 01:32 cli
-rw-r--r-- 1 noorul wheel 29 Mar 22 01:37 test.py
./raas/cli:
total 24
-rw-r--r-- 1 noorul wheel 0 Mar 22 01:28 __init__.py
-rw-r--r-- 1 noorul wheel 107 Mar 22 01:32 __init__.pyc
-rw-r--r-- 1 noorul wheel 37 Mar 22 01:29 entry.py
-rw-r--r-- 1 noorul wheel 234 Mar 22 01:32 entry.pyc
Contents of the entry.py and test.py are
$ --> cat raas/cli/entry.py
def main():
print "Hellow world"
$ --> cat raas/test.py
def main():
print "Test"
But after installing the package using setup.py install in a virtual env. I could only run raas1 and not raas
$ --> ./venv/bin/raas
Traceback (most recent call last):
File "./venv/bin/raas", line 11, in <module>
load_entry_point('raas==0.1', 'console_scripts', 'raas')()
File "/private/tmp/raas/venv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 480, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/private/tmp/raas/venv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2693, in load_entry_point
return ep.load()
File "/private/tmp/raas/venv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2324, in load
return self.resolve()
File "/private/tmp/raas/venv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2330, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
ImportError: No module named cli.entry
$ --> ./venv/bin/raas1
Test
Am I missing something?
What you are missing lies in the line
packages=['raas'],
You might think that this will include raas
with all its subpackages, but it doesn't! packages=['raas']
will include only raas/__init__.py
and every python module in raas
directory - in your case the test.py
. This is why raas1
command works.
However, none of the subpackages of raas
will be included, so the raas.cli
subpackage won't be installed. You should be able to verify it is missing by listing the installed files with pip
(if you have installed the package with it):
$ pip show -f raas
Name: raas
Version: ...
...
Files:
...
raas/__init__.py
raas/test.py
You should see neither raas/cli/__init__.py
nor raas/cli/entry.py
in the files list.
The obvious solution is to include raas.cli
to the packages list:
packages=['raas', 'raas.cli'],
However, it's pretty clumsy to maintain: when adding new package or renaming an existing one, you have to include the changes in the packages list in setup.py
or they will not be included in the distribution. Since you are already using setuptools
, it offers a much better solution:
from setuptools import setup, find_packages
setup(
...
packages=find_packages(),
)
The function find_packages()
will perform a recursive scan of the current directory, looking for python packages, and generate a list of qualified package names that will be included in the distribution. Read its doc for more details.