Подтвердить что ты не робот

Почему в проектах Python нет файлов Makefile для автоматизации?

Интересно, как программисту на Python долгое время ускользал от меня основной аспект: что мы делаем вместо Makefiles?

Большинство ruby-проектов, которые я видел (не только rails), используют Rake, вскоре после того, как node.js стал популярным, появился торт. Во многих других (скомпилированных и некомпилированных) языках существуют классические файлы Make.

Но в Python никому не нужна такая инфраструктура. Я случайно выбрал проекты Python на GitHub, и у них не было никакой автоматизации, кроме установки, предоставляемой setup.py.

В чем причина этого?

Разве нечего автоматизировать? Большинство программистов предпочитают запускать проверки стиля, тесты и т.д. Вручную?

Некоторые примеры:

  • dependencies устанавливает virtualenv и устанавливает зависимости
  • check вызывает pep8 командной строки pep8 и pylint.
  • test задание зависит от dependencies включает virtualenv, запускает selenium-server для интеграционных тестов и вызывает nosetest
  • задача coffeescript компилирует все сценарии coffeescript в минимизированный JavaScript
  • задача runserver зависит от dependencies и coffeescript
  • Задача deploy зависит от check и test и развертывания проекта.
  • задача docs вызывает sphinx с соответствующими аргументами

Некоторые из них являются одноступенчатыми, но, по-моему, они складываются. Из-за Makefile мне не нужно их запоминать.

Чтобы уточнить: я не ищу Python эквивалент для Rake. Я рад с асфальтоукладчиком. Я ищу причины.

4b9b3361

Ответ 1

Нет ли чего автоматизировать?

Не совсем. Все, кроме двух примеров, являются однострочными командами.

tl; dr Очень мало этого действительно интересно или сложно. Очень немногие из этого, похоже, получают выгоду от "автоматизации".

В связи с документацией мне не нужно запоминать команды для этого.

Большинство программистов предпочитают вручную запускать стили, тесты и т.д.

Да.

генерация документации, задача docs вызывает сфинкс с соответствующими аргументами

Это одна строка кода. Автоматизация не очень помогает. sphinx-build -b html source build/html. Это a script. Написано на Python.

Мы делаем это редко. Несколько раз в неделю. После "значительных" изменений.

running stylechecks (Pylint, Pyflakes и pep8-cmdtool). проверяет вызовы pep8 и pillint commandlinetools

Мы этого не делаем. Мы используем модульное тестирование вместо pylint. Вы можете автоматизировать этот трехэтапный процесс.

Но я вижу, как SCons или make могут помочь кому-то здесь.

Тесты

Здесь может быть место для "автоматизации". Это две строки: модульные тесты не-Django (python test/main.py) и тесты Django. (manage.py test). Для запуска обеих линий может применяться автоматизация.

Мы делаем это десятки раз в день. Мы никогда не знали, что нам нужна "автоматизация".

dependecies настраивает virtualenv и устанавливает зависимости

Сделано так редко, что простой список шагов - это все, что нам когда-либо понадобилось. Мы очень тщательно отслеживаем наши зависимости, поэтому никогда не бывает сюрпризов.

Мы этого не делаем.

тестовая задача зависит от зависимостей, позволяет virtualenv, запускает селен-сервер для тестов интеграции и вызывает nosetest

start server & run nosetest как двухступенчатая "автоматизация" имеет смысл. Это избавит вас от ввода двух команд оболочки для выполнения обоих шагов.

задача coffeescript компилирует все кофейные скрипты в миниатюрный javascript

Это очень редкое явление для нас. Я полагаю, что это хороший пример того, что нужно автоматизировать. Может быть полезно автоматизировать однострочный script.

Я могу видеть, как SCons или make могут помочь кому-то здесь.

задача сервера задач зависит от зависимостей и coffeescript

Кроме. Зависимости меняются настолько редко, что это кажется излишним. Я предположил, что это может быть хорошей идеей, что вы вообще не отслеживаете зависимости.

задача развертывания зависит от проверки и тестирования и развертывания проекта.

Это а svn co и python setup.py install на сервере, а затем куча клиентских копий из области подрывной деятельности в область клиента /www. Это a script. Написано в Python.

Это не общий вид или что-то вроде SCons. У него есть только один актер (системный администратор) и один случай использования. Мы никогда не будем смешивать развертывание с другими задачами разработки, контроля качества или тестирования.

