Skip to main content
Stack Overflow
  1. About
  2. For Teams

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

Required fields*

Relative imports for the billionth time

I've been here:

and plenty of URLs that I did not copy, some on SO, some on other sites, back when I thought I'd have the solution quickly.

The forever-recurring question is this: how do I solve this "Attempted relative import in non-package" message?

ImportError: attempted relative import with no known parent package

I built an exact replica of the package on pep-0328:

package/
 __init__.py
 subpackage1/
 __init__.py
 moduleX.py
 moduleY.py
 subpackage2/
 __init__.py
 moduleZ.py
 moduleA.py

The imports were done from the console.

I did make functions named spam and eggs in their appropriate modules. Naturally, it didn't work. The answer is apparently in the 4th URL I listed, but it's all alumni to me. There was this response on one of the URLs I visited:

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.

The above response looks promising, but it's all hieroglyphs to me. How do I make Python not return to me "Attempted relative import in non-package"? It has an answer that involves -m, supposedly.

Why does Python give that error message? What does by "non-package" mean? Why and how do you define a 'package'?

Answer*

Draft saved
Draft discarded
Cancel
29
  • 18
    See python.org/dev/peps/pep-0366 -- "Note that this boilerplate is sufficient only if the top level package is already accessible via sys.path . Additional code that manipulates sys.path would be needed in order for direct execution to work without the top level package already being importable." -- this is the most disturbing bit to me since this "additional code" is actually quite long and can't be stored elsewhere in package to run easily. Commented Aug 29, 2015 at 8:04
  • 68
    I keep coming back to this post despite being a Python veteran. The main message for me is: Either fiddle around with sys.path and __package__ (which is rather ugly, see the other answers) or simply create a "main script" main.py in the root directory of your project and put all modules to be imported in subdirectories. main.py can then access all modules directly through their package names (= the names of the respective folders they're in). Commented Mar 27, 2017 at 12:29
  • 65
    This answer is currently off on a few important details regarding __name__ and sys.path. Specifically, with python -m pkg.mod, __name__ is set to __main__, not pkg.mod; relative imports are resolved using __package__ rather than __name__ in this case. Also, Python adds the script's directory rather than the current directory to sys.path when running python path/to/script.py; it adds the current directory to sys.path when running most other ways, including python -m pkg.mod. Commented Oct 5, 2018 at 19:22
  • 23
    Finally understand after hours of reading... Worth noting that code under if __name__ == '__main__' will still run when using -m. See the comment from @user2357112 Commented Jan 22, 2019 at 20:18
  • 75
    A feature is broken if you have to spend an hour reading this, and if you have to google it time after time, and still only the gurus get it. The python designers dropped the ball on this one, and it should just work, the first time, like any other programming language. Commented Jan 7, 2022 at 16:10

lang-py

AltStyle によって変換されたページ (->オリジナル) /