Python app install via pip3 does not install source packages

Here is my python project structure

▶ tree -L 2
.
├── Dockerfile
├── README.md
├── my_app
│   ├── __init__.py
│   ├── main.py
│   ├── settings.py
│   ├── utils.py
│   └── views.py

And part of my setup.py

    package_dir={'': 'my_app'},
    packages=find_packages(where='my_app'),
    include_package_data=True,
    python_requires='>=3.9',
    entry_points={
        'console_scripts': [
            'my-app=my_app.main:run',
        ],
pip3 install .  --force-reinstall

runs OK and I am in a virtualenv.

However, when trying to run the program

Traceback (most recent call last):
  File "/Users/myuser/myfolder/.venv/bin/my-app", line 5, in <module>
    from my_app.main import run
ModuleNotFoundError: No module named 'my_app'

I also noticed that in ls .venv/lib/python3.9/site-packages/ there are no source files of my-app, only my_app-0.0.1.dist-info file

Why is that?

Answer

You misunderstand how find_packages(where='my_app') work, see this:

find_packages(where=’.’, exclude=())
Return a list all Python packages found within directory ‘where’

This means it doesn’t mean try to find the package my_app from current folder, but try to find packages from the folder my_app, in your case, no package will be found in my_app.

So, for your case, next is enough:

setup.py:

from setuptools import setup, find_packages

setup(
    name="my-app",
    version="0.0.1",

    packages=find_packages(),
    include_package_data=True,
    entry_points={
        'console_scripts': [
            'my-app=my_app.main:run',
        ],
    }
)

Additional, if your main intention is just to include my_app, bypass others, then find_packages(include=[ syntax is what you are looking for:

setup.py:

from setuptools import setup, find_packages

setup(
    name="my-app",
    version="0.0.1",

    packages=find_packages(include=['my_app']),
    include_package_data=True,
    entry_points={
        'console_scripts': [
            'my-app=my_app.main:run',
        ],
    }
)

NOTE, don’t use package_dir={'': 'my_app'}, it will try to find my_app.my_app, unless you use package_dir={'my_app': 'my_app'}, but it’s meaningless in your case.

Leave a Reply

Your email address will not be published. Required fields are marked *