Python Import Error - Run unittest - python

Why am I getting import error for a module I have in the project. All the packages are under the project, they all have __init __.py and other scripts do not give the same error. Python version is 3.6. Code was written in Unix environment.
Here is the import error I get. I am trying to run a test here.
Ran 1 test in 0.001s
FAILED (errors=1)
Error
Traceback (most recent call last):
File "/usr/lib/python3.6/unittest/case.py", line 59, in testPartExecutor
yield
File "/usr/lib/python3.6/unittest/case.py", line 605, in run
testMethod()
File "/usr/lib/python3.6/unittest/loader.py", line 34, in testFailure
raise self._exception
ImportError: Failed to import test module: test_SMSHandler
Traceback (most recent call last):
File "/usr/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName
module = __import__(module_name)
File "/home/sevvalboylu/server/app/api/test_SMSHandler.py", line 11, in <module>
from middleware.services import Sender
ModuleNotFoundError: No module named 'middleware'

Looks like you are missing a project's root path in PYTHONPATH
From the docs (Modules - The Module Source Path)
When a module named spam is imported, the interpreter first searches
for a built-in module with that name. If not found, it then searches
for a file named spam.py in a list of directories given by the
variable sys.path. sys.path is initialized from these locations:
The directory containing the input script (or the current directory
when no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
The installation-dependent default.
If this solution doesn't work for you, please post the project's tree to make it easier find the problem.

I've experienced a similar problem with import error when running unit tests (with correct importable structure), but the cause and the solution are different to described in the answer above. Still this is relevant and may help somebody.
In my case I have structure like that (__init__.py present but omitted below for brevity):
mypkg
\-- foo.py
another
tests
\-- some
\-- <tests here>
mypkg <--- same name as top level module mypkg
\-- test_a.py
When running from top level directory imports in test_a.py of modules from mypkg were failing:
# test_a.py
from mypkg import foo # causes ModuleNotFoundError: No module named 'mypkg.foo'
Renaming mypkg folder under tests folder into something else solved the problem.

Related

Do I have a problem with __init__.py files?

__init__.py files are meant to initialize packages and/or to set what directory is a package, as far as I know.
So my question is, even though these are implicitly run when a package/module is imported, is it normal to receive errors when you run that __init__.py file directly? and why?
I was testing a project I'm currently working on, which is working great, no errors when I import from root files, but what got my attention is that when I execute every module just to check for errors, all the __init__.py files are the ones that throws errors.
For the sake of education,
I followed these 'tutorials' and ran every __init__.py files of every package (directly, not importing a module/package) just to identify if I'm doing something wrong and received errors on those too.
Please, take a look at these examples:
Article: Understanding Python imports, __init__.py and pythonpath — once and for all
Traceback (most recent call last):
File "c:\Users\username\Desktop\python_packages_tutorial\utils\__init__.py", line 1, in <module>
from utils.lower import to_lower
ModuleNotFoundError: No module named 'utils'
I even added the directory to PYTHONPATH env variable, and sys.path even recognizes the directory where it is located. As I said before, it's just happening when I directly execute the init.py file, the rest is working well.
Article: Introduction to Create Own Python Packages
Traceback (most recent call last):
File "c:\Users\username\Desktop\medium_python_packages\my_package\__init__.py", line 1, in <module>
from .my_module1 import *
^^^^^^^^^^^^^^^^^^^^^^^^^
ImportError: attempted relative import with no known parent package
My project __init__.py file:
sys.path
[
'c:\\Users\\username\\Desktop\\code\\projects\\flask_app\\register',
'C:\\Users\\username\\Desktop\\code\\projects\\flask_app\\register', <-- PYTHONPATH env
'C:\\Users\\username\\AppData\\Local\\Programs\\Python\\Python311\\python311.zip',
'C:\\Users\\username\\AppData\\Local\\Programs\\Python\\Python311\\DLLs',
'C:\\Users\\username\\AppData\\Local\\Programs\\Python\\Python311\\Lib',
'C:\\Users\\username\\AppData\\Local\\Programs\\Python\\Python311',
'c:\\Users\\username\\Desktop\\code\\projects\\flask_app\\flask',
'c:\\Users\\username\\Desktop\\code\\projects\\flask_app\\flask\\Lib\\site-packages'
]
Traceback
Traceback (most recent call last):
File "c:\Users\username\Desktop\code\projects\flask_app\register\__init__.py", line 10, in <module>
from register.routes import *
ModuleNotFoundError: No module named 'register'
But they are working as expected.

"ModuleNotFoundError: No module named ..." error when running a unittest that is in tests folder in python

I have the following file/folder structure:
testpackage (folder)
src (folder)
__init__.py
module1.py
tests
__init__.py
test_module1.py
just for clearance: the "module1.py" is under the "src" folder which is under the "testpakcage" folder.
"tests" is also under the "testpakcage" folder - same level as the "src" one.
module1.py has a class named "class1" as so:
class class1:
def method1 (self):
print('i am method1')
in test_module1.py I want to run tests on the above module. this is it's contents:
import unittest
from testpackage.src import module1
t = module1.class1()
t.method1()
this package is not installed, and I don't instead to install or submit it anywereh, I'm just trying to find the best structuring practice for me, for future packaging creation.
problem is: when I run the following either from the "tests" or "testpackage" folder:
/usr/bin/python3.6 -m unittest discover
I get the following error:
E
======================================================================
ERROR: test_module1 (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_module1
Traceback (most recent call last):
File "/usr/lib64/python3.6/unittest/loader.py", line 428, in _find_test_path
module = self._get_module_from_name(name)
File "/usr/lib64/python3.6/unittest/loader.py", line 369, in _get_module_from_name
__import__(name)
something similar also happens when I just try to run "test_module1.py" from the "tests" folder:
Traceback (most recent call last):
File "test_module1.py", line 5, in <module>
from testpackage.src import *
ModuleNotFoundError: No module named 'testpackage'
so I tried changing the "import" line with a few alternatives but none of them work. each one of those was a different attempt (not all of them at once):
from testpackage.src import *
import testpackage.src.module1 as module1
import ..src.module1
from ..src.module1 import class1
searching stackoverflow I found solutions that worked for some but not for those using python 3 and above - which is my case.
any suggestions? I think what I'm trying to do is rather simple and I'm missing something really basic here.
I'm using python3.6 by way
I'm wondering if you saw different errors for some of those different import attempts you made. Not sure if this will solve your problem, but this is one way it would generally be accomplished.
First, I am not sure what the top level of your package is supposed to be. Do you reference testpackage in any of the code in the src folder? If so, that top folder should also contain an __init__.py file.
Now, at the very top of your test_module1.py file, add:
import sys
pkg_dir = ".." # if "src" if the top level folder else "..." if testpackage is the top level folder
sys.path.append(pkg_dir)
Note you must change pkg_dir depending on your module's structure.(which I cannot tell from your question).
What this code does is add the folder containing the top level folder of your package to the python import search tree. This can solve problems that the relative import in your example file will not: if the files in your module use module-level imports (e.g. import testpackage.src.module2 in module1.py). This is common in packages with multiple submodules that cross-import.

ImportError: No module named utils.read

I have a main.py file in the folder project and read.py in the folder ./project/utils. In the main.py, I called
import sys, os
sys.path.append('./utils/')
from utils.read import function1
However, when I use the python main.py command, I got the error
ImportError: No module named utils.read. What should I change? Thanks all
i think you need to add __init__.py
in your directory..
make sure you have __init__.py in utils folder.. then only python will understand it is package folder contains py
__init__.py specifies that the folder is actually a package. a package in python is a directory containing .py files (modules). In every folder which is a package (that is, a folder containing multiple .py files) you should define __init__.py.
It can be empty, or you can put some statements to execute when the package is imported (or modules from the package).
For exmaple, let's take this directory tree:
/dev/package/greeter.py
and current working directory is /dev.
>>> from package import greeter
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
from package import greeter
ImportError: No module named package
import pakcage results in the same error. When adding __init__.py into the package folder, it works. My init is simple as
print 'init executed'
>>> from package import greeter
init executed
>>>
One common functionality to put in __init__.py is the __all__ variable. You can read more about it here Can someone explain __all__ in Python?

Simple migration to __init__.py

I'm upgrading a bunch of scripts where the ecosystem is a bit of a mess. The scripts always relied on external modules, and didn't have any package infrastructure of their own (they also didn't do much OOP, as you can imagine). There's nothing at the top level, but it is the working directory when starting Python and I'd like to keep it that way. At the top-level, I've just created __init__.py file (based on another question). As I'm less experienced with Python __init__.py confuses me a bit. All of the __init__.py files I've created are empty, it's my understanding that this is all that's required.
Assume I have the following directory structure:
__init__.py
dev.properties
prod.properties
F/
Foo.py
__init__.py
B/
bar.py
__init__.py
And the code is like this :
# Foo.py
from ..b import bar
barFunc()
# bar.py
def barFunc():
print "Hello, World!"
sys.stdout.flush()
I've created __init__.py at the root, in F/ and in B/. However, when I run python F/Foo.py, I get an error:
Traceback (most recent call last):
File "F/Foo.py", line 3, in <module>
from ..b import bar
ValueError: Attempted relative import in non-package
What exactly would I need to do to invoke python F/Foo.py and be able to depend on things defined in sibling directories?
Update
Thanks to #user2455127, I realized that I forgot to remove the file extension .py and my working directory was wrong. From the mypackage directory, running python -m mypackage/F/Foo, the error was : myvirtualenv/bin/python: No module named mypackage/B/bar.
Re-reading #user2455127's post, I ran from the directory above and get a long Traceback:
Traceback (most recent call last):
File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
"__main__", fname, loader, pkg_name)
File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
exec code in run_globals
File "<full path>/mypackage/foo/Foo.py", line 24, in <module>
from ..b import bar
ValueError: Attempted relative import in non-package
I'm not quite sure what needs to be done to fix this, but it seems like the __package__ attribute may help. I'll try and figure that out, and post another update.
If the current working directory is F's and B's parent directory, then F and B are available as modules to all Python code. You should run:
$ F/foo.py
and then F/foo.py should contain
from B.bar import barFunc
barFunc()
As for __init__.py, that file's existance simply makes the directory an importable module. If you want to know more about it, check the docs on how imports work. (For most people, reading all of that isn't necessary.)
Relative imports can be pretty messy, so I'd advise shying away from them for now.
Have a look to this :
Attempted relative import in non-package even with init.py and brenBarn's answer
If you run it from the folder upper than the one with dev.properties and the others files (called lambda in my case), with this command line :
python -m lambda.F.Foo
it works.

ImportError: No module named test when ___init__.py is included

I created a python project in this format:
I tried to run my test_jabba.py by cding into the tests directory and running the program and I received this error:
Traceback (most recent call last):
File "./test_jabba.py", line 12, in <module>
from tests import testbench
ImportError: No module named tests
I read around and I realized I needed __init__.py to tell python where other packages are located.
Top portion of test_jabba.py
from tests import testbench
from utils import gopher, jsonstream
I did not add __init__.py into my logs and resources directories as they do no contain any python.
My best guess would be that poc is not in your PYTHONPATH. You can either set/extend the environment variable to contain poc, or
you can manipulate the path in your script using os.path. Your imports, in this case, will have to change accordingly:
from poc.tests import testbench
from poc.utils import gopher, jsonstream
Alternatively, you can use a relative import, to import tests and utils:
from ..tests import testbench
from ..utils import gopher, jsonstream

Categories