- Оригинальный адрес:Current State of Python Packaging - 2019
- Оригинальный автор:Stefano Borini
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:EmilyQiRabbit
- Корректор:TokenJan,IT-rosalyn
Состояние упаковки Python (написано в 2019 г.)
В этом посте я постараюсь рассказать вам о тонкостях упаковки Python. Я провел последние два месяца, используя свое лучшее время каждую ночь, чтобы собрать как можно больше информации, текущих решений и выяснить, что осталось.
Неоднозначная терминология Python — первый источник путаницы. В контексте программирования слово «пакет» означает компонент, который можно установить (например, библиотеку). Но это не относится к python, где устанавливаемый компонент называется «дистрибутив». Однако на самом деле никто вообще не использует термин «дистрибутив» без необходимости (особенно в официальной документации и предложениях по улучшению Python). Между прочим, использование этого термина на самом деле очень плохой выбор, потому что слово «дистрибутив» обычно используется для описания бренда Linux.
Это предупреждение, которое вы должны иметь в виду, потому что упаковка python на самом деле не о python.Сумка, но об этомраспределение. Но я все еще называю это упаковкой.
Я не хочу тратить столько времени на чтение. Можете ли вы дать мне короткую версию? Как мне управлять пакетами Python в 2019 году?
Я предполагаю, что вы программист, который хочет начать разработку пакета Python, шаги следующие:
- первое использованиеPoetryСоздайте среду разработки и укажите прямые зависимости проекта, используя строгий режим. Это гарантирует, что ваши среды разработки и тестирования всегда могут быть воссозданы.
- Создайте файл pyproject.toml, затем используйте поэзию в качестве бэкенда для создания исходных и двоичных дистрибутивов.
- Следующим шагом является указание абстрактных зависимостей пакета. Обратите внимание, что вы должны указать самую низкую версию, которую вы можете определить для запуска пакета. Это гарантирует, что не будут созданы бесполезные версии, конфликтующие с другими пакетами.
Если вы действительно хотите использовать старый способ, требующий setuptools:
- Создайте файл setup.py, укажите в файле все абстрактные зависимости и укажите минимальную рабочую версию этих зависимостей в install_requires.
- Создайте
requirements.txt
файл, в котором указаны строгие, конкретные (то есть указана определенная версия), прямые зависимости. Далее вам нужно будет использовать этот файл для создания фактической рабочей среды. - использовать команду
python -m venv
Создайте виртуальную среду, активируйте среду и используйте ее в этой среде.pip install -rrequirements.txt
команда для установки зависимостей. Используйте эту среду для развития. - Если вам нужны зависимости для тестирования (что, конечно, очень возможно), то вам нужно создать
dev-requirements.txt
файл, а также установить для него зависимости. - Если вам нужно заморозить все конфигурации среды (это рекомендуемая практика), выполните
pip freeze >requirements-freeze.txt
А также использовать эту команду для создания окружения в будущем.
У меня много времени. Пожалуйста, помогите мне объяснить.
Сначала я коснусь текущих проблем, их действительно много.
Предположим, я хочу создать некий «проект» на питоне: это может быть отдельная программа, может быть библиотека. Разработка и использование этого проекта требует включения следующих «ролей»:
- Разработчики: человек или команда, ответственные за написание кода.
- CI: протестируйте автоматизированный процесс для этого проекта.
- Построить: автоматический или полуавтоматический процесс из нашего репозитория git, в который другие могут установить и использовать этот проект.
- конечный пользователь: Человек или команда, которые в конечном итоге будут использовать проект. Если проект представляет собой библиотеку, конечным пользователем могут быть другие разработчики, а если это приложение, то конечным пользователем может быть широкая общественность. Или, если проект представляет собой определенный вид сетевого сервиса, то конечный пользователь — микросервис облачных вычислений. Конечно, есть еще много возможностей, вы понимаете, о чем я, поэтому я не буду перечислять их одну за другой.
Наша цель — сделать так, чтобы все пользователи или устройства были довольны проектом, но у всех у них разные рабочие процессы и потребности, и иногда эти потребности пересекаются. Кроме того, проблемы возникают, когда проект изменяется, выпускается новая версия, старая версия устаревает или почти весь код зависит от другого кода для выполнения своей работы. В проекте должны быть зависимости, и со временем эти зависимости будут меняться, они могут быть нужны или нет, они могут работать на очень низком уровне, поэтому мы должны рассматривать их в разных операционных системах или даже в рамках одной операционной системы. Оба могут быть непереносимыми. Это уже очень сложно.
Что еще хуже, ваши прямые зависимости также имеют свой собственный набор зависимостей. Что, если ваш пакет напрямую зависит от A и B, а они оба зависят от C? Какую версию C следует установить? Если A хочет установить строгую версию 2 C, а B хочет установить строгую версию 1 C, возможно ли это сделать?
Чтобы до некоторой степени устранить эту путаницу, люди разработали способы упаковки кода, чтобы его можно было повторно использовать, установить, версионировать и получить некоторую описательную метаинформацию, такую как: «Уже установлено в 64-разрядной версии Windows, упаковано» или «только для macOS» или «для запуска требуется эта версия или выше».
Ну, теперь я знаю, в чем проблема. Итак, каково решение?
Первым шагом является определение набора объектов, которые могут доставлять конкретную версию программного обеспечения указанной публикации. Эта сущность может доставить то, что мы называемСумка(или дистрибутив на профессиональном языке Python). Доставить можно двумя способами:
- исходный код: упакуйте исходный код в файл zip или tar.gz, а затем скомпилируйте его пользователем.
- бинарный файл: вы компилируете код, а затем публикуете скомпилированный контент, пользователи могут использовать его напрямую без дополнительных действий.
Любой способ может быть полезен, и обычно рекомендуется предлагать оба варианта. Конечно, нужны инструменты, умеющие правильно делать упаковку, особенно для таких задач, как:
- Создайте поставляемый пакет (то есть вышеупомянутыйПостроить)
- Опубликуйте пакет где-нибудь, чтобы другие могли его получить
- Скачайте и установите пакет
- Обработка зависимостей. Что, если для запуска пакета А требуется пакет Б? Если пакету A нужен пакет B, зависит от того, как вы используете A? Пакет B требуется, если пакет A установлен только в Windows?
- Определите время выполнения. Как упоминалось ранее, обычно для запуска небольшой части программного обеспечения требуется множество зависимостей, и эти зависимости лучше всего изолировать от зависимостей другого программного обеспечения. Это должно быть верно, независимо от того, разрабатываете вы или работаете.
Можете быть более конкретными? Что я должен сделать, прежде чем писать код?
Конечно. Прежде чем писать код, вы обычно выполняете следующие шаги:
- Создайте среду Python, независимую от системного Python. Таким образом, вы можете разрабатывать несколько проектов одновременно. И если вы этого не сделаете, содержимое элемента А и содержимое элемента Б могут перепутаться.
- Если вы хотите указать зависимости проекта, имейте в виду, что это можно сделать двумя способами:абстрактный способ, на этом этапе вам нужно только указать, какие зависимости (например, numpy) необходимы в общих чертах, испецифический способ, то вы должны указать номер версии (например, numpy 1.1.0). Причина такого различия будет подробно объяснена позже. Если вы хотите создать рабочую среду разработки, вам необходимо указать зависимости.
- Теперь, когда вы сделали то, что нужно, можно приступать к разработке.
Нужно ли мне использовать какой-либо инструмент для этого?
Трудно сказать, потому что инструменты многочисленны и постоянно меняются. Один из вариантов заключается в том, что вы можете использовать встроенный в pythonvenvСоздайте отдельные «виртуальные среды» Python. затем используйтеpip(также встроенный инструмент Python) для установки зависимых пакетов. Вводить и устанавливать их по одному слишком сложно, поэтому люди обычно записывают определенные зависимости (жестко запрограммированные номера версий) в файл и говорят pip: «прочитайте этот файл и установите все пакеты, записанные в файле». Пип сделает то же самое. Этот файл известен как requirements.txt, который вы могли видеть в других проектах.
Хорошо, но что такое пипс?
pip — это программа, используемая для загрузки и установки пакетов. Если у этих пакетов также есть зависимости, то pip также установит эти подзависимости.
Как это делает пип?
Он найдет соответствующий пакет по имени и номеру версии на удаленном сервисе pypi, загрузит и установит его. Если пакет уже является бинарным, просто установите его. Если это исходный код, pip скомпилирует его, а затем установит. Но pip делает больше, потому что у самого пакета могут быть другие зависимости, поэтому он также подберет эти зависимости и установит их.
Почему вы говорите, что метод использования requirements.txt — это просто «вариант»?
Потому что этот подход может стать утомительным и сложным по мере расширения проекта. Для разных платформ вам необходимо вручную управлять версиями прямой зависимости. Например, в системе Windows вам нужно установить определенный пакет, а в Linux или других системах вам нужен другой пакет, в результате вам нужно поддерживать несколько файлов, таких как win-requirements.txt, linux-requirements.txt и т. д. . в то же время.
Вы также должны принять во внимание, что некоторые зависимости необходимы для запуска вашего программного обеспечения; другие используются только для запуска тестов, эти зависимости необходимы только для разработчиков или устройств CI, но не нужны для других людей, использующих ваше программное обеспечение. в настоящее время их нельзя использовать в качестве зависимостей проекта. Поэтому вам понадобится новый файл dev-requirements.txt.
Проблема в том, что в файле requirements.txt могут быть указаны только прямые зависимости, но в практических приложениях вы хотите настроить то, что вам нужно для создания среды.все зависимости. Почему вы хотите этого? Например, если вы устанавливаете прямую зависимость от A, которая, в свою очередь, зависит от версии 1.1 C. Но однажды C выпустил новую версию 1.2, и с тех пор при создании среды pip будет загружать потенциально уязвимую версию 1.2 C. То есть вдруг ваш тест проваливается, и вы не знаете почему.
Итак, вы хотите указать как зависимости, так и подзависимости этих зависимостей в файле requirements.txt. Но в этом случае вы не можете различить две зависимости в файле, поэтому, когда с зависимостью возникает проблема и вы хотите ее отладить, вам нужно выяснить, какая из них является подзависимостью в файле, и...
Теперь ты понимаешь. Это настоящий беспорядок, и вы не хотите иметь дело с таким беспорядком.
Одна из проблем, с которой вы столкнетесь в следующий раз, заключается в том, что pip может решить, какую версию использовать более примитивным способом, который может зайти в тупик, представив вам неработающую среду или ошибку. Помните этот пример: пакеты A и B зависят от C. Следовательно, вам нужен более сложный процесс.В этом процессе, в основном, pip используется только для загрузки пакетов с определенной версией, а право решать, какую версию устанавливать, дается другим программам, которые должны рассматриваться глобально. принимать более обоснованные решения по версиям.
Например? Пожалуйста, приведите пример.
pipenv является примером. Он объединяет venv, pip и некоторые другие черные технологии, вам нужно только дать список прямых зависимостей, и он сделает все возможное, чтобы решить за вас упомянутую выше путаницу и предоставить вам рабочую среду. Поэзия — еще один пример. Оба часто обсуждаются, и есть некоторые споры как по человеческим, так и по политическим причинам. Но большинство людей предпочитают Поэзию.
Некоторые компании, такие как Continuum и Enthought, имеют собственное управление версиями (например, conda и edm), что обычно позволяет избежать дополнительной сложности зависимостей версий в зависимости от платформы. Мы не будем обсуждать это здесь. Я просто хочу сказать, что если вы хотите использовать множество уже скомпилированных зависимостей или (эти зависимости) зависят от скомпилированных библиотек, что часто встречается, например, в сценариях научных вычислений, то вам лучше всего использовать их систему для управления вашей средой, и это избавит вас от многих проблем. Потому что это то, в чем они хороши.
Так что же лучше, пипенв или Поэзия?
Как я только что сказал, люди предпочитают Поэзию. Я пробовал и то, и другое, и Поэзия для меня лучше, поскольку обеспечивает более совместимое и лучшее решение.
Ну, по крайней мере, мы собираемся использовать Poetry, который настраивает для нас среду, чтобы я мог установить зависимости и начать программировать.
Верно. Но я еще не говорил о строительстве. То есть, когда у вас есть код, как вы создаете релиз?
Хм, да, так вот где появляются setup.py, setuptools и distutils?
Можно сказать, но не точно. Первоначально, когда вы хотели создать исходный или двоичный дистрибутив, вам нужно было использовать модуль стандартной библиотеки под названием distutils. Это можно сделать с помощью скрипта Python setup.py, который волшебным образом создает проекты, которые вы можете отправлять другим. Сценарий может называться как угодно, но setup.py является стандартным соглашением об именах, и другие инструменты (например, широко используемый pip) будут искать только файлы с этим именем. И если pip не найдет версию для сборки, от которой он должен зависеть, он загрузит исходный код и соберет его, короче говоря, просто запустит setup.py, и мы можем только надеяться, что результаты будут хорошими.
Однако distutils не очень хорош, поэтому некоторые люди нашли альтернативы, которые могут делать гораздо больше, чем distutils. Несмотря на проблемы, путаницу и долгий путь разработки, setuptools лучше, и каждый может его использовать. Setuptools по-прежнему использует файлы setup.py в наши дни, создавая иллюзию, что они не изменились и процесс создания среды остался прежним.
Почему мы говорим, что можем только молиться, чтобы исход был хорошим?
Потому что pip не гарантирует, что пакет, который он создаст, запустив setup.py, действительно будет работать. Это просто скрипт Python, который может иметь свои собственные зависимости, и вы не можете изменить его зависимости или отследить их, когда что-то пойдет не так. Это вопрос курицы или яйца.
Но есть опция setup_requires в setuptools.setup() ах
Этот метод является ямой, и вы в принципе не можете использовать его для решения каких-либо проблем. Это также вопрос курицы и яйца. PEP 518 подробно обсуждает это, и окончательный вывод - это шлак. Прекратите использовать его.
Так действительно ли setuptools и setup.py необязательны для сборки релизов? ?
Да в прошлом. Но не обязательно сейчас, но, возможно, это все еще иногда работает. Это зависит от того, что вы хотите опубликовать. В настоящее время никто не хочет, чтобы setuptools был единственным способом решать, как публиковать пакеты. Корень проблемы немного глубже, и есть некоторые технические проблемы, но если вам интересно, взгляните на PEP 518. Самая важная часть, о которой я упоминал выше: если pip хочет создать зависимости, которые он загружает, как он определяет, какую версию загрузить и использовать для выполнения сценария установки? Да, он может предположить, что вам нужно полагаться на setuptools, но это всего лишь предположение. И вам, вероятно, не нужны инструменты настройки в вашей среде, так как же pip принимает решения? В большинстве случаев, почему вы должны использовать setuptools вместо других инструментов?
В большинстве случаев это решает, что любой, кто хочет написать свой собственный инструмент управления пакетами, должен иметь возможность это сделать, поэтому вам просто нужен другой инструмент конфигурации, чтобы определить, какую систему пакетов использовать и какие зависимости вам нужны для сборки вашего проекта.
Использовать pyproject.toml?
правильный. Точнее, подраздел, в котором может быть определен «бэкенд», используемый для сборки пакета. Если вы хотите использовать другой бэкэнд сборки, pip может это сделать. И если вы этого не хотите, то pip предположит, что вы используете инструменты distutils или setuptools, поэтому он вернется к поиску файла setup.py и выполнит его, будем надеяться, что сборка пройдет успешно.
Исчезнет ли со временем setup.py?setuptools(перед ним distutils) использует setup.py для описания того, как создать сборку. Другие инструменты могут использовать другие методы. Возможно, их сделают, добавив что-то в pyproject.toml.
В то же время вы можете, наконец, указать зависимости в pyproject.toml для выполнения сборки, что снимает дилемму курицы и яйца, упомянутую ранее.
Почему стоит выбрать файлы формата toml? Я никогда даже не слышал об этом. Почему бы не использовать JSON, INI или YAML?
Стандартный JSON не позволяет писать комментарии. Но людям действительно нужно полагаться на аннотации для передачи информации о проекте. Вы можете нарушать правила, но это уже не JSON. Кроме того, JSON на самом деле является своего рода античеловеческим, и писать его не очень приятно.
INI на самом деле вообще не является стандартным способом записи и имеет много функциональных ограничений.
YAML может быть потенциальной угрозой безопасности вашего проекта, это как вирус.
В этом случае понятно выбрать томл. Однако разве они не могут включить setuptools в стандартную библиотеку?
Возможно, но проблема в том, что цикл выпуска стандартной библиотеки действительно очень длинный. Distutils очень медленно обновлялся, что и послужило толчком к принятию и распространению setuptools. Но также не гарантируется, что setuptools удовлетворит все потребности. Некоторые пакеты могут иметь особые требования.
Итак, я правильно понял: мне нужно использовать Poetry для создания рабочей среды. Используйте setup.py и setuptools или pyproject.toml для сборки пакета.
Если вы хотите использовать setuptools, вам нужен setup.py, но проблема, с которой вы можете столкнуться, заключается в том, что другим пользователям также необходимо установить setuptools для сборки вашего пакета.
Итак, какие еще инструменты я могу использовать, кроме setuptools?
Вы можете использовать флит или поэзию.
Нужно ли Poetry устанавливать зависимости?
требуется, но его также можно использовать для сборки. пипенв не будет работать.
Кстати, если я использую setup.py, зачем мне указывать зависимости? Какое отношение загруженный мной setup.py имеет к pipenv, Poetry и requirements.txt?
Это абстрактные зависимости, которые необходимы для запуска пакетов и необходимы pip при принятии решения о том, какие версии загружать и устанавливать. Здесь вы должны ослабить ограничение версии зависимостей, потому что если вы не... помните пример, который я приводил ранее, где A и B оба зависят от C? Что, если A спросит: «Я хочу версию 1.2.1 C», а B спросит: «Я хочу версию 1.2.2 C»?
Когда дело доходит до создания исходного дистрибутива загружаемых ресурсов, у pip нет другого выбора. pip не получает требования, которые вы пишете в файле requirements.txt. Он просто запускает setup.py, который заставляет pip использовать setuptools, который затем снова вызывает pip для преобразования абстрактных зависимостей в конкретные устанавливаемые зависимости.
А как же яйца, простая установка, каталоги .egg-info, дистрибутив, virtualenv (это не то же самое, что venv), zc.buildout, bento и эти инструменты?
Просто игнорируйте их. Это либо устаревшие инструменты, либо ответвления других инструментов, либо бесплодные попытки.
Что насчет колес?
Помните, что я сказал ранее? pip должен знать, что загружать из pypi, чтобы он мог загрузить правильную версию и ОС. Wheel — это файл, который содержит ресурсы для загрузки и имеет некоторые специальные указанные поля, которые pip будет использовать для принятия решений при установке зависимостей и подзависимостей.
Имена файлов Wheels включают теги в качестве метаданных (например, pep-0425), поэтому при компиляции определенных ресурсов (например, CPython) Wheels может знать скомпилированную версию, ABI и т. д. Существует стандартный слой для тегов в именах файлов, а определенные слова в метаданных имеют определенные значения.
Не забудьте построить колеса для бинарных дистрибутивов.
Так что насчет .pyz ?
Просто игнорируйте это, строго говоря, это не имеет ничего общего с упаковкой. Но это может быть полезно и по-другому, если вам нужны подробности, см. PEP-441.
Так что насчет pyinstaller?
Pyinstaller — это совсем другая тема. Видите ли, проблема со словом «упаковка» в том, что оно не ясно формулирует, что оно на самом деле означает. До сих пор мы обсуждали:
- Создайте среду, в которой можно разрабатывать библиотеки
- Создавайте проекты, которые вы создаете, в формате, который также могут использовать другие
Но они обычно применяются к библиотекам. Когда дело доходит до публикации приложений, это другая история. Когда вы упаковываете библиотеку, вы знаете, что она станет частью более крупного проекта. И когда вы упаковываете приложение, оно и естьбольшая часть проекта.
Кроме того, если вы хотите предложить свое приложение людям, вам следует указать платформу вашего приложения. Например, вы хотите снабдить исполняемый файл значком, но они должны быть разными на платформах Windows, macOS и Linux.
PyInstaller — это инструмент, который можно использовать, когда вы хотите создать автономное исполняемое приложение. Он создает для вас окончательное приложение на рабочем столе пользователя. Упаковка — это управление сетью зависимостей, библиотек и инструментов, необходимых для создания приложения, которое вы можете использовать или не использовать pyinstaller.
Обратите внимание, однако, что использование этого метода предполагает, что ваше приложение относительно простое и автономное. Если во время установки приложению необходимо выполнять более сложные действия, например создание пароля для входа в Windows, вам потребуется более подходящий и более зрелый установщик, например NSIS. Я не знаю, есть ли в мире Python такая вещь, как NSIS. Но в любом случае NSIS понятия не имеет, что вы развернули. Конечно, вы можете использовать pyinstaller для создания исполняемого приложения, затем использовать NSIS для его развертывания, а также выполнять дополнительные требования, такие как изменения реестра или изменения файловой системы, чтобы приложение работало.
Хорошо, но как мне установить те проекты, в которых у меня уже есть пакет ресурсов? с помощью python setup.py?
неправильный. использоватьpip install .
, потому что эта команда гарантирует, что вы сможете удалить приложение позже, и в целом это лучше. Затем pip проверит pyproject.toml и запустит сборку в фоновом режиме. И если pip не находит файл pyproject.toml, он просто возвращается к старому способу запуска setup.py, чтобы попытаться построить.
Мне очень нравится эта статья, но у меня все еще есть некоторые вопросы, которые я не понимаю.
ты можешь самоткрыть вопрос. Если я знаю ответ, то сразу отвечу. Если я не знаю, я проведу небольшое исследование и вернусь к вам как можно скорее. Моя цель в этой статье — заставить людей, наконец,пониматьупаковка питона.
Есть ли какие-либо справочные ссылки, которые позволили бы мне узнать больше?
Конечно, см.:
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллекти другие поля, если вы хотите видеть больше качественных переводов, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.