Search code examples
pythonpippython-packagingpyproject.toml

sub-package not importable after installation


I've got a package-project with the following structure:

project/
   src/
      handlers/
         __init__.py
         sqlserver.py # contains the SqlServerHandler class
      __init__.py
      project.py # contains other classes
   pyproject.toml

with pyproject.toml as:

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "project"
version = "1.0.0"
requires-python = ">=3.10.5"
authors = [{ name = "me" }]
dependencies = [
    "pyodbc"
]

I can successfuly install it with pip install c:\path\to\project, but when I try to use the handlers module it doesn't show up as if it didn't existed.

from project import SomeClass # works fine
from project.handlers.sqlserver import SqlServerHandler # does not exist

I've checked what the installer generates and the build\lib folder contains everythig so I don't quite understand what I am missing and how I can make sure the sub-modules are also importable?


Solution

  • The solution absolutely doesn't make any sense, but after many trial and errors I finally figured out how to fix that.


    First I navigated to the links provided by @sinoroc and changed the project structre as described here to make use of the autodiscovery: https://setuptools.pypa.io/en/latest/userguide/package_discovery.html#src-layout

    Since this still wasn't enough, I tried a lot of other ideas including adding this setup.py

    from setuptools import setup
    
    setup(
       packages=["src.project.handlers", "src.project.handlers.sqlserver"]
    )
    

    Well, no luck with that.

    Finally, pretty furstrated, I left the setup method empty and it worked!!!

    project/
       src/
          project/ # <-- new level
             handlers/
                __init__.py
                sqlserver.py # contains the SqlServerHandler class
             __init__.py
             project.py # contains other classes
       pyproject.toml
       setup.py # <-- new with empty setup()
    

    Now PyCharm recognizes all sub-packages and the app runs without errors.