Python setuptools что это
distutils, setuptools, pip — Python: Настройка окружения
На прошлом уроке мы познакомились с пакетами и индексами, давайте же узнаем, как устанавливать пакеты из индекса! Для установки, обновления и удаления пакетов часто применяются так называемые пакетные менеджеры (или менеджеры пакетов). Один такой мы рассмотрим, но сначала немного поговорим о фундаменте системы пакетирования Python.
distutils и setuptools
В поставку Python входит distutils, пакет, отвечающий за создание дистрибутивов — архивов кода, которые могут быть распакованы в целевом окружении и установлены так, чтобы интерпретатор Python «увидел» распакованный код. При создании пакета программист создаёт в корневой директории будущего пакета файл setup.py в котором импортирует из модуля distutils функцию setup и вызывает её. Таким образом каждый пакет содержит в себе программу для управления собой!
Подробнее о том, как работает distutils, можно почитать в официальной документации к пакету, а мы сразу двинемся дальше. Дело в том, что пакет distutils появился довольно давно и сейчас сам по себе не очень удобен в использовании. Гораздо чаще используется надстройка над distutils, пакет setuptools.
Пакеты, собранные с помощью setuptools, уже умеют предоставлять metadata: описание, версию, и самое главное — собственные зависимости! Пакеты, которые не зависят ни от чего, кроме самого Python, настолько редки, что без setuptools — можно сказать, «жизни нет». Про этот пакет стоит знать и со временем нужно будет научиться его использовать (опять же, с помощью документации), но в рамках этого курса мы будем рассматривать более простой инструмент для создания пакетов и загрузки их в индекс — poetry, с которым мы познакомимся попозже.
Полезные инструменты Python
Друзья, добрый вечер! У нас отличные новости, открыт набор в новую группу по курсу «Разработчик Python». Группа стартует уже в начале июля, а прямо сейчас, по устоявшейся традиции, мы делимся полезным переводом подготовленным для студентов данного курса.
Когда вы только начинаете учить Python, кто-то объясняет вам, что вы можете добавить свою папку с исходниками в переменную среды PYTHONPATH и тогда ваш код можно будет импортировать из других директорий. Очень часто объясняющий забывает сказать, что в большинстве случаев – это плохая идея. Некоторые люди узнают это в интернете, другие просто понимают на собственном опыте. Но слишком большое количество людей (особенно неопытные программисты), думают, что других альтернатив быть не может.
Эта статья в основном для них, поскольку даже если вы знаете, что существует альтернатива, не всегда бывает просто принять ее и начать использовать. Инструменты Python сбивают с толку, поскольку они представляют из себя большое количество программного обеспечения, построенного одно на основе другого, с большим количеством пересечений и проблем, возникающих из-за этого. Непросто понять, как эти инструменты правильно использовать в своем проекте.
По этой причине я решил написать эту статью и рассмотреть в ней самые популярные инструменты, разобраться когда и где они используются и какие задачи решают. Я попробую объяснить на пальцах как стоит применять каждый из этих инструментов. Если инструмент есть в этом списке, значит, вам, как питонисту, нужно хотя бы знать о его существовании. Я буду рассказывать лишь о тех инструментах, которые могут быть применены для любого проекта или рабочего процесса, и вам следует помнить о них, когда вы начинаете новый проект. Однако это не значит, что вам следует использовать все представленные инструменты в каждом своем проекте. Излишне перегружать проект инструментами, в некоторых случаях это может усложнить его поддержку.
Базовые инструменты
Setuptools
Setuptools – стандартный способ создавать пакеты в Python. Он работает где угодно и хорошо справляется со своей задачей.
Для чего: создание egg, zip или wheel файлов из исходников, определение метаданных для вашего проекта, совместная структурированная и стандартизированная работа над кодом.
Когда используется: Всегда, когда вы пишете код, который должен запускаться на чьей-либо другой машине.
Альтернативы: Poetry, Flit
virtualenv
Virtualenv – менеджер виртуальной среды. Такие изолированные среды представляют собой автономно установленный python с определенным набором предустановленных пакетов. Использование virtualenv означает, что вам не нужно устанавливать пакеты в python системы по умолчанию.
Для чего: разделение зависимостей, поддержка различных версий python одной системой, легкое перемещение зависимостей.
Когда используется: Вам нужно написать код, а для этого нужна версия python отличающаяся от вашей системной версии python по умолчанию.
Альтернативы: Docker или нечто подобное.
Pip – наиболее распространённый менеджер пакетов в python. Он позволяет устанавливать локальные или удаленные пакеты в вашу виртуальную среду или Python системы.
Для чего: установка и удаление пакетов, отслеживание версий пакетов, которые вы используете.
Когда используется: Всегда.
Альтернативы: Poetry, Conda
Создание пакетов и их распространение
Для более тщательного ознакомления у python.org есть отдельная страница: packaging.python.org
distutils
distutils – это предшественник setuptools. Последний активно использует функционал distutils, поэтому нередко приходится взаимодействовать именно с этим инструментом. Distutils – это не совсем тот инструмент, который вы должны иметь в своем арсенале, но вы должны знать, каким образом он вписывается в общую картину.
Pypi или Python Package Index — это большой репозиторий, в котором собраны все ваши самые любимые модули Python. Например, тот же самый pip берет билды пакетов именно оттуда.
Для чего: Для публикации вашего кода.
Когда используется: Когда существует пакет, который вы хотите показать сообществу.
Pypiserver
Pypiserver – это одна из реализаций Package Index API, используемая Pypi. Вы можете создать собственный репозиторий, например, для всей вашей компании и публиковать пакеты не делая публичных релизов.
Для чего: Создание собственных репозиториев внутри организации.
Когда используется: Когда вашему коду не нужна публичная огласка, но над ним нужен полный контроль.
Альтернативы: Warehouse (используется Pypi), djangopypi
Poetry
Poetry является альтернативной системой работы с пакетами, которая заменяет setuptools, pip и некоторые другие инструменты, построенные на их основе. Это попытка полностью пересмотреть то, как работает система пакетов в Python. На настоящее время poetry имеет множество положительных отзывов, но не является самым распространённым инструментом.
Для чего: обработка и распространение пакетов, управление зависимостями, предотвращение проблем с разрешением зависимостей.
Когда используется: Когда у вас намечается новый проект и вы не боитесь использовать узкоспециализированные инструменты.
Альтернативы: Pipenv
Pipenv
Pipenv, подобно Poetry, является инструментом для структурирования зависимостей и конфигурации проектов на Python более вменяемым способом. С помощью Pipfile он управляет зависимостями вашего проекта и обеспечивает согласованность и простоту использования.
Для чего: обработка и распространение пакетов, управление зависимостями.
Когда используется: вам нужен инструмент вроде Poetry, который вызовет меньше вопросов.
Альтернативы: Poetry.
Документация
Sphinx
Sphinx – инструмент для создания документации. Изначально он был создан для обработки документации Python, но стал инструментом общего пользования. Он является наиболее распространенным вариантом для проектов на Python.
Для чего: создание PDF-или HTML-документов с помощью языка разметки из reStructuredText источников.
Когда используется: Когда вашему проекту, API или коду требуется внешняя документация.
Альтернативы: Docutils, Doxygen
autodoc
autodoc — это фундаментальное расширение для Sphinx, которое позволяет создавать reStructuredText файлы из исходного кода на Python с подписями для каждого класса, функции, модуля и так далее.
Для чего: документирование вашего кода или API.
Когда используется: Фактически, каждый раз, когда вы используете Sphinx.
Альтернативы: autosummary
Тестирование
py.test
py.test – по моему мнению, является лучшим пакетом для тестирования на Python. У него множество функций, хотя не все из них раскрыты должным образом, поэтому некоторое время займет поиск всех возможностей, которые предоставляет py.test.
Для чего: тестирование вашего кода.
Когда используется: Всегда, когда вам лень тестировать вручную.
Альтернативы: unittest, nose
Hypothesis
Hypothesis – это инструмент для тестирования отдельных свойств. Короче говоря, он генерирует случайные сценарии тестирования в соответствии с вашими спецификациями, пока не найдет сценарий, при котором тест не проходит успешно. Потратьте некоторое время на изучение принципов, прежде чем начинать использовать этот инструмент.
Для чего: тестирование кода, в особенности обработки данных.
Когда используется: Когда нужно протестировать нетривиальную логику широким спектром входных значений (числа, строки, структурированные данные).
tox представляет из себя менеджер виртуальной среды для тестирования. Это значит, что вы сможете настроить его для выполнения тестов в чистых, настраиваемых виртуальных средах, чтобы гарантировать, что ваш код сможет работать в различных условиях.
Для чего: для кода, который должен запускаться в различных условиях и средах. Также полезен для CI.
Когда используется: Когда нужно, чтобы ваш код поддерживался различными версиями Python, запускался в различных средах и на разных операционных системах.
Альтернативы: bash scrips, CI pipelines
Другие инструменты
pyenv
pyenv – менеджер версий python. Он направлен на упрощение локального рабочего процесса разработчиков при работе с несколькими версиями.
Для чего: запуск различных проектов разными версиями Python.
Когда используется: Вам нужно работать с глобальными версиями Python и у вас их много.
Альтернативы: manual management, virtualenv, Poetry, Pipenv
PyScaffold
PyScaffold — это инструмент для инициализации структуры проекта стандартизированным способом и предоставления некоторых из перечисленных выше инструментов без необходимости настраивать их вручную. Очень гибкий.
Для чего: для загрузки проектов, работы с несколькими проектами с одинаковым инструментарием и структурой.
Когда используется: всегда (если вы знакомы с этим инструментом, но не пытайтесь впервые его использовать, когда вы спешите)
Альтернативы: python-project-template, Cookiecutter
flake8
flake8 – один из самых популярных линтеров для Python. Он запускает различные сценарии для проверки соответствия вашего кода требованиям руководства по стилю Python (PEP-8).
Для чего: проверка вашего проекта на хороший стиль написания кода.
Когда используется: каждый раз, когда ваш проект должен быть прочитан кем-то или вами же.
Альтернативы: pylint
Black
Black автоматически форматирует код. Это значит, что вместо того, чтобы просто проверить ваш код на соответствие стандартам, Black самостоятельно изменит его, чтобы он им соответствовал.
Для чего: автоматическое форматирование кода.
Когда используется: Когда у вас нет проблем с тем, чтобы отказаться от ручного управления вашим кодом.
Альтернативы: autopep8, yapf
Установка python setuptools easy_install и работа с ним
setuptools дополнение для python на данный момент до версии 2.7 позволяющее автоматически загружать и устанавливать пакеты одной строчкой из коммандной строки или консоли для никс систем.
В состав пакета setuptools входит модуль easy_install который позволяет выполнять такие действия как автоматическая загрузка пакетов и их установка, обновление, откат до предыдущей версии.
Для использования easy_install необходимо скачать setuptools и установить, так как автоматика еще не установлена, то все делаем вручную, точнее вручную скачиваем инсталятор ставящий пакет (рассматриваем установку под виндовс)
Обращаю внимание, что setuptools как и easy_install.py доступно на текущий только для python до версии 2.7
Для загрузки переходим на страницу http://pypi.python.org/pypi/setuptools
Пролистав в самый низ странички видим таблицу с доступными пакетами для загрузки, если у нас стоит виндовс и питон 2.7, то выбираем нижний пакет с названием setuptools-0.6c11.win32-py2.7.exe
Загружаем, запускаем инсталятор, производим установку setooptools, после установки переходим в каталог в который установлен питон:
/Python27/Scripts/ и видим там easy_install.exe который запускается из коммандной строки
Теперь чтобы установить пакет достаточно набрать в коммандной строке
easy_install pyside
и будет установлена бесплатная библиотека для работы с графическим интерфейсом QT4
Дополнительные источники информации:
1) Примеры работы с Easy Install
Packaging and distributing projects¶
This section covers the basics of how to configure, package and distribute your own Python projects. It assumes that you are already familiar with the contents of the Installing Packages page.
The section does not aim to cover best practices for Python project development as a whole. For example, it does not provide guidance or tool recommendations for version control, documentation, or testing.
For more reference material, see Building and Distributing Packages in the setuptools docs, but note that some advisory content there may be outdated. In the event of conflicts, prefer the advice in the Python Packaging User Guide.
Requirements for packaging and distributing¶
You’ll need this to upload your project distributions to PyPI (see below ).
Configuring your project¶
Initial files¶
setup.py¶
The most important file is setup.py which exists at the root of your project directory. For an example, see the setup.py in the PyPA sample project.
setup.py serves two primary functions:
setup.cfg¶
setup.cfg is an ini file that contains option defaults for setup.py commands. For an example, see the setup.cfg in the PyPA sample project.
README.rst / README.md¶
All projects should contain a readme file that covers the goal of the project. The most common format is reStructuredText with an “rst” extension, although this is not a requirement; multiple variants of Markdown are supported as well (look at setup() ’s long_description_content_type argument).
MANIFEST.in¶
A MANIFEST.in is needed when you need to package additional files that are not automatically included in a source distribution. For details on writing a MANIFEST.in file, including a list of what’s included by default, see “ Including files in source distributions with MANIFEST.in ”.
MANIFEST.in does not affect binary distributions such as wheels.
LICENSE.txt¶
Every package should include a license file detailing the terms of distribution. In many jurisdictions, packages without an explicit license can not be legally used or distributed by anyone other than the copyright holder. If you’re unsure which license to choose, you can use resources such as GitHub’s Choose a License or consult a lawyer.
For an example, see the LICENSE.txt from the PyPA sample project.
Although it’s not required, the most common practice is to include your Python modules and packages under a single top-level package that has the same name as your project, or something very close.
For an example, see the sample package that’s included in the PyPA sample project.
setup() args¶
As mentioned above, the primary feature of setup.py is that it contains a global setup() function. The keyword arguments to this function are how specific details of your project are defined.
The most relevant arguments are explained below. Most of the snippets given are taken from the setup.py contained in the PyPA sample project.
Start & end with an ASCII letter or digit.
version ¶
This is the current version of your project, allowing your users to determine whether or not they have the latest version, and to indicate which specific versions they’ve tested their own software against.
Versions are displayed on PyPI for each release if you publish your project.
See Choosing a versioning scheme for more information on ways to use versions to convey compatibility information to your users.
If the project code itself needs run-time access to the version, the simplest way is to keep the version in both setup.py and your code. If you’d rather not duplicate the value, there are a few ways to manage this. See the “ Single-sourcing the package version ” Advanced Topics section.
description ¶
Give a short and long description for your project.
description is also displayed in lists of projects. For example, it’s visible in the search results pages such as https://pypi.org/search/?q=jupyter, the front-page lists of trending projects and new releases, and the list of projects you maintain within your account profile (such as https://pypi.org/user/jaraco/).
Give a homepage URL for your project.
author ¶
Provide details about the author.
license ¶
The license argument doesn’t have to indicate the license under which your package is being released, although you may optionally do so if you want. If you’re using a standard, well-known license, then your main indication can and should be via the classifiers argument. Classifiers exist for all major open-source licenses.
The license argument is more typically used to indicate differences from well-known licenses, or to include your own, unique license. As a general rule, it’s a good idea to use a standard, well-known license, both to avoid confusion and because some organizations avoid software whose license is unapproved.
classifiers ¶
Provide a list of classifiers that categorize your project. For a full listing, see https://pypi.org/classifiers/.
Although the list of classifiers is often used to declare what Python versions a project supports, this information is only used for searching & browsing projects on PyPI, not for installing projects. To actually restrict what Python versions a project can be installed on, use the python_requires argument.
keywords ¶
List keywords that describe your project.
project_urls ¶
List additional relevant URLs about your project. This is the place to link to bug trackers, source repositories, or where to support package development. The string of the key is the exact text that will be displayed on PyPI.
packages ¶
Set packages to a list of all packages in your project, including their subpackages, sub-subpackages, etc. Although the packages can be listed manually, setuptools.find_packages() finds them automatically. Use the include keyword argument to find only the given packages. Use the exclude keyword argument to omit packages that are not intended to be released and installed.
py_modules ¶
install_requires ¶
python_requires ¶
If your project only runs on certain Python versions, setting the python_requires argument to the appropriate PEP 440 version specifier string will prevent pip from installing the project on other Python versions. For example, if your package is for Python 3+ only, write:
If your package is for Python 2.6, 2.7, and all versions of Python 3 starting with 3.3, write:
Support for this feature is relatively recent. Your project’s source distributions and wheels (see Packaging your project ) must be built using at least version 24.2.0 of setuptools in order for the python_requires argument to be recognized and the appropriate metadata generated.
In addition, only versions 9.0.0 and higher of pip recognize the python_requires metadata. Users with earlier versions of pip will be able to download & install projects on any Python version regardless of the projects’ python_requires values.
package_data ¶
The value must be a mapping from package name to a list of relative path names that should be copied into the package. The paths are interpreted as relative to the directory containing the package.
data_files ¶
Each (directory, files) pair in the sequence specifies the installation directory and the files to install there. The directory must be a relative path (although this may change in the future, see wheel Issue #92), and it is interpreted relative to the installation prefix (Python’s sys.prefix for a default installation; site.USER_BASE for a user installation). Each file name in files is interpreted relative to the setup.py script at the top of the project source distribution.
scripts ¶
Although setup() supports a scripts keyword for pointing to pre-made scripts to install, the recommended approach to achieve cross-platform compatibility is to use console_scripts entry points (see below).
entry_points ¶
Use this keyword to specify any plugins that your project provides for any named entry points that may be defined by your project or others that you depend on.
For more information, see the section on Advertising Behavior from the setuptools docs.
The most commonly used entry point is “console_scripts” (see below).
console_scripts ¶
Choosing a versioning scheme¶
Standards compliance for interoperability¶
Here are some examples of compliant version numbers:
To further accommodate historical variations in approaches to version numbering, PEP 440 also defines a comprehensive technique for version normalisation that maps variant spellings of different version numbers to a standardised canonical form.
Scheme choices¶
Semantic versioning (preferred)¶
For new projects, the recommended versioning scheme is based on Semantic Versioning, but adopts a different approach to handling pre-releases and build metadata.
The essence of semantic versioning is a 3-part MAJOR.MINOR.MAINTENANCE numbering scheme, where the project author increments:
MAJOR version when they make incompatible API changes,
MINOR version when they add functionality in a backwards-compatible manner, and
MAINTENANCE version when they make backwards-compatible bug fixes.
Adopting this approach as a project author allows users to make use of “compatible release” specifiers, where name
= X.Y requires at least release X.Y, but also allows any later release with a matching MAJOR version.
Python projects adopting semantic versioning should abide by clauses 1-8 of the Semantic Versioning 2.0.0 specification.
Date based versioning¶
Semantic versioning is not a suitable choice for all projects, such as those with a regular time based release cadence and a deprecation process that provides warnings for a number of releases prior to removal of a feature.
A key advantage of date based versioning is that it is straightforward to tell how old the base feature set of a particular release is given just the version number.
Serial versioning¶
This is the simplest possible versioning scheme, and consists of a single number which is incremented every release.
While serial versioning is very easy to manage as a developer, it is the hardest to track as an end user, as serial version numbers convey little or no information regarding API backwards compatibility.
Hybrid schemes¶
Combinations of the above schemes are possible. For example, a project may combine date based versioning with serial versioning to create a YEAR.SERIAL numbering scheme that readily conveys the approximate age of a release, but doesn’t otherwise commit to a particular release cadence within the year.
Pre-release versioning¶
Regardless of the base versioning scheme, pre-releases for a given final release may be published as:
zero or more dev releases (denoted with a “.devN” suffix)
zero or more alpha releases (denoted with a “.aN” suffix)
zero or more beta releases (denoted with a “.bN” suffix)
zero or more release candidates (denoted with a “.rcN” suffix)
pip and other modern Python package installers ignore pre-releases by default when deciding which versions of dependencies to install.
Local version identifiers¶
A local version identifier takes the form
Working in “development mode”¶
You can install a project in “editable” or “develop” mode while you’re working on it. When installed as editable, a project can be edited in-place without reinstallation: changes to Python source files in projects installed as editable will be reflected the next time an interpreter process is started.
To install a Python package in “editable”/”development” mode Change directory to the root of the project directory and run:
You may want to install some of your dependencies in editable mode as well. For example, supposing your project requires “foo” and “bar”, but you want “bar” installed from VCS in editable mode, then you could construct a requirements file like so:
The first line says to install your project and any dependencies. The second line overrides the “bar” dependency, such that it’s fulfilled from VCS, not PyPI.
If, however, you want “bar” installed from a local directory in editable mode, the requirements file should look like this, with the local paths at the top of the file:
Otherwise, the dependency will be fulfilled from PyPI, due to the installation order of the requirements file. For more on requirements files, see the Requirements File section in the pip docs. For more on VCS installs, see the VCS Support section of the pip docs.
Lastly, if you don’t want to install any dependencies at all, you can run:
Packaging your project¶
Before you can build wheels and sdists for your project, you’ll need to install the build package: