jtimmins
jtimmins

Reputation: 367

How to import from a module in the same directory?

I'm attempting to make a Python3.6 package, but have run into ModuleNotFound errors when importing from within the package. The package has the following structure:

project/
    project/
        cache/
            default.py
            interface.py
        __init__.py
        handler.py
test.py

The __init__.py file contains the following:

from .handler import Handler

def getHandler(access_token=None, **kwargs):
    return Handler(access_token, **kwargs)

And then within handler.py, I'm attempting to import from cache with the following:

from .cache.default import DefaultCache

The goal is to allow the following by client code:

import project

handler = project.getHandler()

That last import is failing, and I'm not clear why. Any ideas? TIA.

Not sure how relevant it is, but I'm testing this by running the following in the outer project directory:

> pip install .
> python3 ../test.py

This returns the following traceback (venv) Jamess-MacBook-Pro-2:project james$ python3 ../test.py Traceback (most recent call last): File "../test.py", line 1, in <module> import project File "/Users/james/Work/Project/project/venv/lib/python3.6/site-packages/project/__init__.py", line 1, in <module> from .handler import Handler File "/Users/james/Work/Project/project/venv/lib/python3.6/site-packages/project/handler.py", line 7, in <module> from .cache.default import DefaultCache ModuleNotFoundError: No module named 'project.cache'

Upvotes: 1

Views: 3053

Answers (1)

abarnert
abarnert

Reputation: 365707

From your traceback:

  File "/Users/james/Work/Project/project/venv/lib/python3.6/site-packages/project/handler.py", line 7, in <module>
    from cache.default import DefaultCache

That's not the same as the code you showed us here:

from .cache.default import DefaultCache

The .cache.default is correct—that's a relative path from within project, so it will find project.cache.default in project/cache/default.py.

The cache.default without the leading dot in your actual code is an absolute path, from any of the directories in sys.path. Since there is no file or directory named cache in any of those directories, it fails.


Meanwhile, your project directory structure doesn't seem to be the same thing you showed us either. Otherwise, import project should not find the installed version. By default (and I don't think you've done anything to change it), the first entry in sys.path "is the directory containing the script that was used to invoke the Python interpreter". Which, given the structure you posted here, means that import project should find the project subdirectory in the same directory as test.py, not the one in your venv's site-packages.

Upvotes: 5

Related Questions