I have a structure like this:
myProj
--backend
--app.py
--tests
--test_app.py
When i run the command:
pytest -v --cov=.tests/test_app
I get:
tests/test_app.py:1: in <module>
from backend.app import soma
E ModuleNotFoundError: No module named 'backend'
Why can't import the library?
When the structure like this:
myProj
--app.py
--test_app.py
Perform correctly.
How can i run coverage in my project with the first showed structure ?
This is because backend is not a package.
To make it work as a package you should create an empty file named __init__.py inside the backend folder, so it will work as expected.
To read more about how packages work in Python, check the documentation.
The problem here is the code structure and making a folder as a module so that it can be imported.
To make any folder work as module, we need to keep __init__.py file(empty or with some data to initialise) inside it. And while importing it make sure it's accessible from that file. i.e. either it is in the same directory or in the exported PYTHONPATH.
Consider following structure:
-- backend:
__init__.py
app.py
-- tests:
__init__.py
main.py
Here backend and tests are the directories and if you want to import something in main.py file from the app.py file it will go like following:
from ..backend.app import soma
Note the extra .. before backend module in above import line that helps the Python interpreter to find the soma from backend/app.py file.
As mentioned by #DiegoQueiroz and #HNMN3, you should make sure your directory as python package.
Add __init__.py file inside backend and tests directory.
Then, you need to mention module name in your command.
Given your project structure, you can input this command:
pytest -v --cov=backend.app tests/test_app
Related
I've been reading tons of questions related to this matter but none of the has help me so far. I'm currently using the Python click library to execute scripts as commands.
The current command that I'm trying to execute is placed inside a Python Package which has a __main__.py file, like the parent dir has. The current project structure is the following one.
/myproject
/foo_one
__init__.py
foo_one.py
/foo_two
__init__.py
foo_two.py
/foo_three
__init__.py
foo_three.py
/foo_four
__init__.py
foo_four.py
/foo_five
__init__.py
foo_five.py
/foo_six
__init__.py
foo_six.py
__init__.py
__main__.py
foo_seven.py
Whenever I try to run the __main__.py script located in the project folder, the following error comes up.
ModuleNotFoundError: No module named '__main__.foo_two'; '__main__' is not a package
However, if I try to execute that same script from a folder above with the -m option like this python3 myproject -m, the following is shown up.
ImportError: attempted relative import with no known parent package
The __main__.py has 2 imports like this... The __init__.py is empty.
from .foo_two.foo_two import AClass, AnotherClass, OtherClass
from .foo_three.foo_three import AnotherClassMore
UPDATE: Correcting the syntax error in a previous command, while calling python -m myproject gives me a ModuleNotFoundError because of a module that isn't my responsibility, which is basically a library that is used in the project.
Hopefully, this will be of value to someone out there - I went through half a dozen stackoverflow posts trying to figure out relative imports similar to whats posted above here. I set up everything as suggested but I was still hitting ModuleNotFoundError: No module named 'my_module_name'
Since I was just developing locally and playing around, I hadn't created/run a setup.py file. I also hadn't apparently set my PYTHONPATH.
I realized that when I ran my code as I had been when the tests were in the same directory as the module, I couldn't find my module:
$ python3 test/my_module/module_test.py 2.4.0
Traceback (most recent call last):
File "test/my_module/module_test.py", line 6, in <module>
from my_module.module import *
ModuleNotFoundError: No module named 'my_module'
However, when I explicitly specified the path things started to work:
$ PYTHONPATH=. python3 test/my_module/module_test.py 2.4.0
...........
----------------------------------------------------------------------
Ran 11 tests in 0.001s
OK
So, in the event that anyone has tried a few suggestions, believes their code is structured correctly and still finds themselves in a similar situation as myself try either of the following if you don't just add your export the current directory to your PYTHONPATH:
Run your code and explicitly include the path like so:
$ PYTHONPATH=. python3 test/my_module/module_test.py
To avoid calling PYTHONPATH=., create a setup.py file with contents like the following and run python setup.py development to add packages to the path:
# setup.py
from setuptools import setup, find_packages
setup(
name='sample',
packages=find_packages()
)
The correct syntax would be
python -m myproject
This should execute __main__ in the top-level package.
You need to have __init__.py in each sub folder with python code to tell the interpreter to treat the folder as a module
/myproject
/foo_one
__init__.py # add this
foo_one.py
/foo_two
__init__.py # add this
foo_two.py
/foo_three
__init__.py # add this
foo_three.py
/foo_four
__init__.py # add this
foo_four.py
/foo_five
__init__.py # add this
foo_five.py
/foo_six
__init__.py # add this
foo_six.py
__init__.py
__main__.py
foo_seven.py
the __init__.py is telling the interpreter to treat sub folders as python modules / packages and you should be able to import
The __init__.py file can be empty but needs to be present in the sub folders to be able to import that module / package
I have the common problem of the "module not found" error when trying to import a file within a folder in my project directory as a package. I've tried several solutions from Stackoverflow answers, but none are working for me. Here's what's going on, and what I've tried:
I'm working in a conda environment devenv on a Flask project, using PyCharm, and have a project directory like this:
/some/path/project_root/
migrations/
static/
templates/
reporting/
__init__.py
code.py
tests.py
Inside the tests.py file there are import statements to import code.py as a module:
from .code import my_function
However, when I run (devenv) me#comp:project_root$ > python reporting/tests.py
I get the error: ModuleNotFoundError: No module named '__main__.code'; '__main__' is not a package
I tried appending the project directory path to $PYTHONPATH, and echo $PYTHONPATH returns /some/path/project_root/
What do I need to configure to get this to work properly? Also, whatever settings I need to change, can I make those settings specific to the development environment I'm using?
Change from .code import my_function to from code import my_function. The top level of a package is defined by the highest folder with an __init__.py file. So the top level of your project is the reporting folder and code.py does not need to be a relative import. Best to either avoid relative imports or get an editor like PyCharm that will take care of it for you!
Let's say my project structure looks like this:
app/
main.py
modules/
__init__.py
validation.py
configuration.py
modules package contains reusable code.
main.py executes main application logic.
When I try this in main.py
from modules import validation
I get an error which says that import inside of the validation failed. Validation tries to import configuration and I get 'no module named configuration'
I am using Anaconda distribution on windows.
What is the best way of handling PYTHONPATH during development of the package ?
Is there a way to utilize virtualenv (or conda env) in order to get package, that is in development,on the PYTHONPATH without changing sys.path from the code ?
What is the preferred practice when developing a package ?
I've also tried adding modules (folder) package to the lib/site-packages but it still didn't work.
Change your import in validation.py to:
from . import configuration
This is needed for Python 3 but also works with Python 2.
I'm currently on the last exercise (EX52) of Learn Python The Hard Way and I'm using Nose to test out the code (the exercise is to expand Nose testing to test out more of the code).
This is my file structure
bin
app.py
gothonweb
__init__.py
map.py
sessions
tests
map_tests.py
app_tests.py
The sample code tests out the map.py file using the map_tests.py code.
from nose.tools import *
from gothonweb.map import *
def test_room():
central_corridor = Room("Central Corridor" ...
So I thought I'd expand this by creating a second test file, called app_tests.py that tested the app.py file. It contains this code
from nose.tools import *
from bin.app import *
def test():
pass
When I run nosetests I get this error: ImportError: No module named bin.app
What am I doing wrong?
From your directory structure you can see that bin is not a python package. It is a directory that contains a python module named app as referenced by app.py. Python packages have an __init__.py file inside of folders. I could explain in more detail but it would probably be better to post a link for you to reference.
http://docs.python-guide.org/en/latest/writing/structure/
Since you don't have a __init__.py in your bin directory, it's just a directory, not a package. Since it's not a package, you can't look into the package to find the bin module.
From your parent directory, do
touch bin/__init__.py
on Mac/Linux, or
type NUL>bin\__init__.py
on Windows
I have a project directory that is set up in the following way:
>root
> modules
__init__.py
module1.py
> moduleClass
__init__.py
moduleClass1.py
moduleClass2.py
> scripts
runTests.py
> tests
__init__.py
test1.py
test2.py
run.sh
In runTests.py I have the following import statements:
import modules.module1
import modules.moduleClass.moduleClass2
import tests.test1
import tests.test2
The first two import statements work fine, but the second two give me the errors ImportError: No module named test1 and ImportError: No module named test2. I can't see what is different between the tests and modules directories.
I'd be happy to provide more information as needed.
When you run a script, Python adds the script's containing directory (here, scripts/) to sys.path. If your modules don't appear in sys.path any other way, that means Python may not be able to find them at all.
The usual solution is to put your scripts somewhere in your module hierarchy and "run" them with python -m path.to.module. But in this case, you could just use an existing test runner: Python comes with python -m unittest discover, or you might appreciate something fancier like py.test (pip install --user pytest).
The problem turned out to be that python didn't like the folder name tests. Changing the name to unit_tests solved the problem.