71

I have gone through many Python relative import questions but I can't understand the issue/get it to work.

My directory structure is:

Driver.py A/ Account.py __init__.py B/ Test.py __init__.py 

Driver.py

from B import Test 

Account.py

class Account: def __init__(self): self.money = 0 

Test.py

from ..A import Account 

When I try to run:

python Driver.py 

I get the error

Traceback (most recent call last): from B import Test File "B/Test.py", line 1, in <module> from ..A import Account ValueError: Attempted relative import beyond toplevel package 
2
  • 5
    You really should mention your Python version when asking about features which have changed radically between versions (relative imports, Unicode, and a few others). Sometimes people will be able to guess based on the specific error you got, or how you wrote your code, but you shouldn't count on people guessing right. Commented Feb 15, 2013 at 0:42
  • Give this answer a try. It worked for me Commented Jul 22, 2022 at 13:45

3 Answers 3

41

This is happening because A and B are independent, unrelated, packages as far as Python is concerned.

Create a __init__.py in the same directory as Driver.py and everything should work as expected.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks! Can you explain the init.py files a little bit? I have not understood explanations found online. I come from a c++ background, so I am used to just giving the path for includes and such
It's a bit hand-wavy, but basically: putting a __init__.py file in a directory means "in this directory, all of the .py files, and all of the subdirectories which contain a __init__.py file, are part of the same package".
All he needs if from A import Account in driver.py. Adding the extra init.py and using a relative import is a bit awkward and pollutes the toplevel.
This solution doesn't work for me using Python 2.7.14. I assume the solution is for Python 3.x? Is there a python2 solution for those forced to work in legacy systems?
I created an __init__.py and I'm still getting the same error. I'm on Python 3.7. What gives?
|
18

In my case adding __init__.py was not enough. You also have to append the path of the parent directory if you get module not found error.

root : | |__SiblingA: | \__A.py | |__SiblingB: | \_ __init__.py | \__B.py | 

To import B.py from A.py, you have to do the following

import sys # append the path of the parent directory sys.path.append("..") from SiblingB import B print("B is successfully imported!") 

3 Comments

This worked best for me in August 2022. This should be the accepted answer! The accepted answer does not provide the full directory structure and code for this to work.
It does not working for me. But works with only a dot sys.path.append(".")
Amazing that I had to search for hours for an answer to a very common problem that has frustrated so many people, when it should be easily found in the docs, and also that the solution is so relatively complicated for something that comes up so often. I thought simple is better than complex?
3

The reason for

ValueError: Attempted relative import beyond toplevel package 

is that A is the same directory level as Driver.py. Hence, ..A in from ..A import Account is beyond top-level package.

You can solve this by create a new folder named AandB together with __init__py in this new folder, and then move A and B folders into AandB folder. The directory structure is as following:

The directory structure

Correspondingly, the content in Driver.py should be modified as from AandB.B import Test.

1 Comment

This should be the accepted answer, and it does not requires calling sys.path.append("..")

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.