14

I have a project with this setup.py file:

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="",
    version="0.0.1",
    author="",
    author_email="",
    description="",
    long_description=long_description,
    long_description_content_type="text/markdown",
    packages=setuptools.find_packages(where="./src", exclude=("./tests",)),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.8',
)

This is my project directory structure (first two levels):

$ tree -L 2
.
├── README.md
├── setup.py
├── src
│   └── my_pkg
└── tests
    ├── conftest.py
    ├── data
    ├── __init__.py
    ├── integration
    ├── __pycache__
    └── unit

When I run any setuptools command, I get the following error:

$ python setup.py build
running build
running build_py
error: package directory 'my_pkg' does not exist

The same happens for other commands like python setup.py develop and python setup.py bdist-wheel.

I suspect that it has to do with the src directory, as specified in the find_packages(where="./src") call in the setup.py. However, I've been following the documentation, and it does look the the my_pkg module is discovered at some point.

Why does build_py fail to find it?

Carsten
  • 1,912
  • 1
  • 28
  • 55
  • Change to ```packages=setuptools.find_packages(where="src", exclude=("tests",))``` – Sreeram TP Oct 05 '20 at 10:55
  • @SreeramTP That makes no difference. – Konrad Rudolph Oct 05 '20 at 10:58
  • 2
    ```setuptools.setup( name="", version="0.0.1", author="", author_email="", description="", long_description=long_description, long_description_content_type="text/markdown", package_dir={"": str("src")}, classifiers=[ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ], python_requires='>=3.8', )``` Can you try this? @Carsten – Sreeram TP Oct 05 '20 at 11:01
  • Adding the `package_dir` seems to do the trick indeed. – Carsten Oct 05 '20 at 11:12

1 Answers1

19

find_packages() automatically generates package names. That is, in your case all it does is generate ['my_pkg']. It doesn't actually tell setup() where to find my_pkg, just that it should expect to find a package called my_pkg somewhere. You have to separately tell setup() where it should look for packages. Is this confusing and counter intuitive? Yes. Anyway, you can tell setup() where to find my_pkg by using the package_dir argument. eg.

package_dir={"":"src"}
Dunes
  • 37,291
  • 7
  • 81
  • 97
  • hi, is there a way to do this with `setup.cfg`? – Giuppox Mar 14 '21 at 20:43
  • 4
    https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html#using-a-src-layout – Dunes Mar 15 '21 at 10:07
  • Actually, I do not find the documentation very clear for projects with flat structures. It worked for me by (instead of listing all submodules) only doing in ```setup.cfg```: ```[options]package_dir = mypkg = name_of_your_package``` – eidal May 23 '22 at 09:19