Reputation: 3236
I want to import "main" from a subfolder. Therefore every subfolder contains a __init__.py (but not "source", and its actual name is "Tracks Comparer"). My folders structure is like this:
source\
GPX\
engine.py (contains Engine class)
main.py
from GPX.engine import Engine
Tests\
Integration Tests\
GPX\
engineTest.py
mainTest.py
I want use "main" from mainTest.py, so I tried:
from ... import main
but it does'n work. Error: Attempted relative import in non-package
I use Visual Studio and with "Test Explorer" all tests run except for mainTest.py. For example in engineTest.py there is:
from GPX.engine import Engine
and not something like this:
from ...GPX.engine import Engine # this not works
and in mainTest.py the simple import main
works too.
To be more exact launching tests with Visual Studio works also for mainTest, BUT the import of Engine from GPX.engine fails (Error: engine module not found), I imagine because it refers to the GPX folder in the "Tests" folder. For these reasons, I think the unittest.run() is "called" from root (source folder) when Visual Studio launch tests.
To solve the problem I want to use relative paths (in tests files), but it doesn't work, as I said.
What's wrong in my relative path import? Is this the right way for doing the job? I'm using Python 2.7.
Solution for Attempted relative import in non-package: (in mainTest.py)
import os, sys
sys.path.append(os.path.join("..", ".."))
import main
Solution for engine module not found: (in mainTest.py)
#sys.path.append(os.path.join("..", ".."))
sys.path.insert(0, os.path.join("..", ".."))
# <-- this change set "source" earlier than "Integration Tests" in path.
Upvotes: 0
Views: 815
Reputation: 4071
Assuming you are currently in Integration Tests folder? What about this:
from os import path
import sys
currentDirectory = path.dirname(__file__)
sys.path.append(path.join(currentDirectory, '../../')) # This will get you to source
import main
Upvotes: 1
Reputation: 20518
Relative imports don't work at the file system level, so what you want to do can't be done with relative imports as you described.
It sounds like you are having issues with implicit relative imports (in mainTest
when you import GPX
it implicitly imports .GPX
instead of GPX
as a root module). You can turn off this behavior by adding this line at the top of all your test files:
from __future__ import absolute_import
This will make python import GPX
from sys.path
instead of .GPX
.
Upvotes: 0