How to fix "ImportError: No module named ..." error in Python?
Asked Answered
C

7

139

What is the correct way to fix this ImportError error?

I have the following directory structure:

/home/bodacydo
/home/bodacydo/work
/home/bodacydo/work/project
/home/bodacydo/work/project/programs
/home/bodacydo/work/project/foo

And I am in the directory

/home/bodacydo/work/project

Now if I type

python ./programs/my_python_program.py

I instantly get

ImportError: No module named foo.tasks

The ./programs/my_python_program.py contains the following line:

from foo.tasks import my_function

I can't understand why python won't find ./foo/tasks.py - it's there.

If I do it from the Python shell, then it works:

python
>>> from foo.tasks import my_function

It only doesn't work if I call it via python ./programs/my_python_program.py script.

Cello answered 24/2, 2010 at 12:31 Comment(0)
D
148

Python does not add the current directory to sys.path, but rather the directory that the script is in. Add /home/bodacydo/work/project to either sys.path or $PYTHONPATH.

Doorstep answered 24/2, 2010 at 12:47 Comment(6)
So whats the point then of having init.py in the root folder? It seems to serve no purpose if you edit either sys.path or the pythonpath.He
@Editor: __init__.py only indicates that the directory should be treated as a package, when its parent is either in sys.path or is itself a package.Doorstep
In addition check the permissions on the folder. That was the problem in my case.Haukom
tried both still not working, I am using python 2.7 on macOs Sierra(10.12).Miscarry
To add current dir to python path, use export PYTHONPATH=`pwd`Moina
What worked for me was to add to $PYTHONPATH the parent directory of the project, in your case will be: /home/bodacydo/work ... see this answerTortilla
F
37

Do you have a file called __init__.py in the foo directory? If not then python won't recognise foo as a python package.

See the section on packages in the python tutorial for more information.

Flowery answered 24/2, 2010 at 13:0 Comment(4)
Thanks and yes, I had __init__.py. The problem this time was with $PYTHONPATH. Ignacio's solution worked.Cello
The init.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, init.py can just be an empty fileCaton
Thanks for saving me sometime.Inunction
__init__.py has nothing to do with making absolute imports work, and has not been required to make relative imports work since 3.3.Kosiur
T
11

A better fix than setting PYTHONPATH is to use python -m module.path

This will correctly set sys.path[0] and is a more reliable way to execute modules.

I have a quick writeup about this problem, as other answerers have mentioned the reason for this is python path/to/file.py puts path/to on the beginning of the PYTHONPATH (sys.path).

Tryst answered 17/7, 2017 at 16:39 Comment(0)
C
9

Here is a step-by-step solution:

  1. Add a script called run.py in /home/bodacydo/work/project and edit it like this:

    import programs.my_python_program
    programs.my_python_program.main()
    

    (replace main() with your equivalent method in my_python_program.)

  2. Go to /home/bodacydo/work/project
  3. Run run.py

Explanation: Since python appends to PYTHONPATH the path of the script from which it runs, running run.py will append /home/bodacydo/work/project. And voilà, import foo.tasks will be found.

Cerda answered 25/10, 2011 at 7:38 Comment(0)
P
8

Example solution for adding the library to your PYTHONPATH.

  1. Add the following line into your ~/.bashrc or just run it directly:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
    
  2. Then link your required library into your ~/.python folder, e.g.

    ln -s /home/user/work/project/foo ~/.python/
    
Plectron answered 1/8, 2014 at 10:20 Comment(0)
I
2

In my mind I have to consider that the foo folder is a stand-alone library. I might want to consider moving it to the Lib\site-packages folder within a python installation. I might want to consider adding a foo.pth file there.

I know it's a library since the ./programs/my_python_program.py contains the following line:

from foo.tasks import my_function

So it doesn't matter that ./programs is a sibling folder to ./foo. It's the fact that my_python_program.py is run as a script like this:

python ./programs/my_python_program.py

Insurgency answered 24/2, 2010 at 18:14 Comment(0)
U
1

If you have this problem when using an instaled version, when using setup.py, make sure your module is included inside packages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
Unifoliolate answered 22/11, 2019 at 9:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.