python-3.xsetup.pypython-packaging

Automatically extend all imports within python project by prefix


I am trying to convert my python 3.11.3 project into a package via a setup.py. The general structure is something like this

- project_name/
  - setup.py
  - project_name/
    - sub_module/
       - __init__.py
       - file_containing_class.py

When I wrote the code, I ran all the scripts from within the inner project_name folder. This was convenient because imports were much more readable like this. For instance, I could write into the __init__.py file

from sub_module.file_containing_class import SomeClass

rather than

from project_name.sub_module.file_containing_class import SomeClass

However, when I have a setup.py like

from setuptools import setup, find_packages

setup(
    name='project_name',
    version='1.0.1',
    url=None,
    author='Joe',
    packages=find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
)

I get an error for the import above

ModuleNotFoundError: No module named 'sub_module'

(presumably) because it does not have the project_name prefix. Is there a handy way how to extend all imports by project_name without manually needing to do it? Again, I find the code more readable without it, anyway.


Solution

  • Is there a handy way how to extend all imports by project_name without manually needing to do it?

    Yes. Add a file project_name/project_name/__init__.py (following your layout), with content like the following.

    from .sub_module.file_containing_class import SomeClass
    
    __all__ = [
        "SomeClass"
    ]
    

    If you do that, then after your project is installed (e.g. pip install . from the directory where setup.py lives), you'll be able to do the following (from any directory).

    from project_name import SomeClass