Search code examples
pythonpython-2.xrelative-pathpython-packaging

How to accomplish relative import in Python


Consider:

stuff/
    __init__.py
    mylib.py
    Foo/
        __init__.py
        main.py
        foo/
            __init__.py
            script.py

script.py wants to import mylib.py.

This is just an example, but really I just want to do a relative import of a module in a parent directory. I've tried various things and get this error...

Attempted relative import beyond toplevel package

I read somewhere that the script from where the program starts shouldn't reside in the package, and I tried modifying the structure for that like so...

stuff/
    mylib.py
    foo.py // Equivalent of main.py in above
    foo/
        __init__.py
        script.py

But I got the same error.

How can I accomplish this? Is this even an adequate approach?

In Python 2.


Solution

  • After fiddling with it a bit more, I realized how to set it up, and for the sake of specificity I won't use foo bar names. My project directory is set up as...

    tools/
        core/
            object_editor/
                # files that need to use ntlib.py
                editor.py # see example at bottom
                __init__.py
            state_editor/
                # files that need to use ntlib.py
                __init__.py
            ntlib.py
            __init__.py # core is the top level package
        LICENSE
        state_editor.py # equivalent to main.py for the state editor
        object_editor.py # equivalent to main.py for the object editor
    

    A line in object_editor.py looks like...

    from core.object_editor import editor
    

    A line in editor.py looks like...

    from .. import ntlib
    

    or alternatively

    from core import ntlib
    

    The key is that in the example I gave in the question, the "main" script was being run from within the package. Once I moved it out, created a specific package (core), and moved the library I wanted the editors to share (ntlib) into that package, everything was hunky-dory.