2013-04-10 2 views
1

Наше основное приложение имеет некоторые дополнительные функции, которые пользователи могут включить. Эти функции находятся в их собственном каталоге. Для этих функций могут потребоваться дополнительные зависимости. Я собираюсь поместить их в файл requires.txt. Во время выполнения мы хотели бы сообщить людям, если функция сломается. В настоящее время я рассматриваю что-то вроде этого:python: Как проверить дополнительные требования во время выполнения?

def checkfeature(feature): 
    everything_okay = True 
    f = pkg_resources.resource_stream(feature, "requires.txt") 
    with f: 
    for r in pkg_resources.parse_requirements(f): 
     if pkg_resources.working_set.find(r) is None: 
     print "%r not found, please install, otherwise this feature does not work" % (r,) 
     everything_okay = False 
    return everything_okay 

Правильно ли это, питонический способ делать вещи? Имеет ли это смысл?

Небольшое обновление: Почему так сложны и не только try: import ... except ImportError: ... как предложено в одном ответе:

  1. Наши плагины могут иметь кучу зависимостей. Создание фактического кода, подобного приведенному ниже, довольно многословно.
  2. Некоторым плагинам может потребоваться определенная версия пакета. Тестирование, которое требует либо специфического теста pakcage, либо использования pkg_resources в любом случае. Вот почему моя идея выше использует pkg_resources.
  3. Мы хотим запустить модульные тесты для плагинов, которые можно запустить. Обработка ImportError в модульных тестах не является приятной. Наличие функции can_we_unit_test_this_plugin(plugin) упрощает работу.

Второе обновление: а как насчет extra_require в setup.py?

  1. людям не хватает, чтобы установить их часто. Ладно, плохое оправдание.
  2. Мое зрение - это то, что setup.py загружает extra_require прямо из вышеупомянутого requires.txt в индивидуальные подписи для отдельных элементов. Но это действительно следующий шаг.

ответ

4

Вообще, вы просто попробуйте импорта зависимость, и обрабатывать ImportError исключения изящно:

try: 
    import dependency 
except ImportError: 
    # dependency missing, issue a warning 
    import warnings 
    warnings.warn('dependency not found, please install to enable xyz feature') 

Вы можете перечислить такую ​​зависимость в extras_require записи ваших Setuptools на основе setup.py сценария. pip, easy_install и zc.buildout все может справиться с установкой таких дополнений. См. Declaring “Extras” (optional features with their own dependencies).

Вы можете использовать запись extras_require, чтобы указать минимальные требования к версии, если они есть. Да, есть вероятность, что у пользователя уже установлена ​​более старая версия установленной зависимости; Я просто четко документирую требования. Действительно, тест для функции, а не версии. Если вам нужна более новая версия, потому что был добавлен определенный метод API? Проверьте этот метод, а не версию.

Однако, это звучит так, как будто вы можете упаковать плагин, как отдельных пакетов вместо этого, то список тех в extras_require. Я бы использовал entry points для регистрации и перечисления таких плагинов. Таким образом, вы делаете не необходимо проверить на импорт или для пакетов, вы просто перечислите вместо них зарегистрированные точки входа. Каждый плагин перечисляет свои собственные зависимости и имеет собственные модульные тесты.

+0

Хорошо, я должен был добавить, что нам может понадобиться конкретная версия определенного пакета. И я должен был добавить, что мы хотели бы знать заранее, если функция будет работать. Потому что это способ включения модульных тестов для этой функции. В ближайшее время я улучшу свой вопрос. – Elrond

+0

Я также добавил примечание о 'extra_require' к моему вопросу. Я вижу это как разную часть истории. О проверке функции: Да, это обычно хорошо, но иногда может быть очень уродливым. Особенно, если вы попадаете в сложные ошибки в определенных версиях. Также обратите внимание: приведенная выше проверка не является единственным способом проверки. Особенность, о которой идет речь, может добавить к этой функции самостоятельно. – Elrond

+0

@ Elrond: расширенный; Я думаю, вы хотите разделить плагины на отдельные пакеты. –

Смежные вопросы