Search code examples
python-3.xoopimportrelative-import

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:

  • executing products.py with -m like python -m products.py
  • creating a py venv
  • adding all and package inside the files.

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 ?


Solution

  • 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