I'm currently writing a web application in python that needs unit tests, however whenever I try to import a child module that's in another parent directory I get the following error:
$ python my_package/tests/main.py
Traceback (most recent call last):
File "my_package/tests/test.py", line 1, in <module>
from my_package.core.main import hello
ImportError: No module named my_package.core.main
File: my_package/core/main.py
hello = "Hello"
File: my_package/test/test.py
from my_package.core.main import hello
print(hello, "world!")
My directory structure:
$ tree
.
└── my_package
├── __init__.py
├── core
│ ├── __init__.py
│ └── main.py
└── tests
├── __init__.py
└── test.py
Could someone please explain what I'm doing wrong? Thank you for your time.
It is considered an anti-pattern to modify sys.path. If you want your package to be available to all subpackages, it's better to use setup.py development mode.
Create setup.py in the root of your project:
from setuptools import setup
setup(
name="you_project",
version="0.0.0",
packages=['my_package', ],
install_requires=['requirement1', 'requirement2'],
)
Then run:
$python setup.py develop
After this you will be able to import my_packege from anywhere within your Python environment.
Your my_package is not in PYTHONPATH. At the top of your test.py add the below. Note that any change in location of test.py would affect package_path
from os.path import dirname, abspath
import sys
package_path = dirname(dirname(abspath(__file__)))
sys.path.append(package_path)
Related
I have this file structure
.
└── sample
├── one
│ ├── __init__.py
│ └── util.py
└── two
├── __init__.py
└── test.py
Here is the content of util.py
def isOk():
return True
Here is the content of test.py
from sample.one import util
Whenever I'm inside the [two] folder and I type
python test.py
I get
Traceback (most recent call last):
File "test.py", line 1, in <module>
from sample.one import util
ModuleNotFoundError: No module named 'sample'
How is that possible when I create all folders and __init__.py by the book?
It seems that a method to invoke it might be
python -m two.test
If one and two are both subpackages of sample, then you should add a sample/__init__.py which may be empty.
If you then invoke python -m sample.two.test from the right directory, it should work.
You could even add package-relative imports like this:
# test.py
from ..one import util
Please add the dir path to your PYTHONPATH
export PYTHONPATH=/PATH/TO/DIR/WHICH/CONTAINS/SAMPLE
2 real nice links to go through are:
https://docs.python.org/3/tutorial/modules.html
https://docs.python.org/3/reference/import.html
I'm looking for a way to import a subpackage from within a package in Python 3.
Consider the following structure :
├── main.py
└── package
├── subpackage
│ └── hello.py
└── test.py
What I would like to do is use a function that inside hello.py from within test.py (which is launched by main.py)
main.py
from package.test import print_hello
print_hello()
package/test.py
from subpackage.hello import return_hello
def print_hello():
print(return_hello())
package/subpackage/hello.py
def return_hello():
return "Hello"
But I'm getting the following error :
Traceback (most recent call last):
File ".\main.py", line 1, in <module>
from package.test import print_hello
File "D:\Python\python-learning\test\package\test.py", line 1, in <module>
from subpackage.hello import return_hello
ModuleNotFoundError: No module named 'subpackage'
I tried putting a . in test.py and it worked, but my linter does not like it.
What am I doing wrong ?
edit : I managed to use an absolute path as recommended but now when I try to put everything in a subfolder pylint is not able to import.
└── src
├── main.py
└── package
├── subpackage
│ └── hello.py
└── test.py
Just use
from .subpackage.hello import return_hello
instead of
from subpackage.hello import return_hello
in your test.py file and read this guide for better understanding how imports works in python.
You can see fixed result here : https://repl.it/#ent1c3d/SoupySadUnderstanding
I try to understand how to split up python files belonging to the same project in different directories. If I understood it right I need to use packages as described here in the documentation.
So my structure looks like this:
.
├── A
│ ├── fileA.py
│ └── __init__.py
├── B
│ ├── fileB.py
│ └── __init__.py
└── __init__.py
with empty __init__.py files and
$ cat A/fileA.py
def funA():
print("hello from A")
$ cat B/fileB.py
from A.fileA import funA
if __name__ == "__main__":
funA()
Now I expect that when I execute B/fileB.py I get "Hello from A", but instead I get the following error:
ModuleNotFoundError: No module named 'A'
What am I doing wrong?
Your problem is the same as: Relative imports for the billionth time
TL;DR: you can't do relative imports from the file you execute since
main module is not a part of a package.
As main:
python B/fileB.py
Output:
Traceback (most recent call last):
File "p2/m2.py", line 1, in <module>
from p1.m1 import funA
ImportError: No module named p1.m1
As a module (not main):
python -m B.fileB
Output:
hello from A
One way to solve this is to add module A into the path of fileB.py by adding
import sys
sys.path.insert(0, 'absolute/path/to/A/')
to the top of fileB.py.
My folder trees:
./
├── README.MD
├── basic
│ └── thresh.py
├── images
│ └── figure.jpg
└── utils
├── util.py
└── util.pyc
I want to import util.py in thresh.py:
import sys
sys.path.append('../utils')
import util
When I run command $ python thresh.py in the basic folder, it's allright. But run $ python ./basic/thresh.py in the topmost folder, I will get the error:
ImportError: No module named util
So how to make $ python ./basic/thresh.py and $ python thresh.py both work to import file by given the file's relative path to executed file regardless of python command path?
You can get the absolute path of the script you are executing with (there are other variants also using __file__, but this should work)
import os
wk_dir = os.path.dirname(os.path.realpath('__file__'))
print( wk_dir )
and then get your dir with it, e.g.
import sys
sys.path.append(wk_dir+'/../utils')
PS: You might need to use __file__ instead of '__file__'.
Here's my directory setup:
mydir
├── script1.py
└── shared
├── otherstuff
├── script2.py
└── pkg
├── box.py
└── __init__.py
script2.py starts with
import pkg
and it works great. When I include the same line in script1.py, I get:
Traceback (most recent call last):
File "script1.py", line 1, in <module>
import pkg
Is there any good way to get syntax that simple to work in script1.py? I have been reading about PYTHONPATH and sys.path for the past hour, but I'm trying to make some basic functions available to my repo, and I can't believe that it will require modifying PYTHONPATH everytime I want to run a script.
What am I missing here? What's the best way to get pkg into script1.py?
You have to do:
from shared import pkg
Also, your shared directory should have an __init__.py file
I tested in python 3.x , You can do either -
import shared.pkg
or
from shared import pkg
If you don't want to create the __init__.py file in shared and using import shared.pkg, you can work around this by doing:
import sys
sys.path.insert(0, 'shared')
import pkg