sourcedist.md
1> **Источник:** https://python-all.ru/2.7/distutils/sourcedist.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 4. Создание дистрибутива исходного кода89Как показано в разделе [Простой пример](https://python-all.ru/2.7/distutils/introduction.html#distutils-simple-example), для создания дистрибутива исходного кода используется команда **sdist**. В простейшем случае1011```python12python setup.py sdist13```1415(при условии, что в скрипте установки или файле конфигурации не были указаны параметры **sdist**), **sdist** создаёт архив в формате, принятом по умолчанию для текущей платформы. По умолчанию на Unix это сжатый gzip tar-файл (`.tar.gz`), а на Windows – ZIP-файл.1617Можно указать любое количество форматов с помощью параметра `--formats`, например:1819```python20python setup.py sdist --formats=gztar,zip21```2223чтобы создать tar-архив, сжатый gzip, и zip-архив. Доступны следующие форматы:2425| Формат | Описание | Примечания |26| --- | --- | --- |27| `zip` | zip-файл (`.zip`) | (1),(3) |28| `gztar` | сжатый gzip tar-файл (`.tar.gz`) | (2) |29| `bztar` | сжатый bzip2 tar-файл (`.tar.bz2`) | |30| `ztar` | сжатый tar-файл (`.tar.Z`) | (4) |31| `tar` | tar-файл (`.tar`) | |3233Примечания:34351. по умолчанию на Windows362. по умолчанию на Unix373. требуется внешняя утилита **zip** или модуль [`zipfile`](https://python-all.ru/2.7/library/zipfile.html#module-zipfile) (входит в стандартную библиотеку Python начиная с Python 1.6)384. требует программу **compress**.3940При использовании любого формата `tar` (`gztar`, `bztar`, `ztar` или `tar`) в Unix можно указать имена `owner` и `group`, которые будут заданы для каждого элемента архива.4142Например, чтобы все файлы архива принадлежали пользователю root:4344```python45python setup.py sdist --owner=root --group=root46```4748## 4.1. Указание файлов для распространения4950Если не указан явный список файлов (или инструкции по его генерации), команда **sdist** помещает в дистрибутив исходного кода минимальный набор по умолчанию:5152- все исходные файлы Python, подразумеваемые параметрами `py_modules` и `packages`53- все исходные файлы C, упомянутые в параметрах `ext_modules` или `libraries`54- Скрипты, указанные с помощью опции `scripts`. См. [Установка скриптов](https://python-all.ru/2.7/distutils/setupscript.html#distutils-installing-scripts).55- всё, что похоже на тестовый скрипт: `test/test*.py` (в настоящее время Distutils ничего не делает с тестовыми скриптами, кроме как включает их в дистрибутивы исходного кода, но в будущем появится стандарт для тестирования дистрибутивов модулей Python)56- `README.txt` (или `README`), `setup.py` (или как бы вы ни назвали свой сценарий setup), и `setup.cfg`57- все файлы, соответствующие метаданным `package_data`. См. [Установка данных пакета](https://python-all.ru/2.7/distutils/setupscript.html#distutils-installing-package-data).58- все файлы, соответствующие метаданным `data_files`. См. [Установка дополнительных файлов](https://python-all.ru/2.7/distutils/setupscript.html#distutils-additional-files).5960Иногда этого достаточно, но обычно требуется указать дополнительные файлы для распространения. Типичный способ – написать *шаблон манифеста*, по умолчанию называемый `MANIFEST.in`. Шаблон манифеста – это просто список инструкций для создания файла манифеста, `MANIFEST`, который содержит точный перечень файлов, включаемых в дистрибутив исходного кода. Команда **sdist** обрабатывает этот шаблон и формирует манифест на основе его инструкций и того, что она находит в файловой системе.6162Если вы предпочитаете создать собственный файл манифеста, его формат прост: одно имя файла на строку, только обычные файлы (или симлинки на них). Если вы указываете свой собственный `MANIFEST`, необходимо указать всё: описанный выше стандартный набор файлов в этом случае не применяется.6364Изменено в версии 2.7: Существующий сгенерированный `MANIFEST` будет регенерирован без **sdist** при сравнении времени его модификации с временем `MANIFEST.in` или `setup.py`.6566Изменено в версии 2.7.1: Файлы `MANIFEST` начинаются с комментария, указывающего, что они сгенерированы. Файлы без этого комментария не перезаписываются и не удаляются.6768Изменено в версии 2.7.3: **sdist** будет читать файл `MANIFEST`, если `MANIFEST.in` не существует, как это было до версии 2.7.6970См. раздел [Шаблон MANIFEST.in](https://python-all.ru/2.7/distutils/sourcedist.html#manifest-template) для справки по синтаксису.7172## 4.2. Параметры, связанные с манифестом7374Обычный порядок действий для команды **sdist** следующий:7576- если файл манифеста (по умолчанию `MANIFEST`) существует и первая строка не содержит комментария, указывающего, что он сгенерирован из `MANIFEST.in`, то он используется как есть, без изменений77- если файл манифеста не существует или был ранее автоматически сгенерирован, прочитать `MANIFEST.in` и создать манифест78- если не существует ни `MANIFEST`, ни `MANIFEST.in`, создать манифест только с набором стандартных файлов79- Для создания архива(ов) исходного дистрибутива используется список файлов, находящихся в `MANIFEST` (только что созданных или прочитанных\\n)8081Есть несколько опций, изменяющих это поведение. Во-первых, используйте\\n`--no-defaults` и `--no-prune` для отключения стандартных\\nнаборов «include» и «exclude».8283Во-вторых, возможно, потребуется просто (заново) сгенерировать манифест, но не создавать исходный дистрибутив:8485```python86python setup.py sdist --manifest-only87```8889`-o` – это сокращение для `--manifest-only`.9091## 4.3. Шаблон MANIFEST.in9293Файл `MANIFEST.in` можно добавить в проект, чтобы определить список файлов, включаемых в дистрибутив, создаваемый командой **sdist**.9495При запуске **sdist** он ищет файл `MANIFEST.in` и интерпретирует его для генерации файла `MANIFEST`, содержащего список файлов, которые будут включены в пакет.9697This mechanism can be used when the default list of files is not enough. (See [Specifying the files to distribute](https://python-all.ru/2.7/distutils/sourcedist.html#manifest)).9899### 4.3.1. Принцип100101Шаблон манифеста содержит одну команду на строку, где каждая команда определяет набор файлов для включения или исключения из исходного дистрибутива. Для примера рассмотрим собственный шаблон манифеста Distutils:102103```python104include *.txt105recursive-include examples *.txt *.py106prune examples/sample?/build107```108109Значения должны быть достаточно понятны: включить все файлы в корне дистрибутива, соответствующие `*.txt`, все файлы в каталоге `examples`, соответствующие `*.txt` или `*.py`, и исключить все каталоги, соответствующие `examples/sample?/build`. Всё это выполняется *после* стандартного набора включения, поэтому можно исключить файлы из стандартного набора с помощью явных инструкций в шаблоне манифеста. (Или можно использовать опцию `--no-defaults`, чтобы полностью отключить стандартный набор.)110111Порядок команд в шаблоне манифеста важен: изначально имеется список стандартных файлов, описанный выше, и каждая команда в шаблоне добавляет файлы в этот список или удаляет из него. После полной обработки шаблона манифеста удаляются файлы, которые не должны включаться в дистрибутив исходного кода:112113- все файлы в дереве «build» Distutils (по умолчанию `build/`)114- все файлы в каталогах с именами `RCS`, `CVS`, `.svn`, `.hg`, `.git`, `.bzr` или `_darcs`115116Теперь у нас есть полный список файлов, который записывается в манифест для дальнейшего использования, а затем используется для создания архивов дистрибутива исходного кода.117118Стандартный набор включаемых файлов можно отключить с помощью опции `--no-defaults`, а стандартный набор исключаемых – с помощью `--no-prune`.119120Следуя собственному шаблону манифеста Distutils, проследим, как команда **sdist** формирует список файлов для включения в дистрибутив исходного кода Distutils:1211221. включить все исходные файлы Python в подкаталогах `distutils` и `distutils/command` (поскольку пакеты, соответствующие этим двум каталогам, были указаны в опции `packages` в скрипте настройки – см. раздел [Написание скрипта настройки](https://python-all.ru/2.7/distutils/setupscript.html#setup-script))1232. включить `README.txt`, `setup.py` и `setup.cfg` (стандартные файлы)1243. включить `test/test*.py` (стандартные файлы)1254. включить `*.txt` в корне дистрибутива (это приведёт к повторному обнаружению `README.txt`, но такие дубликаты будут отсеяны позже)1265. включить всё, соответствующее `*.txt` или `*.py`, в поддереве каталога `examples`,1276. исключить все файлы в поддеревьях, начинающихся с каталогов, соответствующих `examples/sample?/build` – это может исключить файлы, включённые на двух предыдущих шагах, поэтому важно, чтобы команда `prune` в шаблоне манифеста располагалась после команды `recursive-include`1287. исключить всё дерево `build`, а также любые каталоги `RCS`, `CVS`, `.svn`, `.hg`, `.git`, `.bzr` и `_darcs`129130Как и в скрипте настройки, имена файлов и каталогов в шаблоне манифеста должны всегда разделяться косой чертой; Distutils позаботится о преобразовании их в стандартное представление на вашей платформе. Таким образом, шаблон манифеста переносим между операционными системами.131132### 4.3.2. Команды133134Команды шаблона манифеста:135136| Команда | Описание |137| --- | --- |138| **include pat1 pat2 ...** | включить все файлы, соответствующие любому из перечисленных шаблонов |139| **exclude pat1 pat2 ...** | исключить все файлы, соответствующие любому из перечисленных шаблонов |140| **recursive-include dir pat1 pat2 ...** | включить все файлы в каталоге *dir*, соответствующие любому из перечисленных шаблонов |141| **recursive-exclude dir pat1 pat2 ...** | исключить все файлы в каталоге *dir*, соответствующие любому из перечисленных шаблонов |142| **global-include pat1 pat2 ...** | включить все файлы в любом месте дерева исходного кода, соответствующие – & любому из перечисленных шаблонов |143| **global-exclude pat1 pat2 ...** | исключить все файлы в любом месте дерева исходных файлов соответствующие – & любым из перечисленных шаблонов |144| **prune dir** | исключить все файлы внутри *dir* |145| **graft dir** | включить все файлы внутри *dir* |146147Здесь используются шаблоны Unix-стиля «glob»: `*` соответствует любой последовательности обычных символов имени файла, `?` соответствует любому одному такому символу, а `[range]` соответствует любому из символов в *диапазоне* (например, `a-z`, `a-zA-Z`, `a-f0-9_.`). Определение «обычного символа имени файла» зависит от платформы: в Unix это любой символ, кроме косой черты; в Windows любой символ, кроме обратной косой черты или двоеточия.148