Python nested subpackage doesn't import when running tests

巧了我就是萌 提交于 2020-01-24 09:29:27

问题


I have a folder structure like this:

api
-- test
    -- test_api.py
    -- __init__.py
-- api
    -- api.py
    -- __init__.py
    -- sub
        -- sub.py
        -- __init__.py

sub.py:

Base = 'base'

api.py:

from sub.sub import Base

def stuff_to_test(): pass

test_api.py:

from api.api import stuff_to_test

def test_stuff_to_test():
    stuff_to_test()

I am in directory api. I run pytest:

==================================== ERRORS ====================================
______________________ ERROR collecting tests/test_api.py ______________________
ImportError while importing test module '/<somepath>/api/tests/test_api.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_api.py:1: in <module>
    from ..api.api import stuff_to_test
api/__init__.py:1: in <module>
    from . import api
api/api.py:1: in <module>
    from sub.sub import Base
E   ImportError: No module named 'sub'
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=========================== 1 error in 0.08 seconds ============================

Same happens if I run the python interpreter and import stuff from test_api.py:

>>> from tests.test_api import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/<somepath>/api/tests/test_api.py", line 1, in <module>
    from api.api import stuff_to_test
  File "/<somepath>/api/api/__init__.py", line 1, in <module>
    from . import api
  File "/<somepath>/api/api/api.py", line 1, in <module>
    from sub.sub import Base
ImportError: No module named 'sub'

My first idea was to make the import in api.py relative:

from .sub.sub import Base

This way tests run fine. But if I run python api/api.py I get this error:

Traceback (most recent call last):
  File "api/api.py", line 1, in <module>
    from .sub.sub import Base
SystemError: Parent module '' not loaded, cannot perform relative import

How can I have it so tests run and application runs?


回答1:


I solved it by adding the following to test.__init__.py

project_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
api_path= os.path.join(project_path, 'api')
sys.path.append(api_path)



回答2:


In python there are two ways to import a module, with a relative path or with an absolute path. When you write from sub.sub import Base you are doing an absolute path import, for a relative path import write from .sub.sub import Base.

An absolute path import go look in the PYTHONPATH to find the starting point of your import, so you should write from api.sub.sub import Base.

For more information: Absolute vs. explicit relative import of Python module



来源:https://stackoverflow.com/questions/46810554/python-nested-subpackage-doesnt-import-when-running-tests

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!