Ex46 ModuleNotFoundError

You need NAME.py too in the NAME Directory. Your test file tries to import a module called NAME but it doesn’t exist.

Think of the package having folders and files within. The init helps python know it’s a package (and you can do stuff with the init when you get more advanced).

So if your tests try to import NAME, it’s actually the module/file (NAME.py) it’s looking for.

@zedshaw + @gpkesley thanks for the advice! I added NAME.py to the NAME directory, so now the structure looks like:

  • skeleton
    • NAME/
      • _ init _.py
      • NAME.py
    • bin/
    • docs/
    • setup.py
    • tests
      • NAME_tests.py
      • _ init _.py

I cleared out the pycache files and am still having the same error though. Any thoughts? Is there something else I should be adding to the new NAME.py file?

Have you double-checked your setup.py includes the NAME module under packages too?


So the setup basically say here is the set up for this programme. It called, blah, blah, blah, by someone, and for it to work, you need the ‘NAME’ module which is part of this package.

@gpkesley I have! My setup.py looks like this as per LPTHW:

from setuptools import setup
except ImportError:
from distutils.core import setup

config = {
‘description’: ‘My Project’,
‘author’: ‘My Name’,
‘url’: ‘URL to project’,
‘download_url’: ‘URL to download project’,
‘author_email’: ‘My email’,
‘version’: ‘0.1’,
‘install_requires’: [‘nose’],
‘packages’: [‘NAME’],
‘scripts’: [],
‘name’: ‘projectname’


I’m going to bet you wrote:

_init_.py – underscore init underscore dot py

But it should be:

__init__.py – underscore underscore init underscore underscore dot py

In fact, I bet if you did that there you my have done it all over. The place you added the NAME.py file would require you to do this:

import NAME from NAME

So that’s probably not what you wanted. I also see you have this single underscore in tests as well. Check it. It could be just the formatting on here though.

@zedshaw I do have underscore underscore init underscore underscore dot py for all my init files in my local drive. The first time I quoted my directory structure in this forum, I believe that the double underscore acted like markup and automatically bolded init, removing said underscores, so I added a blank space and single underscore for clarification in my second comment.

tl;dr My filenames are formatted correctly, I just messed it up in commenting. Still stumped.

Have you tried an absolute path?
from .NAME import NAME
I googled and found this answer, but don’t know if you tried it:

Alright then at this point you’re going to have to make a video for us since there’s nothing else that could be wrong. If you have all the files, you’re inside skeleton and not above it, you have the correct underscores, you’ve set PYTHONPATH, then we can’t figure it out without screenshots of the fail or a video. A screenshot would work but you’d have to do:

  1. pwd and ls where you are
  2. the export PYTHONPATH
  3. The nosetest run and result.

Other mistake people make is they cd tests to try to run them. Once you do that python thinks this is the project root and tries to import files from there, so it expects tests/NAME.py to exist. Never cd down into lower directories to run things. You always stay in the project root.

If you don’t have a quick and easy recorder and you are using chrome :face_with_raised_eyebrow: the try https://chrome.google.com/webstore/detail/screen-recorder/hniebljpgcogalllopnjokppmgbhaden?hl=en

@zedshaw I finally figured this out thanks to your last bit of advice! I was cd’ing down into lower directories to run them, rather than staying in the project root. Everything works fine now, thanks!

1 Like

Thanks for sharing the solution.

Yep, the general rule is this:

Never ever CD down into a project directory. All of the modules expect your python interpreter to be located in the root (top) of the project, when you CD down into the lower directories it throws off where modules are. So, imagine you have this project:


Now imagine that bin/app.py has this inside it:

from code.stuff import TheThing

That import maps like this:

  • code -> code/
  • code.stuff -> code/stuff.py
  • TheThing -> code/stuff.py:class The Thing

So if you were to do a full path of python and map that to a full path on the disk it’d be:

code.stuff.TheThing ===> code/stuff.py:TheThing

That : after .py is a way of saying “Wherever TheThing is defined inside stuff.py” similar to if I wrote “code/stuff.py:42” to get line 42 of code/stuff.py.

Now, imagine if you do this:

cd bin/
python app.py

Your first line tries to load TheThing from the module code.stuff, which then causes python to do this:

  1. look in the current directory for a code/ or code.py file.
  2. Current directory is…bin/ OopS! code/ is one directory up, so this module can’t be found.

The solution is to do this:

$ cd bin/
$ python app.py
# oops I'm in the wrong directory
$ cd ..
$ python bin/app.py
# Ahhhhhh now we're home.

Having same problem as OP, can’t fix it.

I am not CD’ing into a lower directory (e.g. “\ProjectName\tests”).

Name of project is DumbProject. There’s a module (dumb.py) in the appropriate directory along with the required “init.py” file.

Here is my dumb_tests.py (likewise in the appropriate folder with an empty “init.py” file):

from nose.tools import *
import dumb

def setup():
    print "SETUP!"

def teardown():
    print "TEAR DOWN!"

def test_meat():
    print "Doll steak!"

Of course, if I try to run this Python complains it can’t find the module “dumb.”

The instructions in the video / book don’t work as they’re only for Mac or Linux. I’m working on a Windows 10 system. Please help, I’m totally lost.

Just in case it’s some kind of odd path problem, here also is the result of a full ls -r command (I have the Windows Subsystem for Linux installed):

PS C:\Users\WinTenProBox\Google Drive\Python\test_directory\projects\DumbProject> ls -r                                 

    Directory: C:\Users\WinTenProBox\Google Drive\Python\test_directory\projects\DumbProject

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2020-05-28     11:06                bin
d-----       2020-05-22     09:25                docs
d-----       2020-05-28     14:13                dumb
d-----       2020-05-28     14:13                tests
-a----       2020-05-28     12:56            495 setup.py

    Directory: C:\Users\WinTenProBox\Google Drive\Python\test_directory\projects\DumbProject\bin

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2020-05-28     11:10            254 frobnicate.py

    Directory: C:\Users\WinTenProBox\Google Drive\Python\test_directory\projects\DumbProject\dumb

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2020-05-28     06:43            204 dumb.py
-a----       2020-05-22     09:30              0 __init__.py

    Directory: C:\Users\WinTenProBox\Google Drive\Python\test_directory\projects\DumbProject\tests

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2020-05-28     14:13            163 dumb_tests.py
-a----       2020-05-22     09:30              0 __init__.py

Python path seems to be one of the biggest issues that people face when starting out, and when using Nose (which is ivortually deprecated) the whole issue seems more so.

You can check that the module is in the path by adding the directory and checking the path afterwards.

Alternatively, bin Nosetest for unittest or better still, Pytest.

I know @zedshaw considers this book complete/done/finalised, but I do wonder if this section needs to be overhauled in light of the number of issues people have with Nose?

(@zedshaw I’m happy to have a go if it helps…)

1 Like

For now I’d like to stick with the book as-written. I’ll tackle unittest, Pytest, and whatever else is new and different, later.

So how do I fix this?

I made an addition to the code I posted above. I had “dumb_tests.py” print what it thinks the “path” is before attempting to import module “dumb.” To wit:

from os import sys
from nose.tools import *
print sys.path

When I run this revised version of “dumb_tests.py”, it looks like this:

PS C:\Users\WinTenProBox\Google Drive\Python\test_directory\projects\DumbProject> python .\tests\dumb_tests.py
['C:\\Users\\WinTenProBox\\Google Drive\\Python\\test_directory\\projects\\DumbProject\\tests', 'C:\\Windows\\SYSTEM32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Users\\WinTenProBox\\AppData\\Roaming\\Python\\Python27\\site-packages', 'C:\\Python27\\lib\\site-packages']
Traceback (most recent call last):
  File ".\tests\dumb_tests.py", line 5, in <module>
    import dumb
ImportError: No module named dumb

For some reason Python has the \tests subdirectory of my project in sys.path, but not the \dumb subdirectory. I guess that’s where the problem lies.

I think I found at least a temporary fix. If I add the following to “dumb_tests.py” before attempting to import module “dumb”:


then “dumb_tests.py” completes successfully. Not sure whether this is the “textbook” answer but it seems to work.

I am having other difficulties with “setup.py” - it thinks one of my /bin scripts isn’t there. Another path problem I expect.

I noticed that and it is totally weird. Why would tests/ end up in your PYTHONPATH?

Close that powershell window, start a new one, or maybe even reboot your machine just to be sure, then go back and see if it’s there still.

Don’t know. /tests ends up in PYTHONPATH each time though. Tried rebooting and reopening Powershell.

I guess I have to add the appropriate folder to sys.path within each test script, or in anything else that is going to call something found in a subfolder (like /dumb/dumb.py)

You really need to find out why that’s happening because it means that somehow that directory was added to your system path and it will cause you problems later. Go into your system path and see if you can remove it. Also, the only way that I can think of this happening is if you added that directory to your system path then forgot about it.

You can temporarily fix this by typing this into your powershell:


That will tell python that the path to use should include whatever directory you’re currently in (that’s the dot.)

I’m getting the same error… How did you get through this thing?

A free service run by Zed A. Shaw for learncodethehardway.org.