Search code examples
pythonrelative-import

How to do a relative import from the parent directory?


I have searched this and found many answers, all of which tell me to do exactly what I am doing, here is my directory structure:

app/
+-- __init__.py
+-- app_manager.py
+-- app_gui/
|   +-- __init__.py
|   +-- app_gui.py

in app_gui.py I have:

import tkinter as tk
from tkinter import ttk
from app_manager import AppManager

in app manager:

class AppManager():
    def __init__(self):
    """ default constructor for app manager """

In Visual Code, it actually resolves this to an auto completion, which tells me that at least Visual Code sees it as correctly done. However, if I run this I get the following error:

ModuleNotFoundError: No Module named "app_manager"

Edit

Full stack trace when changing to from app.app_manager import AppManager:

Traceback (most recent call last):
   File ".\app_gui\app_gui.py", line 4, in <module>
     from app_manager import AppManager
ModuleNotFoundError: No module named 'app_manager' 

Solution

  • Running python code like this is hacky at best.

    Use a setup.py
    This will require some small changes but will pay immediate benefits.
    You will then be able to use your app package like any other installed package.

    New Directory Structure

    .
    ├── app
    │   ├── app_gui
    │   │   ├── app_gui.py
    │   │   └── __init__.py
    │   ├── app_manager.py
    │   └── __init__.py
    └── setup.py
    

    setup.py

    from setuptools import find_packages, setup
    
    setup(name='app',
          version='0.0.1-dev',
          description='My app package',
          install_requires=['tkinter'],
          packages=find_packages(),
          zip_safe=False)
    

    app_gui.py

    from app.app_manager import AppManager
    
    manager = AppManager()
    

    Putting it all together

    From the same dir as setup.py run:
    $> python setup.py develop

    This will symlink the package into your site-pacakges folder where you can treat it like any other package. i.e. import it using import app from scripts located anywhere on your system.