zipapp --- 実行可能な Python zip アーカイブを管理する

Added in version 3.5.

ソースコード: Lib/zipapp.py


このモジュールは Python コードを含む zip ファイルの作成を行うツールを提供します。 zip ファイルは Python インタープリタで直接実行することが出来ます。 このモジュールは コマンドラインインターフェイスPython API の両方を提供します。

基本的な例

実行可能なアーカイブを Python コードを含むディレクトリから作成する為に コマンドラインインターフェイス をどのように利用することができるかを以下に例示します。アーカイブは実行時にアーカイブ内の myapp モジュールから main 関数を実行します。

$ python -m zipapp myapp -m "myapp:main"
$ python myapp.pyz
<output from myapp>

コマンドラインインターフェイス

コマンドラインからプログラムとして呼び出す場合は、次の形式を使用います:

$ python -m zipapp source [options]

source がディレクトリである場合、 source ディレクトリの内容からアーカイブを作成します。 source がファイルである場合、 source ファイル自身をアーカイブ化し、保存先アーカイブへコピーします。(または --info オプションが指定されている場合はファイルのシェバン行が表示されます。)

以下のオプションが解釈されます:

-o <output>, --output=<output>

出力を output に指定した名前のファイルへ書込みます。このオプションが指定されていない場合、出力先ファイル名は入力元 source と同じになり、 .pyz 拡張子が付与されます。 ファイル名が明示的に指定されている場合は、指定されたファイル名を使用します。(必要であれば .pyz 拡張子が含まれます。)

source がアーカイブである場合は、出力先ファイル名を必ず指定しなければなりません。 (source がアーカイブである場合は output を必ず source とは別の名前にしてください。)

-p <interpreter>, --python=<interpreter>

実行コマンドとしての interpreter を指定する #! 行を書庫に追加します。 また、POSIX では書庫を実行可能にします。 デフォルトでは #! 行を書かず、ファイルを実行可能にはしません。

-m <mainfn>, --main=<mainfn>

mainfn を実行するアーカイブへ __main__.py ファイルを書込んでください。 mainfn 引数は "pkg.mod:fn" の形式で指定します。 "pkg.mod" の場所はアーカイブ内の package/module です。 "fn" は指定した module から呼出すことのできる関数です。 __main__.py ファイルが module から呼出すことのできる関数を実行します。

書庫をコピーする際、 --main を指定することは出来ません。

-c, --compress

Стискайте файли за допомогою методу deflate, зменшуючи розмір вихідного файлу. За замовчуванням файли зберігаються в архіві без стиснення.

書庫をコピーする際、 --compress に効果はありません。

Added in version 3.7.

--info

診断するために書庫に埋め込まれたインタープリタを表示します。 この場合、他の全てのオプションは無視され、SOURCE はディレクトリではなく書庫でなければなりません。

-h, --help

簡単な使用法を表示して終了します。

Python API

このモジュールは 2 つの簡便関数を定義しています:

zipapp.create_archive(source, target=None, interpreter=None, main=None, filter=None, compressed=False)

source からアプリケーション書庫を作成します。 ソースは以下のいずれかです:

  • ディレクトリ名、または 新しいアプリケーションアーカイブがディレクトリのコンテンツから作成される場合に path-like object オブジェクトが参照するディレクトリ。

  • 既存のアプリケーションアーカイブファイルの名前、 または(interpreter 引数に指定した値を反映し、修正する)アーカイブへ ファイルがコピーされる場合に path-like object オブジェクトが参照するファイル。

  • バイトモードの読込みで開くファイルオブジェクト。 ファイルの内容がアプリケーションアーカイブとなり、 ファイルオブジェクトがアーカイブの起点となります。

target 引数は作成される書庫が書き込まれる場所を決めます:

  • ファイル名、または path-like object オブジェクトを指定した場合、アーカイブは指定したファイルへ書き込まれます。

  • 開いているファイルオブジェクトを指定した場合、 アーカイブはそのファイルオブジェクトへ書込みを行ないます。 ファイルオブジェクトは必ずバイトモードの書込みで開いてください。

  • target を指定しないか None を渡した場合、 source は必ずディレクトリでなければならず、target は source のファイル名に .pyz 拡張子を付与したファイル名となります。

interpreter 引数はアーカイブが実行時に使用する Python インタープリタの名前を指定します。 インタープリタ名は "シェバン" 行としてアーカイブの起点に書込まれます。 POSIX では OS によってシェバンが解釈され、 Windows では Python ランチャーによって扱われます。 シェバン行が書込まれていない場合は interpreter の結果を無視します。 interpreter が指定されており、 target がファイル名である場合、 target ファイルの実行可能ビットが設定されます。

main 引数はアーカイブのメインプログラムとして使用する callable の名前を指定します。 main 引数は source がディレクトリであり、 source が既に __main__.py ファイルを保持していない場合に限り、指定することができます。 main 引数は "pkg.module:callable" の形式を取り、 アーカイブは "pkg.module" をインポートして実行され、 指定した callable を引数なしで実行します。 source がディレクトリであり、 __main__.py が含まれていない場合、 main は無視すべきエラーとなり、 作成されたアーカイブには実行可能ビットが設定されません。

Необов’язковий аргумент filter визначає функцію зворотного виклику, якій передається об’єкт Path, що представляє шлях до доданого файлу (відносно вихідного каталогу). Він має повернути True, якщо файл потрібно додати.

Додатковий аргумент compressed визначає, чи стискаються файли. Якщо встановлено значення True, файли в архіві стискаються за допомогою методу deflate; інакше файли зберігаються нестисненими. Цей аргумент не діє під час копіювання існуючого архіву.