Ответ 2

Setuptools может автоматизировать много вещей, а для вещей, которые не встроены, легко расширяется.

  • Чтобы запустить unittests, вы можете использовать команду setup.py test после добавления аргумента test_suite к вызову setup(). (документация)
  • Зависимости (даже если они недоступны в PyPI) могут быть обработаны путем добавления аргумента install_requires/extras_require/dependency_links к вызову setup(). (документация)
  • Чтобы создать пакет .deb, вы можете использовать модуль stdeb.
  • Для всего остального вы можете добавить пользовательские команды setup.py.

Но я согласен с S.Lott, большинство задач, которые вы хотели бы автоматизировать (за исключением обработки зависимостей, может быть, это единственная, которую я нахожу очень полезной) - это задачи, которые вы не запускаете каждый день, поэтому не было бы будь то реальное повышение производительности путем автоматизации их.

Ответ 3

На самом деле автоматизация полезна и для разработчиков Python!

Вызов, вероятно, является самым близким инструментом для того, что вы имеете в виду, для автоматизации обычных повторяющихся задач Python: https://github.com/pyinvoke/invoke

С помощью invoke вы можете создать файл tasks.py, подобный этому (заимствованный из invoke docs)

from invoke import run, task

@task
def clean(docs=False, bytecode=False, extra=''):
    patterns = ['build']
    if docs:
        patterns.append('docs/_build')
    if bytecode:
        patterns.append('**/*.pyc')
    if extra:
        patterns.append(extra)
    for pattern in patterns:
        run("rm -rf %s" % pattern)

@task
def build(docs=False):
    run("python setup.py build")
    if docs:
        run("sphinx-build docs docs/_build")

Затем вы можете запускать задачи в командной строке, например:

$ invoke clean
$ invoke build --docs

Другой вариант - просто использовать Makefile. Например, проект Makefile проекта Python может выглядеть следующим образом:

docs:
    $(MAKE) -C docs clean
    $(MAKE) -C docs html
    open docs/_build/html/index.html

release: clean
    python setup.py sdist upload

sdist: clean
    python setup.py sdist
    ls -l dist

Ответ 4

В Python существует несколько вариантов автоматизации. Я не думаю, что есть культура против автоматизации, есть только один доминирующий способ сделать это. Общий знаменатель distutils.

Тот, который закрыт для вашего описания, buildout. Это в основном используется в мире Zope/Plone.

Я сам использую комбинацию из следующего: Distribute, pip и Fabric. В основном я использую Django, у которого есть команды manage.py для автоматизации.

Он также активно работает в Python 3.3

Ответ 5

Любой достойный тестовый инструмент имеет способ запускать весь пакет в одной команде, и ничто не мешает вам использовать rake, make или что-то еще. Действительно,

Существует мало оснований придумывать новый способ делать вещи, когда существующие методы работают отлично - зачем заново изобретать что-то только потому, что вы его не изобретали? (НИЗ).

Ответ 6

Оригинальный PEP, где он был поднят, можно найти здесь. Distutils стал стандартным методом для распространения и установки модулей Python.

Почему? Просто случается, что python - замечательный язык для выполнения установки модулей Python с.

Ответ 7

Вот несколько примеров использования make файла с python:

https://blog.horejsek.com/makefile-with-python/

https://krzysztofzuraw.com/blog/2016/makefiles-in-python-projects.html

Я думаю, что большинство людей не знают, что такое "makefile for python". Это может быть полезно, но "соотношение сексуальности" слишком мало для быстрого распространения (только мой PPOV).

Ответ 8

Динамическим языкам не нужно ничего, как make, если у них нет некоторых зависимостей интерфейса между модулями. Для этого Python должен будет получать макросы. Вам нужно make в C, чтобы выполнить инкрементную перестройку, когда изменяются интерфейсы, потому что изменения в таких вещах, как сигнатуры функций или структуры, означают, что ранее скомпилированный двоичный код больше не действителен.

Обратите внимание, что зависимости используются только для минимальной перекомпиляции программ на C. Когда вы перестраиваете программу C с типичным Makefile, привязка выполняется полностью. Все файлы .o, только что перекомпилированные или старые из ранней сборки, загружаются в память и превращаются в изображение.

