'no module' error with __init__.py in directory using Nosetests - python

I have the following directory structure:
Chippa/
bin/
__init__.py
app.py
tests/
__init__.py
app_tests.py
tools.py
templates/
hello_form.html
index.html
layout.html
docs/
In my app_tests.py file, I have:
from nose.tools import *
from bin.app import app
from tests.tools import assert_response
When I try to run app_tests.py from outside of the tests directory, one level above the test directory inside the Chippa directory, like so:
python tests/app_tests.py
I get the following error:
Traceback (most recent call last):
File "tests/app_tests.py", line 3, in <module>
from bin.app import app
ImportError: No module named bin.app
But I do have an empty __init__.py in the bin directory, which I thought would have prevented this issue. What am I missing here?

For that import to work, you have to actually be running a proper module in the first place. So, rather than
python tests/app_tests.py
, try
python -m tests.app_tests

Related

How to write __init__.py (and perhaps __main__.py) file to avoid import ModuleNotFoundError

I thought I had understood the import system, however I'm struggling to understand an apparently trivial case: I have a very simple Python application with the following structure:
.
└── myapp
├── __init__.py
├── lib.py
└── myapp.py
The content of lib.py is a trivial function:
def funct():
print("hello from function in lib")
myapp.py is supposed to be the entrance point of the application:
import lib
def main():
lib.funct()
if __name__ == "__main__":
print("calling main")
main()
When I run the main script it works:
> python myapp/myapp.py
calling main
hello from function in lib
However, when I just import the package from IPython for instance, it fails:
In [2]: import myapp
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-2-cabddf3cb27d> in <module>
----> 1 import myapp
~/test/myapp/__init__.py in <module>
----> 1 import myapp.myapp
~/test/myapp/myapp.py in <module>
----> 1 import lib
2
3
4 def main():
5 lib.funct()
ModuleNotFoundError: No module named 'lib'
Why is this happening? Eventually, I'd like that my application is executable with python -m myapp, but also importable.
By default the import searches for module on the paths present in sys.path and one of the path present there is of current directory so
when you executed the main script:
python myapp/myapp.py
The import in myapp.py file searched for lib module in its current directory i.e "myapp" and as lib.py is in same directory, it executed perfectly
But when you imported myapp as a package in IPython,
The import in myapp.py file searches from IPython's path, where Lib.py is not present hence the classic no module found.
There are few things you can do here
use relevant path in myapp.py like
from . import lib
Note: This will generate error if you executed myapp.py directly as a script so handle accordingly
update the sys.path by appending lib.py's path (Not Recommended)
sys.path.append("....../lib.py")
watch this for clear understanding.
Also just to point out, __name__=="__main__" is only true when you execute the file directly. so the code inside if in myapp.py will not work when you'll use it as a module in package.
I hope this was helpful :)

ModuleNotFoundError in Python 3 but not in Python 2

I have a project I want to run on different machines without the need to modify the PYTHONPATH enviroment variable. My projects structure is as follows:
awesome_project/
data/
scripts/
__init__.py
predict/
importer/
__init__.py
__init__.py
predict.py
train/
importer/
__init__.py
__init__.py
train.py
utils/
__init__.py
configuration.py
In my predict and train code I need to import variables defined in the configuration file inside utils. In Python 2 I defined the importer module, in which the __init__.py had the following code:
import sys
from os import getcwd
from os.path import sep
root_path = sep.join(getcwd().split(sep)[:-2])
sys.path.append(root_path)
And it worked as a charm. I imported the variables as: from scripts.utils.configuration import models_path, but now I'm migrating my code to Python 3 and this does not work at all, I get the following error:
Traceback (most recent call last):
File "predict.py", line 11, in <module>
from scripts.utils.configuration import models_path
ModuleNotFoundError: No module named 'scripts.utils'
What am I doing wrong?

Python: include library folder when running from command line

