G. Ballegeer
G. Ballegeer

Reputation: 91

package_dir in setup.py not working as expected

I'm trying to let users write code as a python module (folder with __init__.py defined) under whatever folder name they see fit. After that I want to install that module as a python package but define the import name myself.

The folder structure would be like this:

project_name/
    user_defined_name/
        __init__.py
        ...
    setup.py

According to this I should be able to add this to my setup.py to get it working:

setuptools.setup(
    package_dir={'my_defined_name': 'user_defined_name'},
    packages=['user_defined_name']
)

But the only way that I was able to access the code was by using import user_defined_name. I tried installing the package without -e but that gave the same result. Leaving the packages=['..'] out of the setup functions also did not change the result.

My question is kind of the same as this one and there the only answers seem to be to change folder names and that is something that I would like to avoid. That question mentioned that it might be due to a problem in setuptools but that seemed fixed 3 years ago.

Upvotes: 9

Views: 4605

Answers (2)

RACKGNOME
RACKGNOME

Reputation: 1143

@Oliver's answer here clarified this for me.

My TLDR is that to support both releases (python setup.py install and pip install .) and editable installs (python setup.py develop and pip install -e .) you must change your file structure to

project_name
    setup.py 
    user_defined_name
        my_defined_name
            __init__.py
            ... 
    docs 
    tests

and your setup.py to

setuptools.setup(
    package_dir={'': 'user_defined_name'},
    packages=['my_defined_name']
)

You can support just releases (NOT editable installs) with

project_name
    setup.py 
    user_defined_name
        __init__.py
        ... 
    docs 
    tests
setuptools.setup(
    package_dir={'my_defined_name': 'user_defined_name'},
    packages=['my_defined_name']
)

Upvotes: 6

sinoroc
sinoroc

Reputation: 22275

In short, it looks like you need something like that in your setup.py:

setuptools.setup(
    package_dir={
        'my_defined_name': 'user_defined_name',
    },
    packages=[
        'my_defined_name',
    ],
)

as Ilia Novoselov said in a comment to your question.

This should work, if you package and install the project normally. You would be able to import my_defined_name.

Although, note that as far as I can tell, this will not work if you use an editable installation (python setup.py develop or python -m pip install --editable .). It will be impossible to import my_defined_name, but you would be able to import user_defined_name, which is not what you want.

Upvotes: 5

Related Questions