Search code examples
pythonpython-3.xpipsetuptoolspython-packaging

Error: package directory XYZ does not exist


I have a directory with following structure,

.
├── awesome
│   ├── alice
│   │   ├── conf.py
│   │   └── __init__.py
│   ├── bob
│   │   ├── conf.py
│   │   └── __init__.py
│   ├── conf.py
│   ├── __init__.py
│   └── john
│       ├── conf.py
│       └── __init__.py
├── not_awesome_1
│   ├── __init__.py
│   └── something.py
├── not_awesome_2
│   ├── __init__.py
│   └── something.py
└── setup.py

I want to make the awesome package to be shippable. So, I made the setup.py as below,

from setuptools import find_packages, setup

setup(
    name="my-awesome-package",
    version="0.1.0",
    description="",
    long_description="",
    license="BSD",
    packages=find_packages(where="awesome"),
    include_package_data=True,
    author="JPG",
    author_email="[email protected]",
    install_requires=[],
)

I ran the command python3 setup.py bdist_wheel and it gave me the result

running bdist_wheel
running build
running build_py
error: package directory 'alice' does not exist

What was I trying to achieve?

I wanted to decouple the awesome package and wanted to reuse it in multiple projects as I'm currently using the same in not_awesome_1 or not_awesome_2 packages.

In other words, after the successful installation of my-awesome-package I should be able to use the awesome packge as

from awesome.alice.conf import Alice

alice = Alice()

What have I tried so far?

  • replaced packages=find_packages(where="awesome"), with packages=find_packages(),, but, during the build it also includes the not_awesome_X packages as well - which is not intended.
  • Intriduced package_dir as well
    setup(
        # other options
        packages=find_packages(where="awesome"),
        package_dir={"": "awesome"},
    )
    
    But, this doesn't allow me to import my packages as from awesome.alice.conf import Alice, but, from alice.conf import Alice (ie, awesome is missing)

Questions?

  1. What was I doing wrong here?
  2. How to properly configure packages and package_dir?

Solution

  • I encountered a similar error. Try manually defining both the top-level package and the sub-packages: packages=["awesome", "awesome.alice", "awesome.bob", "awesome.john", "awesome.something.somethingelse"].

    Edit: The issue is that using the where kwarg defines the package to search in. Since you have packages in the root of the project that should not be bundled, you'll likely need to manually add the parent package's name in front of each of its sub-packages.

    from setuptools import find_packages
    
    if __name__ == "__main__":
        print(find_packages(where="awesome"))
        # ['bob', 'alice', 'john', 'john.child']
        # the problem here is that 'awesome' is the root, not the current directory containing awesome
    
        root_package = "awesome"
        print([root_package] + [f"{root_package}.{item}" for item in find_packages(where=root_package)])
        # ['awesome', 'awesome.bob', 'awesome.alice', 'awesome.john', 'awesome.john.child']
    

    Then, in your setup.py:

    ...
    root_package = "awesome"
    ...
    setup(
        # other options
        packages=[root_package] + [f"{root_package}.{item}" for item in find_packages(where=root_package)],
        # package_dir={"": "awesome"}, <- not needed
    )
    

    enter image description here