Attempted relative import with no known parent package python как исправить

ImportError: attempted relative import with no known parent package occurs in Python 3.6 and newer mainly and if you are doing relative import in a module.
Table of Contents
Hide
  1. How does module import work in Python?
  2. Absolute vs. Relative imports
  3. How to fix ImportError: attempted relative import with no known parent package?
    1. Option 1 – Use absolute imports
    2. Option 2 – Get rid of from keyword
    3. Option 3 – Import inside package init file

Module imports sometimes can cause too much frustration if you are a Python beginner. This tutorial will learn how imports work and the solution for ImportError: attempted relative import with no known parent package.

Before getting into the solution, let’s first understand few basic terminologies in Python.

Python Module: A module is a file in Python containing definitions and statements. A module can contain executable statements as well as function definitions. In simple terms, think as a single .py file with some functionality.

Python Package: A Python package consists of one or more modules, and it contains one file named __init__.py that tells Python that this directory is a package. The init file may be empty, or it may include code to be executed upon package initialization.

imports: Imports in Python are essential for structuring your code effectively, and by using the import keyword, you can import any module and reuse it effectively. There are two types of import, Relative and Absolute, which will look in-depth.

Let’s consider a simple example. 

└── myproject
    ├── firstpackage
    │   ├── a.py
    └── secondpackage
        ├── b.py
        ├── c.py
        └── subpackage
            └── d.py

The above project has two packages named firstpackage and secondpackage. Each of these contains some modules, and the secondpackage also has a subpackage that includes its own module. Typically the project structure goes something like this, and it may grow pretty complex.

How does module import work in Python?

Now, let’s say if you import module b in one of your files using the import statement as shown below.

import b

Python will perform the following operations to import the module:

  • Locate, load, and initialize (if required) the requested module
  • Define necessary names in the local namespace and corresponding scope

Now Python interpreter is going to follow the following steps in an attempt to resolve module b .

Step 1: sys.modules lookup

Python will try to look at the module first in the sys.modules, which is a dictionary that has a mapping of key-value pairs of modules. If it finds, then the module is resolved and loaded.

Step 2: Python Standard Library lookup

Python Standard Library contains built-in modules (written in C) that provide access to system functionality such as file I/O that would otherwise be inaccessible to Python programmers. Modules are written in Python that provides standardized solutions for many problems that occur in everyday programming. Some of these modules are explicitly designed to encourage and enhance the portability of Python programs by abstracting away platform-specifics into platform-neutral APIs.

If the name is not found in the sys.modules, it will search in the standard library. If it cannot find over there, then it goes to the next step.

Step 3: sys.path lookup

Python will look into the sys.path as the last step to resolve the module. This is where things can go wrong, and you will get ModuleNotFoundError: No module named ‘b’

Absolute vs. Relative imports

In absolute imports, you need to specify the explicit path from the project’s root directory.

Example – If we have to import module b then we can use the following way to import

import secondpackage.b

Other ways of importing modules in Python

# importing modules a.py
import secondpackage.subpackage.d
import secondpackage.c

In case of relative imports, we need to specify the module’s path relative to the current module’s location.

Example –

# in module a.py
from ..secondpackage import b
from ..secondpackage.b import another_function
# in module b
from . import c
from .c import my_function

Option 1 – Use absolute imports

For instance, the directory structure may be as follows

.
├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module.py
│   │   └── standalone.py
│   └── setup.py

where setup.py is

from setuptools import setup, find_packages
setup(
    name = 'your_package_name',
    packages = find_packages(),
)

Option 2 – Get rid of from keyword

Remove the from keyword and use the standard way of import as shown below.

import secondpackage.c


Option 3 – Import inside package init file

Put this inside your package’s __init__.py file:

# For relative imports to work in Python 3.6
import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))

Assuming your package is like this:

├── project
│   ├── package
│   │   ├── __init__.py
│   │   ├── module1.py
│   │   └── module2.py
│   └── setup.py

Now use regular imports in you package, like:

# in module2.py
from module1 import class1

Avatar Of Srinivas Ramakrishna

Srinivas Ramakrishna is a Solution Architect and has 14+ Years of Experience in the Software Industry. He has published many articles on Medium, Hackernoon, dev.to and solved many problems in StackOverflow. He has core expertise in various technologies such as Microsoft .NET Core, Python, Node.JS, JavaScript, Cloud (Azure), RDBMS (MSSQL), React, Powershell, etc.

It seems, from Python docs and experimenting, that relative imports (involving ., .. etc) only work if

  1. the importing module has a __name__ other than __main__, and further,
  2. the __name__ of the importing module is pkg.module_name, i.e., it has to be imported from above in the directory hierarchy (to have a parent pkg as part of it’s __name__.)

OR

the importing module is being specified via module syntax that includes a parent pkg as python -m pkg.module, in which case it’s __name__ is still __main__, so it is being run as a script, yet relative imports will work. Here __package__ is set and used to find the parent package while __name__ is __main__; more here.

[After all that, it appears that __package__ and sys.path are key to determining if/how relative imports work. __name__ indicates script or module(i.e., __main__ or module_name). __package__ indicates where in the package the relative imports occur with respect to, and the top of __package__ needs to be in sys.path.]

