Home > python > ImportError: attempted relative import with no known parent package

ImportError: attempted relative import with no known parent package

Problem:
I was getting the following errors
ImportError: attempted relative import with no known parent package and ModuleNotFoundError: No module named 'mymodule'

Solution:
This stackoverflow answer helped clear up my confusion.

As answered by sfy on here

TL;DR

You can only relatively import modules inside another module in the same package.

Concept Clarify

We see a lot of example code in books/docs/articles, they show us how to relatively import a module, but when we do so, it fails.

The reason is, put it in a simple sentence, we did not run the code as the python module mechanism expects, even though the code is written totally right. It’s like some kind of runtime thing.

Module loading is depended on how you run the code. That is the source of confusion.

What is a module?
A module is a python file when and only when it is being imported by another file. Given a file mod.py, is it a module? Yes and No, if you run python mod.py, it is not a module, because it is not imported.

What is a package?

A package is a folder that includes Python module(s).

BTW, __init__.py is not necessary from python 3.3, if you don’t need any package initialization or auto-load submodules. You don’t need to place a blank __init__.py in a directory.

That proves a package is just a folder as long as there are files being imported.

Real Answer

Now, this description becomes clearer.

You can only relatively import modules inside another module in the same package.

Given a directory:

. CWD
|-- happy_maker.py # content: print('Sends Happy')
`-- me.py # content: from . import happy_maker

Run python me.py, we got attempted relative import with no known parent package

me.py is run directly, it is not a module, and we can’t use relative import in it.

Solution 1

Use import happy_maker instead of from . import happy_maker

Solution 2

Switch our working directory to the parent folder.

. CWD
|-- happy
| |-- happy_maker.py
`-- me.py

Run python -m happy.me.

When we are in the directory that includes happy, happy is a package, me.py, happy_maker.py are modules, we can use relative import now, and we still want to run me.py, so we use -m which means run the module as a script.

Python Idiom

. CWD
|-- happy
| |-- happy_maker.py # content: print('Sends Happy')
| `-- me.py # content: from . import happy_maker
`-- main.py # content: import happy.me

This structure is the python idiom. main is our script, best practice in Python. Finally, we got there.

Siblings or Grandparents

Another common need:

.
|-- happy
| |-- happy_maker.py
| `-- me.py
`-- sad
`-- sad_maker.py

We want to import sad_maker in me.py, How to do that?

First, we need to make happy and sad in the same package, so we have to go up a directory level. And then from ..sad import sad_maker in the me.py.

That is all.

Source:
https://stackoverflow.com/questions/16981921/relative-imports-in-python-3

Categories: python Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.