Введение в Distutils
Примечание
Этот документ сохраняется только до тех пор, пока документация setuptools по адресу https://setuptools.readthedocs.io/en/latest/setuptools.html самостоятельно не охватывает всю релевантную информацию, которая в настоящее время включена здесь.
Этот документ посвящен использованию Distutils для распространения модулей Python, сконцентрировавшись на роли разработчика/распространителя: если вам нужна информация об установке модулей Python, обратитесь к главе Установка модулей Python (старая версия).
1.1. Концепции и терминология
Использование Distutils довольно просто, как для разработчиков модулей, так и для пользователей/администраторов, устанавливающих модули сторонних разработчиков. Как разработчик, ваши обязанности (кроме написания качественного, хорошо документированного и протестированного кода, разумеется!):
- написать скрипт установки (
setup.pyпо соглашению) - (необязательно) написать конфигурационный файл установки
- создать исходное распределение
- (необязательно) создать одно или несколько скомпилированных (бинарных) распределений
В этом документе рассматриваются каждая из этих задач.
Не все разработчики модулей имеют доступ ко множеству платформ, поэтому не всегда возможно ожидать от них создания множества скомпилированных распределений. Надеемся, что появится класс посредников, называемых *упаковщиками*, чтобы решить эту проблему. Упаковщики будут брать исходные распределения, выпущенные разработчиками модулей, собирать их на одной или нескольких платформах и выпускать получившиеся скомпилированные распределения. Таким образом, пользователи на самых популярных платформах смогут устанавливать большинство популярных распределений модулей Python наиболее естественным для своей платформы способом, не выполняя ни одного скрипта установки или компилируя ни одной строчки кода.
1.2. Простой пример
Скрипт установки обычно довольно прост, хотя, поскольку он написан на Python, нет никаких произвольных ограничений на то, что вы можете с ним сделать, хотя следует быть осторожным, помещая произвольно дорогостоящие операции в свой скрипт установки. В отличие, скажем, от скриптов конфигурации типа Autoconf, скрипт установки может запускаться несколько раз во время сборки и установки вашего распределения модулей.
Если все, что вам нужно сделать, это распространить модуль под названием foo, содержащийся в файле foo.py, то ваш скрипт установки может быть таким же простым:
from distutils.core import setup
setup(name='foo',
version='1.0',
py_modules=['foo'],
)
Некоторые замечания:
- большинство сведений, которые вы предоставляете Distutils, предоставляются в качестве ключевых аргументов функции
setup() - эти ключевые аргументы делятся на две категории: метаданные пакета (имя, номер версии) и информация о том, что находится в пакете (в данном случае список чистых Python-модулей)
- модули указываются по имени модуля, а не имени файла (то же самое будет справедливо для пакетов и расширений)
- рекомендуется предоставить немного больше метаданных, в частности ваше имя, адрес электронной почты и URL-адрес проекта (см. раздел Написание скрипта установки для примера)
Чтобы создать исходное распределение для этого модуля, вам нужно создать скрипт установки setup.py, содержащий приведенный выше код, и выполнить эту команду в терминале:
python setup.py sdist
Для Windows откройте окно командной строки () и измените команду на:
setup.py sdist
sdist создаст архивный файл (например, tarball в Unix, ZIP-файл в Windows), содержащий ваш скрипт установки setup.py, и ваш модуль foo.py. Архивный файл будет иметь имя foo-1.0.tar.gz (или .zip), и будет распаковываться в каталог foo-1.0.
Если конечный пользователь хочет установить ваш модуль foo, ему нужно просто загрузить foo-1.0.tar.gz (или .zip), распаковать его и—с каталога foo-1.0—запустить
python setup.py install
что в конечном итоге скопирует foo.py в соответствующий каталог для модулей сторонних разработчиков в вашей установке Python.
Этот простой пример демонстрирует некоторые фундаментальные концепции Distutils. Во-первых, у разработчиков и установщиков одинаковый базовый пользовательский интерфейс, то есть скрипт установки. Разница заключается в том, какие команды Distutils они используют: команда sdist практически исключительно предназначена для разработчиков модулей, а install чаще используется установщиками (хотя большинство разработчиков иногда захотят установить свой собственный код).
Если вы хотите сделать установку максимально простой для пользователей, вы можете создать одно или несколько скомпилированных распределений для них. Например, если вы работаете на компьютере с Windows и хотите упростить установку для других пользователей Windows, вы можете создать исполняемый установщик (наиболее подходящий тип скомпилированного распределения для этой платформы) с помощью команды bdist_wininst. Например:
python setup.py bdist_wininst
создаст исполняемый установщик foo-1.0.win32.exe в текущем каталоге.
Другие полезные форматы скомпилированных распределений — RPM, реализованные командой bdist_rpm, Solaris pkgtool (bdist_pkgtool) и HP-UX swinstall (bdist_sdux). Например, следующая команда создаст файл RPM под названием foo-1.0.noarch.rpm:
python setup.py bdist_rpm
(Команда bdist_rpm использует исполняемый файл rpm, поэтому её нужно запускать на системах на основе RPM, таких как Red Hat Linux, SuSE Linux или Mandrake Linux.)
Вы можете узнать о доступных форматах распределений в любое время, выполнив
python setup.py bdist --help-formats
1.3. Общая терминология Python
Если вы читаете этот документ, вы, вероятно, хорошо представляете, что такое модули, расширения и т.д. Тем не менее, чтобы убедиться, что все работают на основе общей отправной точки, мы предлагаем следующий глоссарий распространённых терминов Python:
- модуль
-
основная единица повторного использования кода в Python: блок кода, импортируемый каким-либо другим кодом. Три типа модулей нас здесь интересуют: чистые Python-модули, расширенные модули и пакеты.
- чистый Python-модуль
-
модуль, написанный на Python и содержащийся в одном файле
.py(и, возможно, связанных файлах.pyc). Иногда его называют «чистым модулем». - расширенный модуль
-
модуль, написанный на языке низкого уровня реализации Python: C/C++ для Python, Java для Jython. Обычно содержится в одном динамически загружаемом предварительно скомпилированном файле, например, файле разделяемой библиотеки (
.so) для расширений Python в Unix, DLL (с расширением.pyd) для расширений Python в Windows или файле Java-класса для расширений Jython. (Обратите внимание, что в настоящее время Distutils обрабатывает только расширения C/C++ для Python.) - пакет
-
модуль, содержащий другие модули; обычно содержится в каталоге в файловой системе и отличается от других каталогов наличием файла
__init__.py. - корневой пакет
-
корень иерархии пакетов. (Это не совсем пакет, так как у него нет файла
__init__.py. Но нам нужно его как-то назвать.) Большая часть стандартной библиотеки находится в корневом пакете, а также многие небольшие автономные модули сторонних разработчиков, которые не относятся к более крупному набору модулей. В отличие от обычных пакетов, модули в корневом пакете могут находиться во многих каталогах: на самом деле, каждый каталог, указанный вsys.path, вносит свой вклад в модули корневого пакета.
1.4. Терминология Distutils
Следующие термины относятся более конкретно к области распространения модулей Python с помощью Distutils:
- распределение модуля
-
коллекция модулей Python, распространяемых вместе как единый загружаемый ресурс и предназначенная для установки *в целом*. Примеры некоторых известных распределений модулей — NumPy, SciPy, Pillow или mxBase. (Это называлось бы *пакетом*, но этот термин уже используется в контексте Python: одно распределение модулей может содержать ноль, один или несколько пакетов Python.)
- распределение чистого модуля
-
распределение модуля, содержащее только чистые Python-модули и пакеты. Иногда его называют «чистым распределением».
- распределение нечистого модуля
-
распределение модуля, содержащее по крайней мере один расширенный модуль. Иногда его называют «нечистым распределением».
- корень распределения
-
каталог верхнего уровня вашей исходной структуры (или исходного распределения); каталог, где существует
setup.py. Как правило,setup.pyбудет выполняться из этого каталога.
© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/distutils/introduction.html