Search code examples
pythonrelative-import

Python relative import not working even though root package name is being used


I've read quite a bit about relative import's tricky aspects (especially this question). However, the following example is still not working.

I have the following project (available on GitHub):

DirectoryTree

Here's test_some_unit.py:

import unittest

from ..util.foo import run_foo


class TestSomeUnit(unittest.TestCase):
    def test_some_unit(self):
        run_foo()
        print("Unit package")

The integration side is analogous.

Running discovery from current working directory UnittestDiscoverywhich is the parent of package, for the root package package produces a relative import error:

UnittestDiscovery> python -m unittest discover package
EE
======================================================================
ERROR: integration.test_some_integration (unittest.loader._FailedTest.integration.test_some_integration)
----------------------------------------------------------------------
ImportError: Failed to import test module: integration.test_some_integration
Traceback (most recent call last):
  File "C:\ProgramData\anaconda3\Lib\unittest\loader.py", line 407, in _find_test_path
    module = self._get_module_from_name(name)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\Lib\unittest\loader.py", line 350, in _get_module_from_name
    __import__(name)
  File "C:\Users\rodrigobraz\Documents\PyCharmProjects\UnittestDiscovery\package\integration\test_some_integration.py", line 3, in <module>
    from ..util.foo import run_foo
ImportError: attempted relative import beyond top-level package


======================================================================
ERROR: unit.test_some_unit (unittest.loader._FailedTest.unit.test_some_unit)
----------------------------------------------------------------------
ImportError: Failed to import test module: unit.test_some_unit
Traceback (most recent call last):
  File "C:\ProgramData\anaconda3\Lib\unittest\loader.py", line 407, in _find_test_path
    module = self._get_module_from_name(name)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\ProgramData\anaconda3\Lib\unittest\loader.py", line 350, in _get_module_from_name
    __import__(name)
  File "C:\Users\rodrigobraz\Documents\PyCharmProjects\UnittestDiscovery\package\unit\test_some_unit.py", line 3, in <module>
    from ..util.foo import run_foo
ImportError: attempted relative import beyond top-level package


----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (errors=2)

Why does this fail?


Solution

  • In answer to the comment Python relative import not working even though root package name is being used

    Thanks. I am running from the directory above package (it's called UnittestDiscovery) so I would expect module test_some_unit to have name test.unit.test_some_unit, leading ..util to refer to test.util. Is this reasoning incorrect?

    The reasoning is correct (although I don't see any test package) – however probably once the tests are discovered unittest tries to run them from their directory hence you get the error on the top level package – so you should find a way to instruct unittest to run the tests using the -m switch, from the parent of the root package as you do. Don't do the sys.path.append hack, by all means.