So the structure of my directory is
src -- |
a.py
b.py
test -- |
test.py
I have tried everything I could, I am not able to import a.py or b.py inside of test.py in any way
I am running Linux Mint 20.2
I am running Python 3.10.9
I am using venv virtual environment
This what I have tried:
Any time I use relative imports, I get this: ImportError: attempted relative import with no known parent package
Adding init.py to directories did not help
Adding to system path did not help and is not an option, other users will be using it on different OSes, including executable file and so on..
Running python -m is not an option as well
Moving all files to one folder to get rid of the structure is stupid and I am not doing that.
Nothing works, I am losing my head, importing a file from a folder in parallel should not be that complicated
I went through all of the similar questions on this page and nothing helped.
I've had similar problems in the past and thus I've created a new import library: ultraimport
It gives the programmer more control over their imports and allows to do file system based relative and absolute imports.
In your test.py you could then write:
import ultraimport
a = ultraimport('__dir__/../src/a.py')
This will always work, independent of your current working diretory and independent of your sys.path. Also it does not matter how you run your program or if you have an init file.
I am working on a python project which consist of several packages and modules. Hence I need to import modules from different packages. However, when importing these modules I am getting import errors. The folder structure is as follows:
Image of folder structure
Within the module Stage0.py I use the relative import: "from ..data.Datapipe import DataFactory" to import the class DataFactory. However when I execute the script I get an error message: "ModuleNotFoundError: No module named 'MT'"
I would appreciate any feedback as I'm becoming desperate
I'm not 100% sure I've understood this correctly, but by the looks of it when you run the Stage0.py it will set the root python path to the app directory, the problem is that python's use of relative imports only allows to find files within that root directory, this site explains it a bit better to be honest
See here
Note that for relative imports, the dots . can go up only up to (but not including) the directory containing the script run from the command line
Anyway, it to fix it you could create a __main__.py file within the mt folder which calls the Stage0.py script, this will set that mt folder as the root of the project giving access to the other directories.
As a simple solution, I recommend that you put Stage0.py in the same location as the requirements.txt and execute it from there
as follows:
-data/
-__init__.py
-Datapipe.py
-graph/
-__init__.py
-s0.py
-stage0.py
stage0.py
from data.Datapipe import DataFactory
I am trying to organize my project and following is the hierarchy of the project:
-Project
--core
|--__init__.py
|--module_1.py
|--module_2.py
--env1
|--env1.py
--env2
|--env2.py
The project has multiple environments and all of them share the modules in the core directory. I am trying to import function1 from module1 in env1.py and env2.py:
from core.module_1 import function1
I am getting the following error:
ModuleNotFoundError: No module named 'core'
I also tried setting the path of the core directory but no luck. The import works if the module is in the same directory as the script calling it or if the script calling the module is in the main directory (in my case, Project). How do I import the modules from the core directory to the environment directories?
You've got the exact same problem that has been causing me trouble for a lot of last week. Here's my final version. If somehow this creates a time-machine, send that function back to me from last week, would ya?
def load_function(filepath,func_name) -> "function":
"""Load any function from a given path to a .py script."""
return getattr(__import__(filepath,fromlist=[func_name]),func_name)
I am currently running on python 3.6 on anaconda. I have a project structure where (test/lib/yolo/yolo_model.py) and (test/car/detection/cpu_yolo_detector.py).
I run my main from the test directory. My main now calls the script cpu_yolo_detector.py from withing (test/car/detection).
From cpu_yolo_detector.py I want to access the yolo_model.py with
"from lib.yolo.yolo_model import YoloModel"
but I get "no module named lib.yolo".
At the beginning of the main.py I add ('C:\\Users\\Name\\Desktop\\test\\lib\\yolo') to the sys.path and I still get that Error.
I tried both python 3.6 and 3.7 aswell as a virtual environment and without a virtual environment. If I run it with PyCharm everything seems to work but from the terminal it doesn't.
It appears test/ is the root of your project structure. If you want
from lib.yolo.yolo_model import YoloModel
to work, then the directory containing lib/ must be in sys.path.
Try adding 'C:\\Users\\Name\\Desktop\\test' to sys.path.
Try to put the two files (module and main file) in the same directory. If the module name is helpermodule
on main write:
import helpermodule
#or import a specific class/method you might need
I just got set up to use pytest with Python 2.6. It has worked well so far with the exception of handling "import" statements: I can't seem to get pytest to respond to imports in the same way that my program does.
My directory structure is as follows:
src/
main.py
util.py
test/
test_util.py
geom/
vector.py
region.py
test/
test_vector.py
test_region.py
To run, I call python main.py from src/.
In main.py, I import both vector and region with
from geom.region import Region
from geom.vector import Vector
In vector.py, I import region with
from geom.region import Region
These all work fine when I run the code in a standard run. However, when I call "py.test" from src/, it consistently exits with import errors.
Some Problems and My Solution Attempts
My first problem was that, when running "test/test_foo.py", py.test could not "import foo.py" directly. I solved this by using the "imp" tool. In "test_util.py":
import imp
util = imp.load_source("util", "util.py")
This works great for many files. It also seems to imply that when pytest is running "path/test/test_foo.py" to test "path/foo.py", it is based in the directory "path".
However, this fails for "test_vector.py". Pytest can find and import the vector module, but it cannot locate any of vector's imports. The following imports (from "vector.py") both fail when using pytest:
from geom.region import *
from region import *
These both give errors of the form
ImportError: No module named [geom.region / region]
I don't know what to do next to solve this problem; my understanding of imports in Python is limited.
What is the proper way to handle imports when using pytest?
Edit: Extremely Hacky Solution
In vector.py, I changed the import statement from
from geom.region import Region
to simply
from region import Region
This makes the import relative to the directory of "vector.py".
Next, in "test/test_vector.py", I add the directory of "vector.py" to the path as follows:
import sys, os
sys.path.append(os.path.realpath(os.path.dirname(__file__)+"/.."))
This enables Python to find "../region.py" from "geom/test/test_vector.py".
This works, but it seems extremely problematic because I am adding a ton of new directories to the path. What I'm looking for is either
1) An import strategy that is compatible with pytest, or
2) An option in pytest that makes it compatible with my import strategy
So I am leaving this question open for answers of these kinds.
The issue here is that Pytest walks the filesystem to discover files that contain tests, but then needs to generate a module name that will cause import to load that file. (Remember, files are not modules.)
Pytest comes up with this test package name by finding the first directory at or above the level of the file that does not include an __init__.py file and declaring that the "basedir" for the module tree containing a module generated from this file. It then adds the basedir to sys.path and imports using the module name that will find that file relative to the basedir.
There are some implications of this of which you should beware:
The basepath may not match your intended basepath in which case the module will have a name that doesn't match what you would normally use. E.g., what you think of as geom.test.test_vector will actually be named just test_vector during the Pytest run because it found no __init__.py in src/geom/test/ and so added that directory to sys.path.
You may run into module naming collisions if two files in different directories have the same name. For example, lacking __init__.py files anywhere, adding geom/test/test_util.py will conflict with test/test_util.py because both are loaded as import test_util.py, with both test/ and geom/test/ in the path.
The system you're using here, without explicit __init__.py modules, is having Python create implicit namespace packages for your directories. (A package is a module with submodules.) Ideally we'd configure Pytest with a path from which it would also generate this, but it doesn't seem to know how to do that.
The easiest solution here is simply to add empty __init__.py files to all of the subdirectories under src/; this will cause Pytest to import everything using package/module names that start with directory names under src/.
The question How do I Pytest a project using PEP 420 namespace packages? discusses other solutions to this.
import looks in the following directories to find a module:
The home directory of the program. This is the directory of your root script. When you are running pytest your home directory is where it is installed (/usr/local/bin probably). No matter that you are running it from your src directory because the location of your pytest determines your home directory. That is the reason why it doesn't find the modules.
PYTHONPATH. This is an environment variable. You can set it from the command line of your operating system. In Linux/Unix systems you can do this by executing: 'export PYTHONPATH=/your/custom/path' If you wanted Python to find your modules from the test directory you should include the src path in this variable.
The standard libraries directory. This is the directory where all your libraries are installed.
There is a less common option using a pth file.
sys.path is the result of combining the home directory, PYTHONPATH and the standard libraries directory. What you are doing, modifying sys.path is correct. It is something I do regularly. You could try using PYTHONPATH if you don't like messing with sys.path
If you include an __init__.py file inside your tests directory, then when the program is looking to set a home directory it will walk 'upwards' until it finds one that does not contain an init file. In this case src/.
From here you can import by saying :
from geom.region import *
you must also make sure that you have an init file in any other subdirectories, such as the other nested test directory
I was wondering what to do about this problem too. After reading this post, and playing around a bit, I figured out an elegant solution. I created a file called "test_setup.py" and put the following code in it:
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
I put this file in the top-level directory (such as src). When pytest is run from the top-level directory, it will run all test files including this one since the file is prefixed with "test". There are no tests in the file, but it is still run since it begins with "test".
The code will append the current directory name of the test_setup.py file to the system path within the test environment. This will be done only once, so there are not a bunch of things added to the path.
Then, from within any test function, you can import modules relative to that top-level folder (such as import geom.region) and it knows where to find it since the src directory was added to the path.
If you want to run a single test file (such as test_util.py) instead of all the files, you would use:
pytest test_setup.py test\test_util.py
This runs both the test_setup and test_util code so that the test_setup code can still be used.
Are so late to answer that question but usining python 3.9 or 3.10 u just need to add __init__.py folder in tests folders.
When u add this file python interprets this folders as a module.
Wold be like this
src/
main.py
util.py
test/
__init__.py
test_util.py
geom/
vector.py
region.py
test/
__init__.py
test_vector.py
test_region.py
so u just run pytest.
Sorry my poor english
Not the best solution, but maybe the fastest one:
cd path/python_folder
python -m pytest python_file.py