Search code examples
pythonpackagepython-wheel

AttributeError: module 'MyModule' has no attribute 'Module1'


I am trying to turn a project of mine into a package so I can deploy it as a wheel. I have a project directory setup like this:

ProjectDir
├── setup.py
├── MyModule
│   ├── __init__.py
│   ├── Module1
│   │   ├── __init__.py
│   │   ├── main.py
│   ├── Module2
│   │   ├── file1.py
│   │   ├── __init__.py
│   │   ├── file2.py
│   │   ├── file3.py
│   └── Module3
│       ├── __init__.py
│       ├── Sub1
│       │   ├── file1.py
│       │   ├── file2.py
│       │   ├── main.py
│       └── Sub2
│           ├── file1.py
│           ├── main.py
└── test
    ├── test_Module_1
    │   ├── __init__.py
    │   └── test_main.py
    ├── test_Module_2
    ...

Top level __init__.py is empty
Module 1 __init__.py file

from main import Function1

Similar for other module __init__.py files

setup.py

from setuptools import setup, find_packages
import os
import pip

setup(name='MyModule',
    description='Tool suite to run MyModule',
    packages=['MyModule'])

I can import MyModule but when I attempt to access any submodule, I get the following

AttributeError: module 'MyModule' has no attribute 'Module1' Or if I check attributes of my module, none are found.

import MyModule
dir(MyModule)

['builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'path', 'spec', 'os']


Solution

  • This is expected because by default submodules are not imported. You should import them like so to use them:

    import MyModule.Module1
    

    To change this you have to tweak the MyModule/__init__.py file by adding:

    import MyModule.Module1
    

    This way, MyModule.Module1 will be available when you import MyModule, as the __init__.py file is executed.