2

I have this file setup:

mainfolder:
    __init__.py
    mainfile.py
    subfolder1:
        file1.py
        __init__.py
    subfolder2:
        file2.py
        __init__.py

I need to import mainfile.py into file1.py and file2.py. Currently I am using:

from .. import mainfile

However this brings the error: attempted relative import beyond top level package.

I have also tried:

from ...mainfolder import mainfile

Which brings up the same message, and:

from mainfolder import mainfile

Which brings the error message: no module named 'mainfolder'

Within the __init __.py files I have this code:

__all__ = [list of files in package]

I'm not sure why this is not working. I would greatly appreciate it if someone could explain what I am doing wrong.

EDIT: The error "Attempted relative import beyond top-level package" occurred when I ran:

from .. import mainfile

within file 1.

Jebby
  • 1,845
  • 1
  • 12
  • 25
Tom W
  • 21
  • 4

2 Answers2

0

When using packages, Python requires the __package__ variable be defined to make sense of relative imports.

When you call python mainfolder/subfolder2/file2.py, it simply executes file2.py like a script - and, without __package__, fails to do any relative imports.

When you call python -m mainfolder.subfolder2.file2, you're essentially telling Python, "please execute the submodule file2 in the subpackage subfolder2 of the package mainfolder", so it sets __package__ for you and everything works fine.

See this answer for a much more in-depth discussion.

Dan Gittik
  • 3,460
  • 3
  • 17
  • 24
0

You can't do a relative import above the script being called. The best way I've found to fix that error when you can't run your scripts as modules is to add import sys; sys.path += ['../'] at the beginning of the file. This will add the parent directory as one of the locations to look in for modules, so you can then just import mainfile. This also works if the module you want to import is somewhere else in your filesystem, just change ['../'] to the relative path pointing to the directory containing the module you want to import.

Syncrossus
  • 570
  • 3
  • 17