Субмодуль не может импортировать родительский модуль (python)

Это каталоги моего модуля:

mymodule
|-__init__.py
|-file1.py
|-file2.py
|-test
  |-__init__.py
  |-test_file1.py
  |-test_file2.py

test_file1.py содержит эту команду: from .. import file1,


Для запуска тестов я сделал это (в командной строке): python3 -m unittest test.test_file1, (Когда я выполнил эту команду для всего test каталог, он просто сказал мне "все в порядке", но не нашел мои тесты.)

Ответ (также, конечно, в командной строке) был (без огромной части трассировки стека):

   File "/media/me/my_usb/backup me/myfolder/django projects/django-mymodule/mymodule/test/test_file1.py", line 1, in <module>
    from .. import file1
ValueError: attempted relative import beyond top-level package

Что нужно сделать, чтобы это исправить? Какова лучшая практика с тестами в нескольких файлах?


Изменить: я попробовал несколько вещей, как предложено, и это то, что я сделал:

  1. Я изменил направление тестов (как это было предложено в руководстве автостопом по питону. Вот как это выглядит сейчас:

    modulewrapper
    |-mymodule (with the 2 files in it)
    |-... (docs, readME and this stuff)
    |-tests
      |-test_file1.py
      |-test_file2.py
    
  2. Я импортировал mymodule после вставки направления следующим образом (я добавлял этот код в начале каждого тестового файла):

    import sys
    sys.path.insert(0, '../mymodule')
    import file1
    

Я начал тест как обычно: python3 -m unittest test_file1 из каталога тестов. Теперь произошло следующее: (сначала соответствующая часть трассировки стека, затем мое предположение):

File "/media/me/my usb/backup me/my folder/django projects/django-mymodule/tests/test_file1.py", line 4, in <module>
    import file1
  File "../mymodule/file1.py", line 4, in <module>
    from .file2 import MyClass1, MyClass2
SystemError: Parent module '' not loaded, cannot perform relative import

Как бороться с этой новой проблемой? (или это то же самое, что и раньше? Вряд ли это своего рода best_practice для изменения рабочего кода, чтобы можно было запускать тесты.)


Edit2: на данный момент я заменяю jusr from .file2 import someclass от from file2 import someclass, Может ли это иметь негативные побочные эффекты?

1 ответ

Решение

Для модуля test.test_file1, test это ваш пакет верхнего уровня. Вы не можете выйти за пределы этого для относительного импорта; вы можете связаться только с другими модулями внутри test пакет.

Либо беги python3 -m unittest mymodule.test.test_file1 (с вашим рабочим каталогом, установленным в родительский каталог mymodule) или добавить mymodule к вашему пути Python и использовать from mymodule import file1,

Как правило, наилучшей практикой является поставить tests каталог рядом с вашим проектом:

mymodule
|-__init__.py
|-file1.py
|-file2.py
tests
|-test_file1.py
|-test_file2.py

Обратите внимание, что нет __init__.py файл, но некоторые бегуны (особенно pytest, может потребовать один).

Вот как сам проект Django организует тесты, как и большинство других проектов Python (см., Например, click, requests или же flake8). Используйте тест-бегун для обнаружения тестов, таких как nose,

Вы должны добавить свой mymodule Конечно, это работает в родительском каталоге к пути Python, поэтому вы можете добавить

import os
import sys
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.dirname(here))

к началу ваших тестовых файлов, или положить это в utils.py файл, который вы положили в свой каталог тестов.

Также см. Раздел " Структура " в "Руководстве автостопом по Python".

Другие вопросы по тегам