Home > Net >  import error attempting to import from the directory above
import error attempting to import from the directory above

Time:12-24

Not a python developer and I am clearly missing something fundamental here. Using Python 3.10.7 and i am getting an error:

from ..class_one import ClassOne 
ImportError: attempted relative import beyond top-level package

when attempting to execute python run_me.py script in the example below

I have the following structure with following import statements

\Project
    \data_processor
        data_process.py
            from ..class_one import ClassOne  <--getting an error here
    run_me.py
        from data_processor.data_process import DataProcess
    class_one.py
    

interesting that when i type a line from ..class_one import ClassOne in data_process.py my IDE thinks its completely legit and intellisence works, suggesting that i import ClassOne.

Most of the solutions imply Python earlier than v3.3 (changed the way packages are handled), which isn't the case here.

CodePudding user response:

Python does not allow relative imports beyond the top-level package. This is why you are seeing the ImportError: attempted relative import beyond top-level package error...

Try to use absolute import, like this:

from Project.class_one import ClassOne

You can also move the class_one module to a package within the current project, you can create a new package and move the class_one module to it. Then, you can use a relative import to import the ClassOne module:

\Project
    \data_processor
        data_process.py
            from my_package.class_one import ClassOne
    run_me.py
        from data_processor.data_process import DataProcess
    \my_package
        class_one.py

Finally, it's not recommended (complexity, cause confusion and difficulty to read the code) but I think you can try to use a 'sys.path' to add the parent directory to the Python path. I think it will allow you to use a relative import:

import sys
sys.path.insert(0, '..')
from class_one import ClassOne

CodePudding user response:

Why you get that error?

Remember relative imports are resolved using __package__ variable(I'm talking about ..class_one). Add a simple print statement in your data_process.py to see the value of this variable:

print(__package__)

You're in Project folder and you run python run_me.py, so this variable must be: 'data_processor'. So you can't go beyond "one" level up. (It follows the dots as we see next).

When you can go one level up?

In run_me.py change your import statement from:

from data_processor.data_process import DataProcess

to

from Project.data_processor.data_process import DataProcess

Before running your script, we need to tell Python where to find Project folder. It doesn't know right now! We are in Project directory and there is no Project directory in where we are. So just add it to the sys.path in run_me.py:

import sys
sys.path.insert(0, PATH TO PARENT OF Project DIRECTORY)

Now run your command -> python run_me.py. Every thing works fine.

Did you notice the value of __package__? It's now 'Project.data_processor'. We went one level down, so we can go one level up .( As I said, it follows the dots.)


That was the reason. But what you can do now?

  1. I think the most simple solution is to just stick with absolute imports. If you know in which directory you are and check the records in sys.path, you won't get into problems.

  2. You can manually hack __package__ which I do not recommend. To do so, add:

__package__ = "Project.data_processor"

at the top in your data_process.py file. Then change your directory to the parent, and tun your script like:

python -m Project.run_me
  • Related