I'm having difficultly with important a python module from another folder. Here's how my folder looks currently
foldername/
__init__.py
A/
__init__.py
spam.py
grok.py
B/
__init__.py
foo.py
I'm trying to import the functions and classes from the grok.py file into the foo.py in B. This is how my foo.py looks like
from ..A.spam import func
However, I get the following error:
ValueError: attempted relative import beyond top-level package
Could somebody help me? I don't understand where I'm going wrong
You can't use '..' like you do on the command line. You have to add your 'A' folder to your Python path. You can use sys.path.append('/dir/of/A') and then from A.spam import func
Instead of using sys.path you could also add a *.pth-file to your python or anaconda "site-packages"-folder which contains the path to the folder "A".
Import via from A.spam import func as #bikemule already proposed.
Related
I have this package I designed which have the following structure,
General/
__init__.py
Vector/
__init__.py
module_1.py
module_A.py
In module_A there is a just a function prints a string.
In module_1 there is,
from ...General import module_A
module_A.function()
Then I create a separate python file First.py which only has the line import General.Vector.module_1.
I put this file in to the parent directory of General and locate cmd to the parent directory and run python First.py
Then I get the error ValueError: attempted relative import beyond top-level package
But if I change module_1 to
from .. import module_A
module_A.function()
Then this works.
I searched for a solution and from this post, I got a good understanding about relative imports. Then it was pointed out to me that if I add my package to sys.path then python First.py would work regardless of where the First.py is located.
So I tried to add my package to sys.path as this post suggests.
I changed my First.py to
import sys
sys.path.insert(0,'/path/to/General')
import General.Vector.module_1
But that didn't work.
1 I like to know the reason for this two different behaviours for module_1's changes.
2 I like to know how to add my package to sys.path.
This question already has answers here:
How to do relative imports in Python?
(18 answers)
Closed 4 years ago.
I have a simple project structure like this:
➜ (venv:evernote) evernote_bear_project git:(master) ✗ tree | grep -v pyc
.
├── README.md
...
(snip)
...
├── manage.py
├── sample
│ ├── EDAMTest.py <==== here is an import that won't work
│ └── enlogo.png
└── util
├── __init__.py
├── files.py <====== This is being imported
└── test_files.py
Now I have a relative import in sample/EDAMTest.py:
from ..util.files import *
When I try to run python sample/EDAMTest.py from project root folder in command line, I get an error saying:
ValueError: attempted relative import beyond top-level package
I know this has been asked many times, but I still don't get it.
Since I'm running the script from the project root, in my understanding Python should be able to "know" that when I try to import from ..util.files import *, that it should go up one directory, no?
EDIT
Thanks for all the answers.
So what I understand from the link above is this:
I was running the module sample/EDAMTest.py directly via python sample/EDAMTest.py, and that meant
that the __name__ of the module was __main__
and now the path (sample/) was my "root" so to speak.
So now Python searches only this path and any path that's below it for modules / packages. Hence the error message attempted relative import _beyond top-level package_, so it cannot go one more level up, because it is at the root already.
Also Python cannot look one level "up", since this syntax from ..util.files import * does not go up a level in directory, but in a list of modules / packages it keeps on the "import search path" (sys.path)?
Is that correct?
sys.path.append() is a tweak, if your directory structure is fixed and there is nothing you can do about it.
Otherwise, you can try rearranging the folders. The easiest is moving util under sample, another option is making both of the folders psrt of a larger package.
Also import * is not ensorsed.
The relative import syntax is for importing other modules from the same package, not from the file system.
Depending on what you want, you could...
Fix the package so that the relative import works
Put __init__.py files in the project root and sample directory and run the script from one level up. This doesn't seem like what you want.
Tell python where to find the package
Set the PYTHONPATH environment variable so that python can find the package.
PYTHONPATH='.':$PYTHONPATH python samples/EDAMTest.py
Install util so that python can find it
Add a setup script and use it to install the util package and avoid setting PYTHONPATH.
"The relative import syntax is for importing other modules from the same package, not from the file system.", This is right as stated by George G.
Put __init__.py in your subfolders, which will make them package.
__init__.py can be an empty file but it is often used to perform
setup needed for the package(import things, load things into path, etc).
However you can import File into your __init__.py to make it
available at the package level:
# in your __init__.py
from util import files
# now import File from util package
from util import files
of if you want to import some specific method or class, you can do
from util.files import some_function
Another thing to do is at the package level make util/modules
available with the __all__ variable. When the interpeter sees
an __all__ variable defined in an __init__.py it imports the
modules listed in the __all__ variable when you do:
from package import *
__all__ is a list containing the names of modules that you want to be
imported with import * so looking at our above example again if we
wanted to import the submodules in util the all variable
in util/init.py would be:
__all__ = ['files', 'test_files']
With the __all__ variable populated like that, when you perform
from util import *
it would import files and test_files.
I'm trying to organize my scripts in a way I can use absolute imports, without appending to sys.path, making it as easy to use in different computers as possible without problems. I have read and I understand absolute paths are the most appropriate way to do this.
My folder structure looks something like:
main/
__init__.py
tools/
__init__.py
script1.py
base/
__init__.py
script2.py
I have been trying to do from main.tools.script1 import Foo in file main/base/script2.py and I still get the error ImportError: No module named main.tools.script1.
If is print sys.path, the first item is main/base/.
If I run python on a terminal from main, I can import tools.script1, but cannot write main.tools.script1.
I have read other posts, but this is still really not clear for me.
MyNiceProgram-1.0/
setup.py
README
LICENSE
bin/
myniceprogram.py # main entry point
myniceprogram/
__init__.py
tools/
__init__.py
script1.py
base
__init__.py
script2.py
Then you use:
from myniceprogram.tools import script1
from myniceprogram.base import script2
Don't
Name your main package main - it should be treated as a global package so the name should be descriptive. If you want to have a package named main put it inside myniceprogram.main
Execute scripts inside your package. Your main script should be outside the package for absolute import to work. Otherwise you can end up having two copies of the same script, imported absolutely and relatively.
I have a module(Executive.py) that I am trying to import into another module I am working on (ExecutiveTest.py). The directory structure is like so:
src/
common/
python/
Executive.py
tests/
ExecutiveTest.py
In ExecutiveTest.py, I have the following line:
from common.Executive import Executive
I get an error saying:ImportError: No module named common.Executive
How do I correct this import error?
You have to have an __init__.py file in the root of your package (it can be empty). Also, your module hierarchy has to reflect the directory structure, so python and tests should be part of the import as well.
I found a similar post here. it looks like you can define the path that python refers to when looking for stuff to import. Something like:
sys.path.append( )
First off all: I'm sorry, I know there has been lots of question about relative imports, but I just didn't find a solution. If possible I would like to use the following directory layout:
myClass/
__init__.py
test/
demo.py
benchmark.py
specs.py
src/
__init__.py
myClass.py
Now my questions are:
How do the test files from within the package properly import myClass.py?
How would you import the package from outside, assuming you take myClass as submodule in libs/myClass or include/myClass?
So far I couldn't find an elegant solution for this. From what I understand Guido's Decision it should be possible to do from ..src import myClass but this will error:
ValueError: Attempted relative import in non-package
Which looks as it doesn't treat myClass as packages. Reading the docs:
The __init__.py files are required to make Python treat the directories as containing packages;
It seems I'm missing something that specifies where the scripts of the package are, should I use .pth ?
ValueError: Attempted relative import in non-package
Means you attempt to use relative import in the module which is not package. Its problem with the file which has this from ... import statement, and not the file which you are trying to import.
So if you are doing relative imports in your tests, for example, you should make your tests to be part of your package. This means
Adding __init__.py to test/
Running them from some outside script, like nosetests
If you run something as python myClass/test/demo.py, relative imports will not work too since you are running demo module not as package. Relative imports require that the module which uses them is being imported itself either as package module, from myClass.test.demo import blabla, or with relative import.
After hours of searching last night I found the answer to relative imports in python!! Or an easy solution at the very least. The best way to fix this is to have the modules called from another module. So say you want demo.py to import myClass.py. In the myClass folder at the root of the sub-packages they need to have a file that calls the other two. From what I gather the working directory is always considered __main__ so if you test the import from demo.py with the demo.py script, you will receive that error. To illustrate:
Folder hierarchy:
myClass/
main.py #arbitrary name, can be anything
test/
__init__.py
demo.py
src/
__init__.py
myClass.py
myClass.py:
def randomMaths(x):
a = x * 2
y = x * a
return y
demo.py:
from ..src import myClass
def printer():
print(myClass.randomMaths(42))
main.py:
import test.demo
demo.printer()
If you run demo.py in the interpreter, you will generate an error, but running main.py will not. It's a little convoluted, but it works :D
Intra-package-references describes how to myClass from test/*. To import the package from outside, you should add its path to PYTHONPATH environment variable before running the importer application, or to sys.path list in the code before importing it.
Why from ..src import myClass fails: probably, src is not a python package, you cannot import from there. You should add it to python path as described above.