How to Solve Attempted Relative Import With No Known Parent Package in Python

Olorunfemi Akinlua Feb 02, 2024
How to Solve Attempted Relative Import With No Known Parent Package in Python

Relative imports in Python can be tricky, especially when dealing with multiple modules within a single directory. Depending on how you design your Python codebase, you can experience an ImportError.

However, a good understanding of the import system is sufficient to prevent such errors, including the ImportError: attempted relative import with no known parent package. The error message makes it easy to troubleshoot where the problem might stem from.

In this case, it is from the non-presence of the parent package. This article showcases and explains how to solve the ImportError issue.

Use submodules to Solve the ImportError: attempted relative import with no known parent package in Python

The error ImportError: attempted relative import with no known parent package stems when we use the .module_name expression as in the code below.

import .module_name

Let’s replicate the issue by creating three files within a new directory. You can use the structure below to test it out.

The IError directory houses all the Python code, and the myPackage directory houses all the package files. Then, the [main.py](http://main.py) accesses the myPackage.py.

IError/
    myPackage/
        __init__.py
        myNewPackage.py
    main.py

To recreate the error message, we need only the __init__.py file. The __init__.py file lets the Python interpreter know that a directory contains Python module code, in this case, the myNewPackage.py.

Before we recreate the error, let’s write the code that will be contained in all three Python files.

In the myNewPackage.py file, the below code snippet is present:

def createSingleDict(name, value):
    return {"name": name, "value": value}

The __init__.py file:

from .myNewPackage import createSingleDict

The main.py file, which uses the myPackage module:

import myPackage as pkg

User = pkg.createSingleDict("Jacob", 25)

print(User)

The myNewPackage.py contains a single function that takes two arguments and returns a dictionary with the arguments passed. The __init__.py uses the import statement and keywords, from and import to import the myNewPackage.py into the __init__.py file.

The main.py imports the myPackage without using the myPackage.myNewPackage expression. All of these are possible because of submodules.

The __init__.py file and the statement within it load the submodule mechanism where the myNewPackage file (attribute) is bound to the parent (myPackage) namespace.

The key part of the statement within the __init__.py file is the dot before the module name. This allows for the binding to the placed to the parent’s module.

Remember the part of the error message, with no known parent package. This is the reason you are experiencing the error.

Let’s run just the __init__.py file. The output of the execution is below.

Traceback (most recent call last):
  File "c:\Users\akinl\Documents\IError\myPackage\__init__.py", line 1, in <module>
    from .myNewPackage import createSingleDict
ImportError: attempted relative import with no known parent package

This error occurs because we are running the __init__.py file without the context of the parent namespace, myPackage. However, if we run the main.py with the import statement, import myPackage as pkg, we will not have any errors.

The output can be seen below:

{'name': 'Jacob', 'value': 25}

Therefore, don’t use the . operator before the module_name unless within the __init__.py or the binding or context of a parent namespace to prevent the ImportError: attempted relative import with no known parent package.

To better understand what is going on, if you remove the . operator within the import statement in __init__.py, we will not have any errors running the file.

from myNewPackage import createSingleDict

However, if we run the main.py file, it will cause the error below because we have not made binding of the myNewPackage module to the parent module, myPackage.

Traceback (most recent call last):
  File "c:\Users\akinl\Documents\IError\tempCodeRunnerFile.py", line 1, in <module>
    import myPackage as pkg
  File "c:\Users\akinl\Documents\IError\myPackage\__init__.py", line 1, in <module>
    from myNewPackage import createSingleDict
ModuleNotFoundError: No module named 'myNewPackage'

To make the code run, we will have to use the . operator within the import statement in main.py and remove (delete) the __init__.py file.

import myPackage.myNewPackage as pkg

User = pkg.createSingleDict("Jacob", 25)

print(User)

However, this is cumbersome, and it makes more sense to bind your submodules to the parent module using the . operator within __init__.py, but always make sure you are running it within the parent context.

If you have two submodules, it works the same way. The new submodules otherPackage.py may contain the code below:

def printName(name):
    print("The user's name is " + name)

You update the __init__.py file to bind the new submodule to the parent namespace.

from .myNewPackage import createSingleDict
from .otherPackage import printName

And within the main.py, you have to use the alias pkg to access the function within the other submodule. That is the beauty of binding to the parent namespace, the ease of importing.

import myPackage as pkg

User = pkg.createSingleDict("Jacob", 25)

print(User)
pkg.printName("Jacob")

The output of the code:

{'name': 'Jacob', 'value': 25}
The user's name is Jacob

With all these, you have all the required information to prevent or solve the ImportError: attempted relative import with no known parent package within your Python codebase.

Olorunfemi Akinlua avatar Olorunfemi Akinlua avatar

Olorunfemi is a lover of technology and computers. In addition, I write technology and coding content for developers and hobbyists. When not working, I learn to design, among other things.

LinkedIn

Related Article - Python Error