> **Источник:** https://python-all.ru/3.10/distutils/introduction.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 1. Введение в Distutils

> **Примечание**
>
> Этот документ сохраняется только до тех пор, пока `setuptools` документация по адресу [https://setuptools.readthedocs.io/en/latest/setuptools.html](https://python-all.ru/3.10/distutils/introduction.html) не станет самостоятельно охватывать всю актуальную информацию, приведённую здесь.

Этот документ посвящён использованию Distutils для распространения модулей Python, с упором на роль разработчика/распространителя: если вам нужна информация об установке модулей Python, обратитесь к разделу [Installing Python Modules (Legacy version)](https://python-all.ru/3.10/install/index.html#install-index).

## 1.1. Основные понятия и терминология

Использовать Distutils довольно просто как для разработчиков модулей, так и для пользователей или администраторов, устанавливающих сторонние модули. В роли разработчика ваши обязанности (помимо написания качественного, хорошо задокументированного и протестированного кода) таковы:

- написание setup-скрипта (`setup.py` по соглашению);
- (опционально) написание конфигурационного файла setup.cfg;
- создание исходной дистрибуции (source distribution);
- (опционально) создание одной или нескольких сборок (двоичных дистрибуций).

Каждая из этих задач описана в данном документе.

Не все разработчики модулей имеют доступ к множеству платформ, поэтому не всегда разумно требовать от них создания множества готовых сборок. Предполагается, что возникнет прослойка посредников, называемых *пакетёрами (packagers)*, которые решат эту проблему. Пакетёры будут брать исходные дистрибуции, выпущенные разработчиками, собирать их на одной или нескольких платформах и выпускать готовые двоичные дистрибуции. Таким образом, пользователи самых популярных платформ смогут устанавливать наиболее популярные дистрибуции модулей Python наиболее естественным для своей платформы способом – без необходимости запускать setup-скрипт или компилировать хотя бы строчку кода.

## 1.2. Простой пример

Сам setup-скрипт обычно довольно прост, но, поскольку он написан на Python, нет произвольных ограничений на то, что можно в нём делать. Однако стоит проявлять осторожность, размещая в нём слишком затратные по времени операции. В отличие от, скажем, configure-скриптов в стиле Autoconf, setup-скрипт может запускаться несколько раз в процессе сборки и установки вашей дистрибуции.

Если вы хотите распространять только модуль `foo`, содержащийся в файле `foo.py`, то ваш setup-скрипт может быть таким:

```python
from distutils.core import setup
setup(name='foo',
      version='1.0',
      py_modules=['foo'],
      )
```

Несколько замечаний:

- большая часть информации, передаваемой Distutils, задаётся в виде именованных аргументов функции `setup()`;
- эти именованные аргументы делятся на две категории: метаданные пакета (имя, номер версии) и информация о содержимом пакета (в данном случае – список чистых модулей Python);
- модули указываются по имени, а не по имени файла (то же справедливо для пакетов и расширений);
- рекомендуется указывать немного больше метаданных, в частности ваше имя, адрес электронной почты и URL проекта (пример приведён в разделе [Написание setup-скрипта](https://python-all.ru/3.10/distutils/setupscript.html#setup-script)).

Чтобы создать исходную дистрибуцию для этого модуля, напишите setup-скрипт `setup.py`, содержащий приведённый выше код, и выполните в терминале команду:

```python
python setup.py sdist
```

Для Windows откройте окно командной строки (Пуск ‣ Стандартные) и измените команду на:

```python
setup.py sdist
```

Команда **sdist** создаст архивный файл (например, tarball в Unix, ZIP-файл в Windows), содержащий ваш setup-скрипт `setup.py` и модуль `foo.py`. Архив будет называться `foo-1.0.tar.gz` (или `.zip`) и распаковываться в каталог `foo-1.0`.

Если конечный пользователь захочет установить ваш модуль `foo`, ему достаточно скачать `foo-1.0.tar.gz` (или `.zip`), распаковать его и из каталога `foo-1.0` выполнить:

```python
python setup.py install
```

который в конечном итоге скопирует `foo.py` в соответствующий каталог для сторонних модулей в установке Python.

Этот простой пример демонстрирует некоторые фундаментальные концепции Distutils. Во-первых, и разработчики, и установщики имеют одинаковый базовый интерфейс – сценарий setup. Разница в том, какие команды *commands* Distutils они используют: команда **sdist** почти исключительно для разработчиков модулей, а **install** чаще используется установщиками (хотя большинство разработчиков время от времени тоже хотят устанавливать свой код).

Другие полезные форматы собранных дистрибутивов: RPM (реализован командой **bdist\_rpm**), Solaris **pkgtool** (**bdist\_pkgtool**) и HP-UX **swinstall** (**bdist\_sdux**). Например, следующая команда создаст RPM-файл с именем `foo-1.0.noarch.rpm`:

```python
python setup.py bdist_rpm
```

(Команда **bdist\_rpm** использует исполняемый файл **rpm**, поэтому её нужно запускать на системе на базе RPM, такой как Red Hat Linux, SuSE Linux или Mandrake Linux.)

Узнать, какие форматы дистрибутивов доступны в любой момент, можно выполнив

```python
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` запускается из этого каталога.
