jimifiki
jimifiki

Reputation: 5544

Basic Python import mechanics

I have the following directory tree:

project/
  A/
    __init__.py
    foo.py
  TestA/
    __init__.py
    testFoo.py

the content of testFoo is:

import unittest
from A import foo

from the project directory I run python testA/testFoo.py

I get a ModuleNotFoundError No module named A

I have two question: how to improt and run A.foo from TestA.testFoo and why is it so difficult to grasp the import logic in Python? Isn't there any debug trick to solve this kind of issues rapidly, I'm sorry I have to bother you with such basics questions?

Upvotes: 0

Views: 426

Answers (5)

bboumend
bboumend

Reputation: 510

When your are executing a file an environment variable called python path is generated, python import work with this variable to find your file to import, this path is generated with the path of the file you are executing and it will search in the current directory and sub directories containing an __init__.py file, if you want to import from a directory on the same level you need to modify your python path or change the architecture of your project so the file executed is always on top level.

you can include path to your python path like this :

import sys
sys.path.insert(0, "/path/to/file.py")

You can read more on import system : https://docs.python.org/3/reference/import.html

The best way in my opinion is to not touch the python path and include your test directoy into the directory where tested files are:

project/
  A/
    __init__.py
    foo.py
    TestA/
        __init__.py
        testFoo.py

Then run the python -m unittest command into your A or project directory, it will search into your current and sub directories for test and execute it.

More on unittest here : https://docs.python.org/3/library/unittest.html

Upvotes: 1

atline
atline

Reputation: 31654

You definitely cannot find A because python need look from sys.path, PYTHONPATH to find the module.

And python will automatically add current top level script to sys.path not currently directory to sys.path. So if you add print(sys.path) in testFoo.py, you will see it only add project/TestA to the sys.path.

Another word, the project did not be included in sys.path, then how python can find the module A?

So you had to add the project folder to sys.path by yourself, and, this just needed in top script, something like follows:

import unittest
import sys
import os
file_path = os.path.abspath(os.path.dirname(__file__)).replace('\\', '/')
lib_path = os.path.abspath(os.path.join(file_path, '..')).replace('\\', '/')
sys.path.append(lib_path)

Upvotes: 0

moonscar
moonscar

Reputation: 31

The recommended way in py3 may be like below

echo $pwd
$ /home/user/project
python -m testA.testFoo

The way of execute module python -m in python is a good way to replace relative references。

Upvotes: 0

Alex
Alex

Reputation: 199

Can you try this ?

Create an empty file __init__.py in subdirectory TestA. And add at the begin of main code

from __future__ import absolute_import

Then import as below :

import A.foo as testfoo

Upvotes: 1

Shintlor
Shintlor

Reputation: 812

Add the folder project/testA to the system pythonpath first:

import sys
sys.path.insert(0, "/path/to/pythonfile")

and try the import again.

Upvotes: 1

Related Questions