So, continuing with @AmitTendulkar ‘s example, if you run this as > python main.py or > python -m main or > python -m ecommerce.products from the project root directory, or enter interactive python from that root directory and import main, or import ecommerce.products the relative imports in products.py will work.

But if you > python products.py or > python -m products from within ecommerce directory, or enter interactive python from that ecommerce directory and import products they will fail.

It is helpful to add

print("In module products __package__, __name__ ==", __package__, __name__)

etc. in each file to debug.

UPDATE:

How imports work depend on sys.path and __package__, not on __name__.
Issued from /home/jj, > python sub/mod.py has a sys.path, __package__ of /home/jj/sub, None -absolute imports of modules in sys.path work, relative imports fail.

> python -m sub.mod has sys.path, __package__ of /home/jj, sub -absolute imports of modules in sys.path work, relative imports work relative to sys.path + __package__.

It is more helpful to add

import sys    
print("In module products sys.path[0], __package__ ==", sys.path[0], __package__)

etc. in each file to debug.

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.

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:UsersakinlDocumentsIErrormyPackage__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:UsersakinlDocumentsIErrortempCodeRunnerFile.py", line 1, in <module>
    import myPackage as pkg
  File "c:UsersakinlDocumentsIErrormyPackage__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.

Every program in any programming language starts with a header file, package, or module. In Python, the Import statement is the first statement of the program that allows users to import modules into the code. It has a similar function to the #include header_file statement of C or C++.

Python modules can access the built-in code from other modules by importing the Python function or file using the word «import.» But most Python users do not know that their program may show an error if they fail to use the packages in a proper format.

This article will discuss one of the most common error messages, i.e., the ImportError: attempted relative import with no known parent package in Python.

What is import statement in Python?

One of the most common ways to invoke import machinery is to use the import statement, but apart from this, users can also add to the Python import. The import statement comprises the import keyword, including the name of a Python module.

In the import statement, the interpreter performs two operations, i.e., it involves two procedures. Firstly, import looks for a module, and secondly, the import wraps the search result to the name in the local scope.

When users import a module in their code, Python executes all of the code of the desired module file and presents it to the importer file to run.

Syntax of an import statement in Python:

The import statement allows programmers to import both packages and modules. Generally, Python has two types of import syntax. When programmers use the first import syntax, they import the built-in resource directly. Programmers can also import specific objects from the module or package.

Note:

It is a point to remember that when users import a package, it virtually imports the package’s __init__.py file as a module.

import abcd

Here, «abcd» can either be a package or a module. Again, when users use the second syntax, i.e., they can also import the resource from other packages or modules.

Syntax:

from abcd import mod

here, the «mod» can be a subpackage, module, or object, like a class or function.

What are packages and modules in Python?

Before understanding this error, we have to understand the concept of packages & modules so that we can easily debug those errors. When users use a package in a Python code, they import the file __init__.py, which is for every user-oriented code.

A Python package operates on a library, explaining the whole Python code as a single unit of a particular function. A Python package also changes the user-interpreted code by modifying it so that the Python interpreter can efficiently operate it in the run time.

On the other hand, a Python module is a file including Python code in run time for any user-oriented code. The Python modules are different libraries themselves, which contain built-in functions.

Syntax:

from abcd import mod

Here, the term «abcd» signifies a package, and the term «mod» defines a module or a sub package.

The cause behind the error named, ImportError: attempted relative import with no known parent package in python:

Before fixing the error, let us know why the Python interpreter shows the Importerror message. as we have discussed above, users can import a module inside a package, two packages, or one module inside another module.

Often, programmers make a mistake while calling a package in the import statement. They should know the difference between the parent package and the subpackage while importing.

If users fail to import the parent library in the import statement, the interpreter will show the error message, «ImportError: attempted relative import with no known parent package in Python.»

How to fix the «Importerror attempted relative import with no known parent package» error in Python?

The solution to this problem is easy. Before advancing to the body of the Python program, programmers first create a Python file with their setup name; then make that package global so they can easily access it.

After users create their file, inside that file, they need to specify the name of the Python package they want to import.

Let us see an example with the help of a code and understand it more precisely:

from setuptools import setup, find_packages
setup(name = 'package_two', packages = find_packages())

Here, you can see that we have provided our package name. Now we need to remove the relative path from our one.py file.

To do so follow the below code example:

Code Snippet:

from package_two import second_module
print("Hello World!")
two.fun()

Output:

Explanation:

Now, we can see in the above output there is no error message. Both the parent package and the module are known to the interpreter.

An example to show how to use the Python packages and modules in the right format:

└── myproject
├── first_package
│ ├── A.py
└── second_package
├── B.py
├── C.py
└── sub_package
└── D.py

Conclusion:

We hope from this article; Python programmers get the solution to fix the error named «ImportError: attempted relative import with no known parent package.» Debugging these import-related errors is essential in the real-life scenarios where software development requires using packages & modules frequently to reduce or eliminate repetitive work in Python prorgrams.

Понравилась статья? Поделить с друзьями:
  • Authentication error scp secret laboratory
  • Authentication error right click on forts
  • Attempt to call global a nil value ошибка
  • Authentication error occurred wifi
  • Attempt 1 at connecting failed connection error proxy connection timed out 10