Piotr Jurkiewicz
Piotr Jurkiewicz

Reputation: 1799

Automatic discover of Python subpackages in setup.py

I have the following project structure:

project_dir
├── my_package
│   ├── subpackage
│   │   ├── bar.py
│   │   └── __init__.py
│   ├── foo.py
│   └── __init__.py
├── not_wanted_package
│   ├── other.py
│   └── __init__.py
└── setup.py

I want to create Python package containing my_package (and all its subpackages), but not not_wanted_package. Using python3 setup.py sdist bdist_wheel.

The following setup.py works fine:

from setuptools import setup
setup(
        name='my_package',
        version='1.0',
        packages=['my_package', 'my_package.subpackage']
)

But when I will add/remove/rename any subpackage I will have to manually update this file. I can use functions provided by setuptools, but find_packages() discovers all packages (including not_wanted_package). On the other hand find_packages('my_package') discovers only subpackage.

Is there any way to use find_packages() or find_namespace_packages() to automatically discover my_package and its subpackages?

Upvotes: 2

Views: 1870

Answers (2)

phd
phd

Reputation: 94511

from setuptools import setup, find_packages

setup(
    …
    packages=find_packages(include=['my_package']),
    …
)

When keyword include is used in find_packages only such packages are included. Every other packages including not_wanted_package are not listed.

Or you can exclude it with exclude=['not_wanted_package']

Upvotes: 1

boreq
boreq

Reputation: 840

find_packages supports excluding packages according to the documentation. If that is insufficient you can still simply use find_packages but filter the output against a static list of excluded packages. setup.py is a standard Python file which means that adding your own code to it is not a problem.

from setuptools import find_packages

def filter_packages(...):
    ...

setup(
    ...
    packages=filter_packages(find_packages("src")),
    ...
)

If your problem lies only in discovering all packages and not only subpackages then see what the file structure used by werkzeug looks like. The way that repository is organised aims to eliminate problems with find_packages. As you can see the werkzeug directory in the repository is placed in an extra src directory effectively making it src/werkzeug.

https://github.com/pallets/werkzeug/blob/c6dfc4880328fe9c4558d2b2e2325761f4e17f58/setup.py#L51

Upvotes: 0

Related Questions