В динамических языках построение программы более похоже на шаг связывания программ на C, чем на этапе компиляции.

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

Единственное, что выделяется make, и почему оно используется, - это инкрементные сборки с большими многослойными зависимостями. Даже для скомпилированных языков, таких как C, мы бы не использовали make, если бы нас не интересовали инкрементные перестройки. То есть, если программа была перестроена с нуля каждый раз, когда были сделаны изменения, сценарии построения скриптов могли бы создать изображение.

В проекте C make используется для различных задач автоматизации, поскольку он уже используется для создания программы. Makefile просто "выращивает волосы": он накапливает различные специальные цели которые выполняют различные легкие обязанности. Это происходит потому, что Makefile обрабатывает самые сложные, детальные попытки построения программы, постепенно и с нуля. Он создает своего рода "концентратор" для организации других автоматизаций. Эти цели не используют то, что делает; они легко могут быть оболочечными скриптами вне Makefile. Большинство из этих действий не вписываются в парадигму обновления цели на основе ее отсутствия или предпосылки являются более новыми. Многие из них выполняют действие безоговорочно, например: дважды обновляют фальшивую цель, и эффект происходит дважды. (Правило истинного make ничего не сделает во второй раз, если первая попытка удастся обновить его цель).

Одна из технических причин, по которой a Makefile заканчивается как центр автоматизации в некоторых проектах C, состоит в том, что система конфигурации сборки готовит некоторые важные переменные, а те, которые находятся в синтаксисе make, появляются как назначения в некотором make include файле. Конечно, когда вам нужно что-то автоматизировать, скриптология нуждается в содержимом этих переменных, и поэтому вы размещаете ее там, где она имеет к ним доступ: в Makefile в качестве новой цели.

Если эта практика должна произойти в ситуации, когда make никогда не использовался для создания инкрементных построений в дереве объектных файлов, это было бы "анти-шаблон". Либо кодеры-питоны инстинктивно избегают анти-шаблона, либо им просто не приходит в голову, что вместо того, чтобы писать пять простых сценариев для выполнения пяти задач автоматизации, они могут создать Makefile с пятью фиктивными целями и иметь дополнительное удовольствие с особенностями, такими как каждая строка рецепта make выполняется в новом экземпляре оболочки.

Ответ 9

Утилита make - это инструмент оптимизации, который сокращает время, затрачиваемое на создание программного образа. Сокращение времени достигается, когда все промежуточные материалы из предыдущей сборки все еще доступны, и только небольшие изменения были внесены на входы (такие как исходный код). В этой ситуации make может выполнить "инкрементную сборку": перестроить только подмножество промежуточных элементов, на которые влияет изменение на входы.

Когда выполняется полная сборка, все, что make эффективно, - это выполнение набора шагов сценариев. Эти же шаги можно было просто положить в плоский сценарий. Опция -n make действительно выведет эти шаги, что сделает это возможным.

Makefile не является "автоматизацией"; это "автоматизация с целью оптимизации инкрементных перестроек". Все, что написано с помощью любого скриптового инструмента, - это автоматизация.

Итак, почему проект Python избегал таких инструментов, как make? Вероятно, потому что проекты Python не борются с длительными сроками сборки, которые они хотят оптимизировать. И, кроме того, компиляция файла .py в .pyc не имеет такой же сети зависимостей, как .c от .o.

Исходный файл AC может #include сотни зависимых файлов; односимвольное изменение в любом из этих файлов может означать, что исходный файл должен быть перекомпилирован. Правильно написанный Makefile обнаружит, когда это или не так.

Большой проект C или C++ без инкрементной системы сборки означает, что разработчику приходится ждать часов, чтобы исполняемый образ выскочил для тестирования. Быстрые, инкрементные сборки необходимы.

В случае с Python, вероятно, все, о чем вам нужно беспокоиться, - это когда файл .py более новый, чем соответствующий .pyc, который можно обрабатывать с помощью простых сценариев: перебирать все файлы и перекомпилировать что-либо более новое, чем его байт-код. Кроме того, компиляция является необязательной, в первую очередь!

Поэтому причина, по которой проекты Python, как правило, не используют make заключается в том, что их потребность в инкрементной оптимизации перестройки низкая, и они используют другие инструменты для автоматизации; инструменты, более знакомые программистам Python, такие как Python.