source または target へファイルオブジェクトを指定した場合、 caller が create_archive の呼出し後にオブジェクトを閉じます。

既存のアーカイブをコピーする際、ファイルオブジェクトは read , readline , write メソッドのみを提供します。 アーカイブをディレクトリから作成する際、 target がファイルオブジェクトである場合は、 zipfile.ZipFile クラスへ渡されます。必ずクラスが必要とするメソッドを提供してください。

バージョン 3.7 で変更: Added the filter and compressed parameters.

zipapp.get_interpreter(archive)

アーカイブの最初の行の #! に指定されたインタープリタを返します。 #! が無い場合は None を返します。 archive 引数は、ファイル名またはバイトモードの読込みで開いた ファイルに準じるオブジェクトを指定することができ、アーカイブの起点で決定されます。

使用例

ディレクトリを書庫に圧縮し、実行します。

$ python -m zipapp myapp
$ python myapp.pyz
<output from myapp>

同じことを create_archive() 関数を使用して行うことができます:

>>> import zipapp
>>> zipapp.create_archive('myapp', 'myapp.pyz')

POSIX でアプリケーションを直接実行可能にするには使用するインタープリタを指定します。

$ python -m zipapp myapp -p "/usr/bin/env python"
$ ./myapp.pyz
<output from myapp>

シバン行を既存の書庫で置換するには、 create_archive() function: を使用して変更された書庫を作成します:

>>> 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 #!, але є інші проблеми, які слід враховувати:

  • Якщо ви використовуєте "/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, наприклад .

Як правило, ви повинні використовувати "/usr/bin/env python2" або "/usr/bin/env python3", залежно від того, чи ваш код написаний для Python 2 чи 3.

Створення автономних програм за допомогою zipap

Використовуючи модуль zipapp, можна створювати самодостатні програми Python, які можна розповсюджувати серед кінцевих користувачів, яким потрібно лише встановити відповідну версію Python у своїй системі. Ключ до цього полягає в тому, щоб об’єднати всі залежності програми в архів разом із кодом програми.

Щоб створити окремий архів, виконайте наведені нижче дії.

  1. Створіть свою програму в каталозі як зазвичай, щоб у вас був каталог myapp, що містить файл __main__.py і будь-який допоміжний код програми.

  2. Встановіть усі залежності вашої програми в каталог myapp за допомогою pip:

    $ python -m pip install -r requirements.txt --target myapp
    

    (це припускає, що у вас є вимоги до проекту у файлі requirements.txt - якщо ні, ви можете просто вручну перерахувати залежності в командному рядку pip).

  3. Упакуйте програму за допомогою:

    $ python -m zipapp -p "interpreter" myapp
    

Це створить окремий виконуваний файл, який можна буде запустити на будь-якій машині з доступним відповідним інтерпретатором. Дивіться インタープリタの指定 для деталей. Його можна надіслати користувачам як один файл.

В Unix файл myapp.pyz є виконуваним у тому вигляді, в якому він є. Ви можете перейменувати файл, щоб видалити розширення .pyz, якщо ви віддаєте перевагу "простій" назві команди. У Windows файл myapp.pyz[w] є виконуваним через те, що інтерпретатор Python реєструє розширення файлів .pyz і .pyzw під час встановлення.

Застереження

Якщо ваша програма залежить від пакета, який містить розширення C, цей пакет не можна запустити з zip-файлу (це обмеження ОС, оскільки виконуваний код має бути присутнім у файловій системі, щоб завантажувач ОС міг його завантажити). У цьому випадку ви можете виключити цю залежність із zip-файлу та вимагати, щоб ваші користувачі встановили його, або надіслати його разом із zip-файлом і додати код до свого __main__.py, щоб включити каталог, що містить розархівований модуль, у sys.path. У цьому випадку вам потрібно буде переконатися, що надіслано відповідні двійкові файли для вашої цільової архітектури (і, можливо, вибрати правильну версію для додавання до sys.path під час виконання, на основі комп’ютера користувача).

Формат архіву програми Python Zip

З версії 2.6 Python може виконувати файли zip, які містять файл __main__.py. Для виконання Python архів програми просто має бути стандартним zip-файлом, що містить файл __main__.py, який буде запущено як точка входу для програми. Як зазвичай для будь-якого сценарію Python, батьківський сценарій (у цьому випадку zip-файл) буде розміщено в sys.path і, таким чином, інші модулі можуть бути імпортовані з zip-файлу.

Формат файлу zip дозволяє додавати довільні дані до файлу zip. Формат програми zip використовує цю можливість для додавання до файлу стандартного рядка POSIX "shebang" (#!/path/to/interpreter).

Формально формат програми Python zip є таким:

  1. An optional shebang line, containing the characters b'#!' followed by an interpreter name, and then a newline (b'\n') character. The interpreter name can be anything acceptable to the OS "shebang" processing, or the Python launcher on Windows. The interpreter should be encoded in UTF-8 on Windows, and in sys.getfilesystemencoding() on POSIX.

  2. Стандартні дані файлу zip, згенеровані модулем zipfile. Вміст zip-файлу має включати файл під назвою __main__.py (який має бути в "корені" zip-файлу, тобто не може бути у підкаталозі). Дані файлу zip можна стиснути або розпакувати.

Якщо в архіві програми є рядок shebang, він може мати біт виконуваного файлу, встановлений у системах POSIX, щоб дозволити його виконання безпосередньо.

Немає вимог, щоб інструменти в цьому модулі використовувалися для створення архівів програми - модуль є зручним, але архіви у вищезазначеному форматі, створені будь-якими засобами, прийнятні для Python.