David
David

Reputation: 632

Relative import doesn't work : ImportError: attempted relative import with no known parent package

This are the files:

parent_directory:

enter image description here

parent_directory/ecommerce:

enter image description here

parent_directory/ecommerce/payments:

enter image description here

What I'm trying to do is to use a relative import in products.py in order to import database.py. I know that I can just write import database but I want to learn relative imports. I've also tried to import main.py from the top level directory, parent_directory, but that doesn't work either so I thought I'll just try to do the easiest relative import possible and that is, importing a file from the same package.

This is the code for products.py inside parent_directory/ecommerce:

from .database import Database

class Product:
    pass

And this is the code from the database.py file inside parent_directory/ecommerce:

if __name__ == "__main__":
    import products

    x = products.Product()

class Database:
    pass

print("file : {0:<35} || name : {1:<20} || package : {2:<20}".format(
    str(__file__).split("\\")[-1],
    str(__name__),
    str(__package__),
))

I tried several things like:

Here is my init.py file from parent_directory/ecommerce:

__all__ = ["database", "products"]
__package__ = "ecommerce"

No matter what I do, I always get this error: ImportError: attempted relative import with no known parent package. I know that this question has been asked before. I've tried many things out but nothing worked. Do you have any idea how to fix this ?

Upvotes: 0

Views: 2560

Answers (2)

David
David

Reputation: 632

I've found a way to import files from parent directories, since it's very easy to import them from sub-packages by using absolute imports.

# inside parent_directory/ecommerce/products.py trying to import parent_directory/main.py
import sys
import os

current_file = os.path.realpath(__file__)
current_dir_ecommerce = os.path.dirname(current_file)
parent_dir_parent_directory = os.path.dirname(current_dir_ecommerce)
sys.path.insert(0, parent_dir_parent_directory)

import main # works

I just added the parent directory to sys.path.

Upvotes: 0

David
David

Reputation: 632

I found the solution to my problem. I have to be outside the package and use -m and instead of using / to send the path, I have to use . instead so :

python -m parent_directory.ecommerce.products

This will fix the problem but I have to execute this line outside the top-level package ( in my case, the top level package is parent_directory ).

# Inside products.py
from .database import Database # works
from ..main import SomeRandomClass # works

class Product:
    pass

Upvotes: 1

Related Questions