PEP8-импорт не в верхней части файла с sys.путь



Задача

PEP8 имеет правило о размещении импорта в верхней части файла:

Импорт всегда помещается в начало файла, сразу после любых комментариев и записей модуля, а также перед глобалами и константами модуля.

Однако в некоторых случаях я мог бы сделать что-то вроде:
import sys
sys.path.insert("..", 0)

import my_module

В этом случае утилита командной строки pep8 помечает мой код:

Импорт уровня модуля E402 не в верхней части файл

Каков наилучший способ достижения соответствия PEP8 модификациям sys.path?

Почему

У меня есть этот код, потому что я следую структуре проекта, приведенной в руководстве автостопщика по Python.

Это руководство предполагает, что у меня есть папка my_module, отдельная от папки tests, обе из которых находятся в одном каталоге. Если я хочу получить доступ к my_module из tests, я думаю, что мне нужно добавить .. к sys.path
202   5  

5 ответов:

Часто у меня есть несколько файлов с тестами в подкаталоге foo/tests моего проекта, в то время как модули, которые я тестирую, находятся в foo/src. Чтобы запустить тесты из foo/tests без ошибок импорта, я создаю файл foo/tests/pathmagic.py, который выглядит следующим образом;

"""Path hack to make tests work."""

import os
import sys

bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
modpath = os.sep.join(bp + ['src'])
sys.path.insert(0, modpath)

В каждом тестовом файле я использую

import pathmagic  # noqa

Как первый импорт. Комментарий "noqa" предотвращает pycodestyle/pep8 от жалоб на неиспользованный импорт.

Если есть только несколько импорта, вы можете просто игнорировать PEP8 на этих import строках:

import sys
sys.path.insert("..", 0)
import my_module  # noqa

Есть еще один обходной путь.

import sys
... all your other imports...

sys.path.insert("..", 0)
try:
    import my_module
except:
    raise

Я только что боролся с подобным вопросом, и я думаю, что нашел немного более приятное решение, чем принятый ответ.

Создайте модуль pathmagic, который выполняет фактическую sys.манипулирование путями, но внесите изменения в контекстном менеджере :

"""Path hack to make tests work."""

import os
import sys

class context:
    def __enter__(self):
        bp = os.path.dirname(os.path.realpath('.')).split(os.sep)
        modpath = os.sep.join(bp + ['src'])
        sys.path.insert(0, modpath)

    def __exit__(self, *args):
        pass

Затем в ваших тестовых файлах (или там, где вам это нужно) вы делаете:

import pathmagic

with pathmagic.context():
    import my_module
    # ...
Таким образом, вы не получите никаких жалоб от flake8/pycodestyle, вам не нужны специальные комментарии, и структура, кажется, имеет смысл.

Для дополнительной аккуратности рассмотрите возможность фактического возврата пути в блоке __exit__, хотя это может вызвать проблемы с ленивым импортом (если вы поместите код модуля вне контекста), так что, возможно, не стоит беспокоиться.


EDIT : просто увидел гораздо более простой трюк в ответе на другой вопрос: Добавьте assert pathmagic под вашим импортом, чтобы избежать комментария noqa.

Чтобы соответствовать PEP8, вы должны включить свой путь проекта в путь python для выполнения относительного / абсолютного импорта.

Чтобы сделать это, вы можете посмотреть на этот ответ: постоянно добавлять каталог в PYTHONPATH

    Ничего не найдено.

Добавить ответ:
Отменить.