I have a directory structure:
root_dir
├── src
│   └── p1.py
└── lib
├── __init__.py
├── util1.py
└── util2.py
I want to run src/p1.py which uses lib/util1.py using an import statement import lib.util1 as u1.
It runs fine when I use PyCharm, but I want to also run it from command line. How can I run the program from command line?
I have tried cd root_dir then python src/p1.py.
But it produces the following error:
Traceback (most recent call last):
File "./src/p1.py", line 1, in <module>
import lib.util1 as u1
ImportError: No module named lib.util1
How can I run the python program src/p1.py from the command line?
Edit: Based on the suggestion from #Sumedh Junghare, in comments, I have added __init__.py in lib folder. But still it produces the same error!
You need the following steps
Add __init__.py at lib folder.
Add this line at p1.py file on top
import sys
sys.path.append('../')
import lib.util1 as u1
Run the p1.py file from src dir. Hope it will work.
Edit:
If you do not want to add sys.path.append('../'), set PYTHONPATH in env-var from this resource.
How to add to the pythonpath in Windows?
Improving on Saiful's answer, You can do the following which will allow you to run the your program from any working directory
import sys
import os
sys.path.append(os.path.join(os.path.realpath(os.path.dirname(__file__)), "../"))
import lib.util1 as u1

Python 3.5 cannot import a module

I have read a ton of stackoverflow answers and a bunch of tutorials. In addition, I tried to read the Python documentation, but I cannot make this import work.
This is how the directory looks like:
myDirectory
├── __init__.py
├── LICENSE
├── project.py
├── README.md
├── stageManager.py
└── tests
├── __init__.py
└── test_project.py
There is a class in project.py called Project, and I want to import it in a file under tests directory. I have tried the following:
Relative import:
from ..project import Project
def print_sth():
print("something")
This gives me the following error: (running from the tests directory as python test_project.py and from myDirectory as python tests/test_project.py)
Traceback (most recent call last):
File "test_project.py", line 1, in <module>
from ..project import Project
SystemError: Parent module '' not loaded, cannot perform relative import
Absolute import with package name:
If I have something like the following, I get ImportError (with the same run command as above).
from project import Project
def print_sth():
print("something")
------------------------------------------------------
Traceback (most recent call last):
File "test_project.py", line 1, in <module>
from project import Project
ImportError: No module named 'project'
and this too:
from myDirectory.project import Project
def print_sth():
print("something")
------------------------------------------------------
Traceback (most recent call last):
File "test_project.py", line 1, in <module>
from myDirectory.project import Project
ImportError: No module named 'myDirectory'
Finally, I tried adding the if __name__ == '__main__' statement within the test_project.py file, but it still failed. I would really appreciate if anyone could help. If there is a solution where I do not have to write a verbose command, I would prefer that.
When you run a Python script by filename, the Python interpreter assumes that it is a top-level module (and it adds the directory the script is in to the module search path). If the script is in a package, that's not correct. Instead, you should run the module using the -m flag, which takes a module name in the same format as an import statement (dotted separators) and puts the current directory in the module search path.
So, you could run the test from myDirectory with: python -m tests.test_project. When you run the script this way, either of the kinds of imports you tried will work.
But if myDirectory is supposed to be a top-level package itself (as the __init__.py file suggests), you should probably go up one level further up, to myDirectory's parent, and run the script with two levels of package names: python -m myDirectory.tests.test_project. If you do this and want the test to use an absolute import you'd need to name the top level package that the project module is in: from myDirectory.project import Project.

Unable to load modules with my current python project structure

I have created a Flask application in portal/webapp.py. When I try to start the application using python portal/webapp.py I get the following error:
Traceback (most recent call last):
File "portal/webapp.py", line 3, in <module>
from db import TenantManager, QueryHandler
File "****/Project/portal/db.py", line 4, in <module>
from sql_parser.SQLParserTools import Parser, Builder
ImportError: No module named sql_parser.SQLParserTools
Here is my project structure
Project/
portal/
__init__.py
db.py
manage.py
test/
__init__.py
test_db.py
webapp.py
sql_parser/
__init__.py
error.py
SQLParserTools.py
StringParsers.py
test/
__init__.py
test_parser.py
I think you should add ..../Project/ to your PYTHONPATH variable.
Note that since there is no __init__.py in Project. You consider that portal and sql_parser are two different project. One which is using the other.

Categories