8

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.

G. Ballegeer
  • 81
  • 2
  • 8
  • 1
    Have you tried ```packages=['my_defined_name']```? – Ilia Novoselov Nov 21 '20 at 15:29
  • You write "_python module (folder with `__init__.py` defined)_", but it is called a Python import package. A Python module is a single importable `*.py` file. – sinoroc Nov 21 '20 at 17:05
  • @IliaNovoselov is right. you probably should hange to `packages=['my_defined_name']`. – sinoroc Nov 21 '20 at 17:13
  • @IliaNovoselov I've tried the suggestion and it didn't work. – G. Ballegeer Nov 22 '20 at 16:19
  • @G.Ballegeer Make sure to clean up old attempts at packaging the project. In particular there should be a `*..egg-info` directory somewhere, make sure to delete it before recreating the distributions. – sinoroc Nov 22 '20 at 17:01
  • Your code is python 3 or 2? – Joac Nov 25 '20 at 22:49
  • @Joac It is python 3 code. – G. Ballegeer Nov 26 '20 at 09:37
  • @sinoroc I've tried in a new conda environment but I got the same problem. – G. Ballegeer Nov 26 '20 at 09:37
  • @G.Ballegeer It is difficult to help you, without knowing more details. As far as I can tell Ilia's suggestion is the right answer. If it still does not work, then there might be something else wrong that we can not see from your question and comments. -- Also be careful that `package_dir` and _editable_ installations do not mix well at all. There is basically just one `package_dir` trick that works with _editable_, it is the `src`-layout trick. Everything else, including what you are doing here, will not work. – sinoroc Nov 26 '20 at 09:42

2 Answers2

5

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.

sinoroc
  • 18,409
  • 2
  • 39
  • 70
  • Yes, indeed. The problem seems to indeed lie with the fact that I wanted to use an editable installation. Shame that the option for that doesn't seem available, but thanks for the effort! – G. Ballegeer Nov 28 '20 at 12:50
4

@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']
)
RACKGNOME
  • 1,123
  • 1
  • 8
  • 12