8

I've searched for some time to find a solution to this problem but have come up dry. I'm hoping I can find some help here. As the title suggests, python is not recognizing a module that has been set in my PYTHONPATH.

I'm currently working on a project that has the following overall structure:

base
├── util
│   └── logging_utility.py
└── project
    └── app
        ├── config.py
        └── runner.py

This is executed in python 3.5 via a virtual environment called venv_1. I use a Mac running El Capitan.

My runner.py script calls the logging_utility using the following import statement:

from util.logging_utility import method.

When executing, I receive this error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'util.logging_utility'

I am running this in the terminal from the base level of the directory. I'm using the following command to call the script:

PYTHONPATH=$HOME/base VIRTUAL_ENV=$HOME/.virtualenvs/venv_1 PATH=$VIRTUAL_ENV/bin:$PATH $HOME/.virtualenvs/venv_1/bin/python -- project/app/runner.py

Now, I've tried to debug this by printing out my env as well as sys.path. In both cases, the base directory appears in the path. So why on earth am I receiving this error?

I've also tried to update the import statement to from base.util.logging_utility import method which gives me the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'base'

Any idea why this is happening and how I can correct this?

Thanks!

UPDATE

Thanks to Billy and Moinuddin Quadri whose suggestions solved the issue. For some reason I still needed to add the __init__.py files. Even though python 3.3+ supports implicit imports, looks like it was still needed. This solved the problem.

Community
  • 1
  • 1
Marto
  • 171
  • 3
  • 10
  • How was Python installed? Through the Python desktop installer or Anaconda? – Ébe Isaac Nov 18 '16 at 18:27
  • 2
    Put an empty `__init__.py` file in your `util`, `project` and `app` directories to make them Python packages. – Billy Nov 18 '16 at 18:28
  • @ÉbeIsaac it was installed using Homebrew. – Marto Nov 18 '16 at 18:41
  • ...although I don't think that will fully solve your problem, since in python 3.5 it should implicitly treat your `util` directory as a `namespace package`: https://docs.python.org/3/reference/import.html?highlight=namespace%20package#namespace-packages... – Billy Nov 18 '16 at 18:42
  • @Billy I was under the impression python3.5 [no longer requires](http://stackoverflow.com/a/37140173/4942372) the `__init__.py` file. Is that not correct? – Marto Nov 18 '16 at 18:42
  • @Marto, yes, it was merely a suggestion since you probably should still use the `__init__.py` file so you're not inadvertently invoking a complex feature of the language. – Billy Nov 18 '16 at 18:43
  • 1
    Now that would be a slight problem. You see, Homebrew and MacPorts have their own PYTHONPATH preset. – Ébe Isaac Nov 18 '16 at 18:44
  • @Billy you were correct. for some reason I still needed to add the `__init__.py` files. This solved the problem. – Marto Nov 18 '16 at 19:06

1 Answers1

7

You might not be having the path to package in your PYTHONPATH. In order to add that, do:

 import sys
 sys.path.append('/absolute/path/to/base')

Since from Python 3.3, you do not need the __init__.py.

For the older version, the other possible reason is missing __init__.py. If you do not have a __init__.py file present in the directory, you can not import files of that directory.

As is mentioned in the Packages Document:

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 file, but it can also execute initialization code for the package or set the __all__ variable, described later.

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • 2
    I thought `__init__.py` is [no longer needed](http://stackoverflow.com/a/37140173/4942372) in python 3.3+. – Marto Nov 18 '16 at 18:43
  • you were correct. for some reason I still needed to add the `__init__.py` files. This solved the problem. – Marto Nov 18 '16 at 19:06
  • for anyone going insane why you can't import despite adding your module directory to PYTHONPATH with `os.environ`, named function `__import__` doesn't look for paths in PYTHONPATH. They are added to `sys.path` once python is executed. – NONONONONO Jun 11 '21 at 03:17