2

I'm just starting with Python and do have more experience with C#\Java. So what makes my head hurt is how do I import my Python modules to another custom module? I've already tried couple of things:

SO: Python can't find my module

SO: Cant import my own modules

SO: Import Error: no module named when importing my own module

and several more, but those generally sugget me to use relative imports (using appropriate number of . before import statement). It seems fragile to me because as far as I know imports are relative and resolved depending on where file.py was executed.

So here is my project structure in PyCharm:

Project
├───lib
│    ├───__init__.py
│    ├───pages
│    │   ├───__init__.py
│    │   ├───pageA.py
│    │   └───pageB.py
│    └───actions
│        ├───__init__.py
│        ├───actionA.py
│        └───actionB.py
├───tests
│    ├───__init__.py
│    ├───base_test.py
│    └───search_test.py
└───main.py

In my search_test.py I do import module from lib.actions.actionA import ActionA, in actionA.py I'm importing module like from lib.pages.pageA import PageA. And here is my main.py:

import unittest
from tests.search_test import SearchTest

def create_test_suite():
    test_suite = unittest.TestSuite()
    test_suite.addTest(SearchTest())
    return test_suite


if __name__ == 'main':
    suite = create_test_suite()
    runner = unittest.TextTestRunner(verbosity=2)
    runner.run(suite)

When I run this within PyCharm it works perfectly. But now I need to run it from console:

D:\Projects\Python Projects> python -m unittest project_name.main

and I'm facing ImportError: no module named 'lib'. With this:

D:\Projects\Python Projects\project_name> python main.py

nothing happens.

What can I do? Should I stick to relative pattern or there is some kind of Java-like packages importing?

Amrait Dalerian
  • 95
  • 1
  • 10
  • in your search_test.py file import os import sys sys.path.append(os.path.join(os.path.dirname(__file__),'../')) from lib.actions.actionA import ActionA and then you can run it from any directory. – parthiban Dec 18 '20 at 12:13

3 Answers3

1

When you face ImportError this means Python doesn't find your module. So, where does it look for modules?

Probably your PyCharm working directory fits your project. But when you execute it from command line, Python looks for modules in the current directory and in PYTHONPATH env variable. This env variable is translated into a list, which you can check with

import os
print os.sys.path

Make sure your project is in that path, and if not add it's directory to PYTHONPATH env variable. You can check this answer on instruction how to.

Also, you can update the env variable through command line, as explaiend here

Chen A.
  • 10,140
  • 3
  • 42
  • 61
  • Thanks for the suggestion, but what will happen if I ship this project to another machine? It seems that I will need to repeat the process of setting `PYTHONPATH` variable once again, isn't it? – Amrait Dalerian Oct 12 '17 at 17:17
  • Eventually you'll need to indicate Python where the lib is located. Or use packages, and ship packages instead of single scripts / libraries – Chen A. Oct 12 '17 at 18:21
  • That's interesting. You mean shipping whole project as a single package? – Amrait Dalerian Oct 12 '17 at 18:56
  • Yes. Add another hierarchy with a folder and perform relative imports to your project – Chen A. Oct 12 '17 at 21:47
1

I think instead of python -m unittest project_name.main you should change to the project_name folder and run python -m unittest main there

Shmygol
  • 913
  • 7
  • 16
  • Thanks for your update, but no, it doesn't work either. I'll be able to provide more details on that later, but if memory serves it says `cannot find main module` or `main is not a module`, if I remember correctly. – Amrait Dalerian Oct 12 '17 at 17:15
  • Are you sure you changed to the folder of your project `cd project_name`? It's pretty strange, if main is not found. – Shmygol Oct 13 '17 at 05:43
  • Actually, you are right. It was complaining about `SearchTest` not having `runTest` attribute, but not the error I said. My fault. I've modified `main.py` as suggested [here](https://stackoverflow.com/questions/19087189/python-unittest-testcase-object-has-no-attribute-runtest) and it worked as expected. Now, I do need to fix paths to external data and I'll be fine. – Amrait Dalerian Oct 13 '17 at 06:44
0

Modules are imported using sys.path list of paths. You can see what it contains:

import sys
print(sys.path)

will print something like:

['C:\\Users\\***\\miniconda3\\envs\\science\\python311.zip',
 'C:\\Users\\***\\miniconda3\\envs\\science\\DLLs',
 'C:\\Users\\***\\miniconda3\\envs\\science\\Lib',
 'C:\\Users\\***\\miniconda3\\envs\\science',

Your single task is to add an element representing the location of your module. It can be absolute or relative:

sys.path.append(r'..\..\the folder where my custom lib lives')
print(sys.path)

['C:\\Users\\***\\miniconda3\\envs\\science\\python311.zip',
 'C:\\Users\\***\\miniconda3\\envs\\science\\DLLs',
 'C:\\Users\\***\\miniconda3\\envs\\science\\Lib',
 'C:\\Users\\***\\miniconda3\\envs\\science',
 '..\\..\\the folder where my custom lib lives']

Then import the file as usual, if the file is a python script with extension .py, remove the extension when importing:

import custom_lib as cl
mins
  • 6,478
  • 12
  • 56
  • 75