Alex 75
Alex 75

Reputation: 3236

import main file (not another module) from a subfolder

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

Answers (2)

Chrispresso
Chrispresso

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

univerio
univerio

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

Related Questions