preface

In this article, I will resolve ImportError: Runtime relative import with no known parent package. When you run a Python script. Relative references are used (like import.. This exception may occur when the package is referenced by module.

Let’s look at an example where this exception occurs.

The problem

Suppose you have the following directory structure:

Project ├ ─ ─ config. Py └ ─ ─ package ├ ─ ─ just set py └ ─ ─ demo. PyCopy the code

Config.py contains some variables that should be used in demo.py

  • project/config.py
count = 5
Copy the code
  • project/package/demo.py
from.import config
print("The value of config.count is {0}".format(config.count))
Copy the code

When we try to run demo.py, we get the following error:

E:\project> python demos/demo.py
Traceback (most recent call last):
  File "demos/demo.py", line 1.in <module>
    from.import config
ImportError: attempted relative import with no known parent package
Copy the code

The Python interpreter throws an exception without a parent package. Why is that?

Let’s look at how the Python interpreter parses the relevant modules. From PEP 328, we find an introduction to the Relative imports (relative references) :

Relative imports use a module’s __name__ attribute to determine that module’s position in the package hierarchy. If the Module’s name does not contain any package information (e.g. it is set to __main__) then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

Relative imports use the module’s __name__ attribute to determine the module’s position in the package hierarchy. If the module’s name does not contain any package information (for example, it is set to __main__), a relative reference will assume that the module is a top-level module, regardless of its actual location on the file system.

In other words, the algorithm for solving modules is based on the values of the __name__ and __package__ variables. Most of the time, these variables do not contain any package information —- for example: when __name__ = __main__ and __package__ = None, the Python interpreter does not know which package the module belongs to. In this case, relative references treat the module as a top-level module, regardless of its actual location on the file system.

To demonstrate this principle, let’s update the code:

  • project/config.py
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
count = 5
Copy the code
  • project/package/demo.py
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
from.import config
print("The value of config.count is {0}".format(config.count))
Copy the code

Try running it again, and you get the following output:

E:\project> python demos/demo.py
__file__=demos/demo.py      | __name__=__main__    | __package__=None
Traceback (most recent call last):
  File "demos/demo.py", line 3.in <module>
    from.import config
ImportError: attempted relative import with no known parent package
Copy the code

As we can see, the Python interpreter has no information about which package the module belongs to (__name__ = __main__ and __package__ = None), so it throws an exception that the parent package cannot be found.

Solution 1

  • We convert the project directory to a package by creating a new empty __init__.py file init.

  • We create a file main.py in the parent directory of the project directory

Toplevel ├ ─ ─ main. Py └ ─ ─ project ├ ─ ─ just set py ├ ─ ─ config. Py └ ─ ─ package ├ ─ ─ just set py └ ─ ─ demo. PyCopy the code
  • toplevel/main.py
print('__file__={0:<35} | __name__={1:<20} | __package__={2:<20}'.format(__file__,__name__,str(__package__)))
import project.demos.demo
Copy the code

Run the new example with the following output:

E:\toplevel>python main.py
__file__=main.py                             | __name__=__main__             | __package__=None
__file__=E:\toplevel\project\demos\demo.py   | __name__=project.demos.demo   | __package__=project.demos
__file__=E:\toplevel\project\config.py       | __name__=project.config       | __package__=project
The value of config.count is 5
Copy the code

Importing project.demos. Demo in main.py sets the package information (__name__ and __package__ variables) for relative references. The Python interpreter can now successfully parse relative references in project\demos\demo.py.

Solution 2

  • We convert the project directory to a package by creating a new empty __init__.py in the project folder.

  • Call the Python interpreter in the toplevel directory with the -m argument to execute project.demos. Demo [1]

Toplevel └ ─ ─ project ├ ─ ─ just set py ├ ─ ─ config. Py └ ─ ─ package ├ ─ ─ just set py └ ─ ─ demo. PyCopy the code

Execute again:

E:\toplevel>python -m project.demos.demo
__file__=E:\toplevel\project\demos\demo.py   | __name__=__main__        | __package__=project.demos
__file__=E:\toplevel\project\config.py       | __name__=project.config  | __package__=project
The value of config.count is 5
Copy the code

Running this command automatically sets the package information (the __package__ variable). The Python interpreter can now successfully resolve relative references in project\ demos\demo.py (even considering __name __ = __ main__).

[1] Note that the -m file does not have a.py suffix

import-error-relative-no-parent

Note: Reprint please retain the following content

The original link: www.napuzba.com/story/impor…

Text link: vimiix.com/post/2017/1…