Субмодуль не может импортировать родительский модуль (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
Что нужно сделать, чтобы это исправить? Какова лучшая практика с тестами в нескольких файлах?
Изменить: я попробовал несколько вещей, как предложено, и это то, что я сделал:
Я изменил направление тестов (как это было предложено в руководстве автостопом по питону. Вот как это выглядит сейчас:
modulewrapper |-mymodule (with the 2 files in it) |-... (docs, readME and this stuff) |-tests |-test_file1.py |-test_file2.py
Я импортировал
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".