zipapp — Управление исполняемыми zip-архивами Python
Новая в версии 3.5.
Исходный код: Lib/zipapp.py
Этот модуль предоставляет инструменты для управления созданием zip-архивов, содержащих код Python, которые могут быть непосредственно выполнены интерпретатором Python. Модуль предоставляет как командную строку, так и API Python.
1. Базовый пример
Следующий пример демонстрирует, как можно использовать командную строку для создания исполняемого архива из каталога, содержащего код Python. При запуске архив выполнит функцию main из модуля myapp в архиве.
$ python -m zipapp myapp -m "myapp:main" $ python myapp.pyz <output from myapp>
2. Командная строка
При вызове в качестве программы из командной строки используется следующий формат:
$ python -m zipapp source [options]
Если source — это каталог, это создаст архив из содержимого source. Если source — это файл, это должен быть архив, и он будет скопирован в целевой архив (или содержимое его строки shebang будет отображено, если указан параметр –info).
Поддерживаются следующие параметры:
-
-o <output>, --output=<output> -
Записать вывод в файл с именем output. Если этот параметр не указан, имя выходного файла будет таким же, как у входного source, с расширением
.pyzдобавленным. Если указано явное имя файла, оно используется как есть (поэтому расширение.pyzдолжно быть включено, если это требуется).Имя выходного файла должно быть указано, если source — архив (и в этом случае output не должен совпадать с source).
-
-p <interpreter>, --python=<interpreter> -
Добавить строку shebang в архив, задающую interpreter в качестве команды для запуска. Также, в POSIX, сделать архив исполняемым. По умолчанию не записывать строку shebang и не делать файл исполняемым.
-
-m <mainfn>, --main=<mainfn> -
Записать в архив файл
__main__.py, который выполняет mainfn. Аргумент mainfn должен иметь вид «pkg.mod:fn», где «pkg.mod» — пакет/модуль в архиве, а «fn» — вызываемый объект в данном модуле. Файл__main__.pyвыполнит этот вызываемый объект.--mainне может быть указан при копировании архива.
-
--info -
Отобразить интерпретатор, встроенный в архив, для целей диагностики. В этом случае все остальные параметры игнорируются, и SOURCE должен быть архивом, а не каталогом.
-
-h, --help -
Вывести краткую справку по использованию и выйти.
3. API Python
Модуль определяет две удобные функции:
-
zipapp.create_archive(source, target=None, interpreter=None, main=None) -
Создать архив приложения из source. Источник может быть любым из следующего:
- Имя каталога или объект
pathlib.Path, указывающий на каталог, в этом случае будет создан новый архив приложения из содержимого этого каталога. - Имя существующего файла архива приложения или объект
pathlib.Path, указывающий на такой файл, в этом случае файл копируется в целевой файл (изменяя его для отражения значения, данного для аргумента interpreter). Имя файла должно содержать расширение.pyzпри необходимости. - Объект файла, открытый для чтения в режиме байтов. Содержимое файла должно быть архивом приложения, и предполагается, что объект файла расположен в начале архива.
Аргумент target определяет, куда будет записан результирующий архив:
- Если это имя файла или объект
pathlb.Path, архив будет записан в этот файл. - Если это открытый объект файла, архив будет записан в этот объект файла, который должен быть открыт для записи в режиме байтов.
- Если параметр target опущен (или
None), source должен быть каталогом, и target будет файлом с тем же именем, что и source, с добавленным расширением.pyz.
Аргумент interpreter указывает имя интерпретатора Python, с помощью которого будет выполняться архив. Он записывается как строка shebang в начале архива. В POSIX это будет интерпретироваться ОС, а в Windows — обработчиком Python. Пропуск interpreter приводит к тому, что строка shebang не записывается. Если интерпретатор указан, и target — имя файла, то биты исполнения целевого файла будут установлены.
Аргумент main указывает имя вызываемого объекта, который будет использоваться в качестве основной программы для архива. Он может быть указан только если источник — это каталог, и источник не содержит файл
__main__.py. Аргумент main должен иметь вид «pkg.module:callable», и архив будет запущен путём импорта «pkg.module» и выполнения заданного вызываемого объекта без аргументов. Опускание main является ошибкой, если источник — это каталог, не содержащий файл__main__.py, поскольку в противном случае результирующий архив не будет исполняемым.Если для source или target указан объект файла, вызывающий обязан закрыть его после вызова create_archive.
При копировании существующего архива, объекты файлов, передаваемые, нуждаются только в методах
read,readline, илиwrite. При создании архива из каталога, если target — объект файла, он будет передан классуzipfile.ZipFile, и должен предоставить необходимые методы этому классу. - Имя каталога или объект
-
zipapp.get_interpreter(archive) -
Возвращает интерпретатор, указанный в строке shebang в начале архива. Если строки shebang нет, возвращает
None. Аргумент archive может быть именем файла или файлоподобным объектом, открытым для чтения в режиме байтов. Предполагается, что он находится в начале архива.
4. Примеры
Упаковать каталог в архив и запустить его.
$ python -m zipapp myapp $ python myapp.pyz <output from myapp>
То же самое можно сделать, используя функцию create_archive():
>>> import zipapp
>>> zipapp.create_archive('myapp.pyz', 'myapp')
Чтобы сделать приложение непосредственно исполняемым в POSIX, укажите интерпретатор для использования.
$ python -m zipapp myapp -p "/usr/bin/env python" $ ./myapp.pyz <output from myapp>
Чтобы заменить строку shebang в существующем архиве, создайте изменённый архив, используя функцию create_archive():
>>> import zipapp
>>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3')
Чтобы обновить файл на месте, выполните замену в памяти с помощью объекта BytesIO, а затем перезапишите исходный файл. Обратите внимание, что при перезаписи файла на месте есть риск, что ошибка приведёт к потере исходного файла. Этот код не защищён от таких ошибок, но производственный код должен быть защищён. Также этот метод будет работать только в том случае, если архив помещается в память:
>>> import zipapp
>>> import io
>>> temp = io.BytesIO()
>>> zipapp.create_archive('myapp.pyz', temp, '/usr/bin/python2')
>>> with open('myapp.pyz', 'wb') as f:
>>> f.write(temp.getvalue())
Обратите внимание, что если вы укажете интерпретатор и затем распространите свой архив приложения, вам нужно убедиться, что используемый интерпретатор переносимый. Загрузчик Python для Windows поддерживает большинство распространённых форм строки POSIX shebang, но есть и другие моменты, которые нужно учитывать:
- Если вы используете «/usr/bin/env python» (или другие формы команды «python», такие как «/usr/bin/python»), вам нужно учитывать, что пользователи могут иметь Python 2 или Python 3 в качестве по умолчанию, и написать код, который будет работать с обеими версиями.
- Если вы используете явную версию, например «/usr/bin/env python3», ваше приложение не будет работать для пользователей, у которых этой версии нет. (Это может быть то, что вам нужно, если вы не сделали свой код совместимым с Python 2).
- Нет способа сказать «Python X.Y или более поздние версии», поэтому будьте осторожны при использовании точной версии, например «/usr/bin/env python3.4», так как вам нужно будет изменить строку shebang для пользователей Python 3.5, например.
5. Формат архива Python Zip Application
Python может выполнять zip-файлы, содержащие файл __main__.py с версии 2.6. Для того, чтобы Python смог его выполнить, архив приложения должен быть обычным zip-файлом, содержащим файл __main__.py, который будет точкой входа в приложение. Как обычно для любого скрипта Python, родитель скрипта (в данном случае zip-файл) будет помещён в sys.path, и поэтому можно импортировать дополнительные модули из zip-файла.
Формат zip-файла позволяет добавлять произвольные данные в начало zip-файла. Формат архива приложения Python использует эту возможность для добавления стандартной строки POSIX shebang в файл (#!/path/to/interpreter).
Формально, формат архива Python Zip Application:
- Необязательная строка shebang, содержащая символы
b'#!'за которым следует имя интерпретатора, а затем символ новой строки (b'\n') . Имя интерпретатора может быть любым, приемлемым для обработки shebang ОС, или загрузчика Python в Windows. Интерпретатор должен быть закодирован в UTF-8 в Windows и вsys.getfilesystemencoding()в POSIX. - Стандартные данные zip-файла, как генерируются модулем
zipfile. Содержимое zip-файла должно включать файл с именем__main__.py(который должен быть в «корне» zip-файла — т. е., он не может находиться в подкаталоге).
Если у архива приложения есть строка shebang, то на POSIX-системах может быть установлен исполняемый бит, что позволит его напрямую выполнить.
Нет требования, чтобы инструменты в этом модуле использовались для создания архивов приложений — этот модуль удобство, но архивы в указанном формате, созданные любым способом, приемлемы для Python.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/zipapp.html