Andrés Delfino | 271818f | 2018-09-14 14:13:09 -0300 | [diff] [blame] | 1 | :mod:`zipapp` --- Manage executable Python zip archives |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 2 | ======================================================= |
| 3 | |
| 4 | .. module:: zipapp |
Andrés Delfino | 271818f | 2018-09-14 14:13:09 -0300 | [diff] [blame] | 5 | :synopsis: Manage executable Python zip archives |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 6 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 7 | .. versionadded:: 3.5 |
| 8 | |
| 9 | **Source code:** :source:`Lib/zipapp.py` |
| 10 | |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 11 | .. index:: |
| 12 | single: Executable Zip Files |
| 13 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 14 | -------------- |
| 15 | |
| 16 | This module provides tools to manage the creation of zip files containing |
| 17 | Python code, which can be :ref:`executed directly by the Python interpreter |
| 18 | <using-on-interface-options>`. The module provides both a |
| 19 | :ref:`zipapp-command-line-interface` and a :ref:`zipapp-python-api`. |
| 20 | |
| 21 | |
| 22 | Basic Example |
| 23 | ------------- |
| 24 | |
Martin Panter | 00ccacc | 2016-04-16 04:59:38 +0000 | [diff] [blame] | 25 | The following example shows how the :ref:`zipapp-command-line-interface` |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 26 | can be used to create an executable archive from a directory containing |
| 27 | Python code. When run, the archive will execute the ``main`` function from |
| 28 | the module ``myapp`` in the archive. |
| 29 | |
Serhiy Storchaka | 46936d5 | 2018-04-08 19:18:04 +0300 | [diff] [blame] | 30 | .. code-block:: shell-session |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 31 | |
| 32 | $ python -m zipapp myapp -m "myapp:main" |
| 33 | $ python myapp.pyz |
| 34 | <output from myapp> |
| 35 | |
| 36 | |
| 37 | .. _zipapp-command-line-interface: |
| 38 | |
| 39 | Command-Line Interface |
| 40 | ---------------------- |
| 41 | |
| 42 | When called as a program from the command line, the following form is used: |
| 43 | |
Serhiy Storchaka | 46936d5 | 2018-04-08 19:18:04 +0300 | [diff] [blame] | 44 | .. code-block:: shell-session |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 45 | |
| 46 | $ python -m zipapp source [options] |
| 47 | |
| 48 | If *source* is a directory, this will create an archive from the contents of |
| 49 | *source*. If *source* is a file, it should be an archive, and it will be |
| 50 | copied to the target archive (or the contents of its shebang line will be |
| 51 | displayed if the --info option is specified). |
| 52 | |
| 53 | The following options are understood: |
| 54 | |
| 55 | .. program:: zipapp |
| 56 | |
| 57 | .. cmdoption:: -o <output>, --output=<output> |
| 58 | |
| 59 | Write the output to a file named *output*. If this option is not specified, |
| 60 | the output filename will be the same as the input *source*, with the |
| 61 | extension ``.pyz`` added. If an explicit filename is given, it is used as |
| 62 | is (so a ``.pyz`` extension should be included if required). |
| 63 | |
| 64 | An output filename must be specified if the *source* is an archive (and in |
| 65 | that case, *output* must not be the same as *source*). |
| 66 | |
| 67 | .. cmdoption:: -p <interpreter>, --python=<interpreter> |
| 68 | |
| 69 | Add a ``#!`` line to the archive specifying *interpreter* as the command |
| 70 | to run. Also, on POSIX, make the archive executable. The default is to |
| 71 | write no ``#!`` line, and not make the file executable. |
| 72 | |
| 73 | .. cmdoption:: -m <mainfn>, --main=<mainfn> |
| 74 | |
| 75 | Write a ``__main__.py`` file to the archive that executes *mainfn*. The |
| 76 | *mainfn* argument should have the form "pkg.mod:fn", where "pkg.mod" is a |
| 77 | package/module in the archive, and "fn" is a callable in the given module. |
| 78 | The ``__main__.py`` file will execute that callable. |
| 79 | |
| 80 | :option:`--main` cannot be specified when copying an archive. |
| 81 | |
Zhiming Wang | d87b105 | 2017-09-29 13:31:52 -0400 | [diff] [blame] | 82 | .. cmdoption:: -c, --compress |
| 83 | |
| 84 | Compress files with the deflate method, reducing the size of the output |
| 85 | file. By default, files are stored uncompressed in the archive. |
| 86 | |
| 87 | :option:`--compress` has no effect when copying an archive. |
| 88 | |
Berker Peksag | 12d6056 | 2017-11-04 15:17:56 +0300 | [diff] [blame] | 89 | .. versionadded:: 3.7 |
| 90 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 91 | .. cmdoption:: --info |
| 92 | |
| 93 | Display the interpreter embedded in the archive, for diagnostic purposes. In |
| 94 | this case, any other options are ignored and SOURCE must be an archive, not a |
| 95 | directory. |
| 96 | |
| 97 | .. cmdoption:: -h, --help |
| 98 | |
| 99 | Print a short usage message and exit. |
| 100 | |
| 101 | |
| 102 | .. _zipapp-python-api: |
| 103 | |
| 104 | Python API |
| 105 | ---------- |
| 106 | |
| 107 | The module defines two convenience functions: |
| 108 | |
| 109 | |
Zhiming Wang | d87b105 | 2017-09-29 13:31:52 -0400 | [diff] [blame] | 110 | .. function:: create_archive(source, target=None, interpreter=None, main=None, filter=None, compressed=False) |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 111 | |
| 112 | Create an application archive from *source*. The source can be any |
| 113 | of the following: |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 114 | |
Serhiy Storchaka | 4aec9a8 | 2017-03-25 13:05:23 +0200 | [diff] [blame] | 115 | * The name of a directory, or a :term:`path-like object` referring |
Paul Moore | a4d4dd3 | 2015-03-22 15:32:36 +0000 | [diff] [blame] | 116 | to a directory, in which case a new application archive will be |
| 117 | created from the content of that directory. |
Serhiy Storchaka | 4aec9a8 | 2017-03-25 13:05:23 +0200 | [diff] [blame] | 118 | * The name of an existing application archive file, or a :term:`path-like object` |
| 119 | referring to such a file, in which case the file is copied to |
Paul Moore | a4d4dd3 | 2015-03-22 15:32:36 +0000 | [diff] [blame] | 120 | the target (modifying it to reflect the value given for the *interpreter* |
| 121 | argument). The file name should include the ``.pyz`` extension, if required. |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 122 | * A file object open for reading in bytes mode. The content of the |
| 123 | file should be an application archive, and the file object is |
| 124 | assumed to be positioned at the start of the archive. |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 125 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 126 | The *target* argument determines where the resulting archive will be |
| 127 | written: |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 128 | |
Serhiy Storchaka | 4aec9a8 | 2017-03-25 13:05:23 +0200 | [diff] [blame] | 129 | * If it is the name of a file, or a :term:`path-like object`, |
Paul Moore | a4d4dd3 | 2015-03-22 15:32:36 +0000 | [diff] [blame] | 130 | the archive will be written to that file. |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 131 | * If it is an open file object, the archive will be written to that |
| 132 | file object, which must be open for writing in bytes mode. |
Serhiy Storchaka | ecf41da | 2016-10-19 16:29:26 +0300 | [diff] [blame] | 133 | * If the target is omitted (or ``None``), the source must be a directory |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 134 | and the target will be a file with the same name as the source, with |
| 135 | a ``.pyz`` extension added. |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 136 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 137 | The *interpreter* argument specifies the name of the Python |
| 138 | interpreter with which the archive will be executed. It is written as |
| 139 | a "shebang" line at the start of the archive. On POSIX, this will be |
| 140 | interpreted by the OS, and on Windows it will be handled by the Python |
| 141 | launcher. Omitting the *interpreter* results in no shebang line being |
| 142 | written. If an interpreter is specified, and the target is a |
| 143 | filename, the executable bit of the target file will be set. |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 144 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 145 | The *main* argument specifies the name of a callable which will be |
| 146 | used as the main program for the archive. It can only be specified if |
| 147 | the source is a directory, and the source does not already contain a |
| 148 | ``__main__.py`` file. The *main* argument should take the form |
| 149 | "pkg.module:callable" and the archive will be run by importing |
| 150 | "pkg.module" and executing the given callable with no arguments. It |
| 151 | is an error to omit *main* if the source is a directory and does not |
| 152 | contain a ``__main__.py`` file, as otherwise the resulting archive |
| 153 | would not be executable. |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 154 | |
Paul Moore | 0780bf7 | 2017-08-26 18:04:12 +0100 | [diff] [blame] | 155 | The optional *filter* argument specifies a callback function that |
| 156 | is passed a Path object representing the path to the file being added |
| 157 | (relative to the source directory). It should return ``True`` if the |
| 158 | file is to be added. |
Jeffrey Rackauckas | b811d66 | 2017-08-09 06:37:17 -0700 | [diff] [blame] | 159 | |
Zhiming Wang | d87b105 | 2017-09-29 13:31:52 -0400 | [diff] [blame] | 160 | The optional *compressed* argument determines whether files are |
| 161 | compressed. If set to ``True``, files in the archive are compressed |
| 162 | with the deflate method; otherwise, files are stored uncompressed. |
| 163 | This argument has no effect when copying an existing archive. |
| 164 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 165 | If a file object is specified for *source* or *target*, it is the |
| 166 | caller's responsibility to close it after calling create_archive. |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 167 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 168 | When copying an existing archive, file objects supplied only need |
| 169 | ``read`` and ``readline``, or ``write`` methods. When creating an |
| 170 | archive from a directory, if the target is a file object it will be |
| 171 | passed to the ``zipfile.ZipFile`` class, and must supply the methods |
| 172 | needed by that class. |
| 173 | |
Paul Moore | 0780bf7 | 2017-08-26 18:04:12 +0100 | [diff] [blame] | 174 | .. versionadded:: 3.7 |
Zhiming Wang | d87b105 | 2017-09-29 13:31:52 -0400 | [diff] [blame] | 175 | Added the *filter* and *compressed* arguments. |
Paul Moore | 0780bf7 | 2017-08-26 18:04:12 +0100 | [diff] [blame] | 176 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 177 | .. function:: get_interpreter(archive) |
| 178 | |
| 179 | Return the interpreter specified in the ``#!`` line at the start of the |
| 180 | archive. If there is no ``#!`` line, return :const:`None`. |
| 181 | The *archive* argument can be a filename or a file-like object open |
| 182 | for reading in bytes mode. It is assumed to be at the start of the archive. |
| 183 | |
| 184 | |
| 185 | .. _zipapp-examples: |
| 186 | |
| 187 | Examples |
| 188 | -------- |
| 189 | |
| 190 | Pack up a directory into an archive, and run it. |
| 191 | |
Serhiy Storchaka | 46936d5 | 2018-04-08 19:18:04 +0300 | [diff] [blame] | 192 | .. code-block:: shell-session |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 193 | |
| 194 | $ python -m zipapp myapp |
| 195 | $ python myapp.pyz |
| 196 | <output from myapp> |
| 197 | |
Stéphane Wirtel | 07fbbfd | 2018-10-05 16:17:18 +0200 | [diff] [blame] | 198 | The same can be done using the :func:`create_archive` function:: |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 199 | |
| 200 | >>> import zipapp |
| 201 | >>> zipapp.create_archive('myapp.pyz', 'myapp') |
| 202 | |
| 203 | To make the application directly executable on POSIX, specify an interpreter |
| 204 | to use. |
| 205 | |
Serhiy Storchaka | 46936d5 | 2018-04-08 19:18:04 +0300 | [diff] [blame] | 206 | .. code-block:: shell-session |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 207 | |
| 208 | $ python -m zipapp myapp -p "/usr/bin/env python" |
| 209 | $ ./myapp.pyz |
| 210 | <output from myapp> |
| 211 | |
| 212 | To replace the shebang line on an existing archive, create a modified archive |
| 213 | using the :func:`create_archive` function:: |
| 214 | |
| 215 | >>> import zipapp |
| 216 | >>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3') |
| 217 | |
| 218 | To update the file in place, do the replacement in memory using a :class:`BytesIO` |
| 219 | object, and then overwrite the source afterwards. Note that there is a risk |
| 220 | when overwriting a file in place that an error will result in the loss of |
| 221 | the original file. This code does not protect against such errors, but |
| 222 | production code should do so. Also, this method will only work if the archive |
| 223 | fits in memory:: |
| 224 | |
| 225 | >>> import zipapp |
| 226 | >>> import io |
| 227 | >>> temp = io.BytesIO() |
| 228 | >>> zipapp.create_archive('myapp.pyz', temp, '/usr/bin/python2') |
| 229 | >>> with open('myapp.pyz', 'wb') as f: |
| 230 | >>> f.write(temp.getvalue()) |
| 231 | |
Cheryl Sabella | 4be79f2 | 2018-03-20 18:23:19 -0400 | [diff] [blame] | 232 | |
| 233 | .. _zipapp-specifying-the-interpreter: |
| 234 | |
| 235 | Specifying the Interpreter |
| 236 | -------------------------- |
| 237 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 238 | Note that if you specify an interpreter and then distribute your application |
| 239 | archive, you need to ensure that the interpreter used is portable. The Python |
| 240 | launcher for Windows supports most common forms of POSIX ``#!`` line, but there |
| 241 | are other issues to consider: |
| 242 | |
| 243 | * If you use "/usr/bin/env python" (or other forms of the "python" command, |
| 244 | such as "/usr/bin/python"), you need to consider that your users may have |
| 245 | either Python 2 or Python 3 as their default, and write your code to work |
| 246 | under both versions. |
| 247 | * If you use an explicit version, for example "/usr/bin/env python3" your |
| 248 | application will not work for users who do not have that version. (This |
| 249 | may be what you want if you have not made your code Python 2 compatible). |
| 250 | * There is no way to say "python X.Y or later", so be careful of using an |
| 251 | exact version like "/usr/bin/env python3.4" as you will need to change your |
| 252 | shebang line for users of Python 3.5, for example. |
| 253 | |
Cheryl Sabella | 4be79f2 | 2018-03-20 18:23:19 -0400 | [diff] [blame] | 254 | Typically, you should use an "/usr/bin/env python2" or "/usr/bin/env python3", |
| 255 | depending on whether your code is written for Python 2 or 3. |
| 256 | |
| 257 | |
| 258 | Creating Standalone Applications with zipapp |
| 259 | -------------------------------------------- |
| 260 | |
| 261 | Using the :mod:`zipapp` module, it is possible to create self-contained Python |
| 262 | programs, which can be distributed to end users who only need to have a |
| 263 | suitable version of Python installed on their system. The key to doing this |
| 264 | is to bundle all of the application's dependencies into the archive, along |
| 265 | with the application code. |
| 266 | |
| 267 | The steps to create a standalone archive are as follows: |
| 268 | |
| 269 | 1. Create your application in a directory as normal, so you have a ``myapp`` |
| 270 | directory containing a ``__main__.py`` file, and any supporting application |
| 271 | code. |
| 272 | |
| 273 | 2. Install all of your application's dependencies into the ``myapp`` directory, |
| 274 | using pip: |
| 275 | |
Serhiy Storchaka | 46936d5 | 2018-04-08 19:18:04 +0300 | [diff] [blame] | 276 | .. code-block:: shell-session |
Cheryl Sabella | 4be79f2 | 2018-03-20 18:23:19 -0400 | [diff] [blame] | 277 | |
| 278 | $ python -m pip install -r requirements.txt --target myapp |
| 279 | |
| 280 | (this assumes you have your project requirements in a ``requirements.txt`` |
| 281 | file - if not, you can just list the dependencies manually on the pip command |
| 282 | line). |
| 283 | |
| 284 | 3. Optionally, delete the ``.dist-info`` directories created by pip in the |
| 285 | ``myapp`` directory. These hold metadata for pip to manage the packages, and |
| 286 | as you won't be making any further use of pip they aren't required - |
| 287 | although it won't do any harm if you leave them. |
| 288 | |
| 289 | 4. Package the application using: |
| 290 | |
Serhiy Storchaka | 46936d5 | 2018-04-08 19:18:04 +0300 | [diff] [blame] | 291 | .. code-block:: shell-session |
Cheryl Sabella | 4be79f2 | 2018-03-20 18:23:19 -0400 | [diff] [blame] | 292 | |
| 293 | $ python -m zipapp -p "interpreter" myapp |
| 294 | |
| 295 | This will produce a standalone executable, which can be run on any machine with |
| 296 | the appropriate interpreter available. See :ref:`zipapp-specifying-the-interpreter` |
| 297 | for details. It can be shipped to users as a single file. |
| 298 | |
| 299 | On Unix, the ``myapp.pyz`` file is executable as it stands. You can rename the |
| 300 | file to remove the ``.pyz`` extension if you prefer a "plain" command name. On |
| 301 | Windows, the ``myapp.pyz[w]`` file is executable by virtue of the fact that |
| 302 | the Python interpreter registers the ``.pyz`` and ``.pyzw`` file extensions |
| 303 | when installed. |
| 304 | |
| 305 | |
| 306 | Making a Windows executable |
| 307 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 308 | |
| 309 | On Windows, registration of the ``.pyz`` extension is optional, and |
| 310 | furthermore, there are certain places that don't recognise registered |
| 311 | extensions "transparently" (the simplest example is that |
| 312 | ``subprocess.run(['myapp'])`` won't find your application - you need to |
| 313 | explicitly specify the extension). |
| 314 | |
| 315 | On Windows, therefore, it is often preferable to create an executable from the |
| 316 | zipapp. This is relatively easy, although it does require a C compiler. The |
| 317 | basic approach relies on the fact that zipfiles can have arbitrary data |
| 318 | prepended, and Windows exe files can have arbitrary data appended. So by |
| 319 | creating a suitable launcher and tacking the ``.pyz`` file onto the end of it, |
| 320 | you end up with a single-file executable that runs your application. |
| 321 | |
| 322 | A suitable launcher can be as simple as the following:: |
| 323 | |
| 324 | #define Py_LIMITED_API 1 |
| 325 | #include "Python.h" |
| 326 | |
| 327 | #define WIN32_LEAN_AND_MEAN |
| 328 | #include <windows.h> |
| 329 | |
| 330 | #ifdef WINDOWS |
| 331 | int WINAPI wWinMain( |
| 332 | HINSTANCE hInstance, /* handle to current instance */ |
| 333 | HINSTANCE hPrevInstance, /* handle to previous instance */ |
| 334 | LPWSTR lpCmdLine, /* pointer to command line */ |
| 335 | int nCmdShow /* show state of window */ |
| 336 | ) |
| 337 | #else |
| 338 | int wmain() |
| 339 | #endif |
| 340 | { |
| 341 | wchar_t **myargv = _alloca((__argc + 1) * sizeof(wchar_t*)); |
| 342 | myargv[0] = __wargv[0]; |
| 343 | memcpy(myargv + 1, __wargv, __argc * sizeof(wchar_t *)); |
| 344 | return Py_Main(__argc+1, myargv); |
| 345 | } |
| 346 | |
| 347 | If you define the ``WINDOWS`` preprocessor symbol, this will generate a |
| 348 | GUI executable, and without it, a console executable. |
| 349 | |
| 350 | To compile the executable, you can either just use the standard MSVC |
| 351 | command line tools, or you can take advantage of the fact that distutils |
| 352 | knows how to compile Python source:: |
| 353 | |
| 354 | >>> from distutils.ccompiler import new_compiler |
| 355 | >>> import distutils.sysconfig |
| 356 | >>> import sys |
| 357 | >>> import os |
| 358 | >>> from pathlib import Path |
| 359 | |
| 360 | >>> def compile(src): |
| 361 | >>> src = Path(src) |
| 362 | >>> cc = new_compiler() |
| 363 | >>> exe = src.stem |
| 364 | >>> cc.add_include_dir(distutils.sysconfig.get_python_inc()) |
| 365 | >>> cc.add_library_dir(os.path.join(sys.base_exec_prefix, 'libs')) |
| 366 | >>> # First the CLI executable |
| 367 | >>> objs = cc.compile([str(src)]) |
| 368 | >>> cc.link_executable(objs, exe) |
| 369 | >>> # Now the GUI executable |
| 370 | >>> cc.define_macro('WINDOWS') |
| 371 | >>> objs = cc.compile([str(src)]) |
| 372 | >>> cc.link_executable(objs, exe + 'w') |
| 373 | |
| 374 | >>> if __name__ == "__main__": |
| 375 | >>> compile("zastub.c") |
| 376 | |
| 377 | The resulting launcher uses the "Limited ABI", so it will run unchanged with |
| 378 | any version of Python 3.x. All it needs is for Python (``python3.dll``) to be |
| 379 | on the user's ``PATH``. |
| 380 | |
| 381 | For a fully standalone distribution, you can distribute the launcher with your |
| 382 | application appended, bundled with the Python "embedded" distribution. This |
| 383 | will run on any PC with the appropriate architecture (32 bit or 64 bit). |
| 384 | |
| 385 | |
| 386 | Caveats |
| 387 | ~~~~~~~ |
| 388 | |
| 389 | There are some limitations to the process of bundling your application into |
| 390 | a single file. In most, if not all, cases they can be addressed without |
| 391 | needing major changes to your application. |
| 392 | |
| 393 | 1. If your application depends on a package that includes a C extension, that |
| 394 | package cannot be run from a zip file (this is an OS limitation, as executable |
| 395 | code must be present in the filesystem for the OS loader to load it). In this |
| 396 | case, you can exclude that dependency from the zipfile, and either require |
| 397 | your users to have it installed, or ship it alongside your zipfile and add code |
| 398 | to your ``__main__.py`` to include the directory containing the unzipped |
| 399 | module in ``sys.path``. In this case, you will need to make sure to ship |
| 400 | appropriate binaries for your target architecture(s) (and potentially pick the |
| 401 | correct version to add to ``sys.path`` at runtime, based on the user's machine). |
| 402 | |
| 403 | 2. If you are shipping a Windows executable as described above, you either need to |
| 404 | ensure that your users have ``python3.dll`` on their PATH (which is not the |
| 405 | default behaviour of the installer) or you should bundle your application with |
| 406 | the embedded distribution. |
| 407 | |
| 408 | 3. The suggested launcher above uses the Python embedding API. This means that in |
| 409 | your application, ``sys.executable`` will be your application, and *not* a |
| 410 | conventional Python interpreter. Your code and its dependencies need to be |
| 411 | prepared for this possibility. For example, if your application uses the |
| 412 | :mod:`multiprocessing` module, it will need to call |
| 413 | :func:`multiprocessing.set_executable` to let the module know where to find the |
| 414 | standard Python interpreter. |
| 415 | |
| 416 | |
Brett Cannon | cc4dfc1 | 2015-03-13 10:40:49 -0400 | [diff] [blame] | 417 | The Python Zip Application Archive Format |
| 418 | ----------------------------------------- |
| 419 | |
| 420 | Python has been able to execute zip files which contain a ``__main__.py`` file |
| 421 | since version 2.6. In order to be executed by Python, an application archive |
| 422 | simply has to be a standard zip file containing a ``__main__.py`` file which |
| 423 | will be run as the entry point for the application. As usual for any Python |
| 424 | script, the parent of the script (in this case the zip file) will be placed on |
| 425 | :data:`sys.path` and thus further modules can be imported from the zip file. |
| 426 | |
| 427 | The zip file format allows arbitrary data to be prepended to a zip file. The |
| 428 | zip application format uses this ability to prepend a standard POSIX "shebang" |
| 429 | line to the file (``#!/path/to/interpreter``). |
| 430 | |
| 431 | Formally, the Python zip application format is therefore: |
| 432 | |
| 433 | 1. An optional shebang line, containing the characters ``b'#!'`` followed by an |
| 434 | interpreter name, and then a newline (``b'\n'``) character. The interpreter |
| 435 | name can be anything acceptable to the OS "shebang" processing, or the Python |
| 436 | launcher on Windows. The interpreter should be encoded in UTF-8 on Windows, |
| 437 | and in :func:`sys.getfilesystemencoding()` on POSIX. |
| 438 | 2. Standard zipfile data, as generated by the :mod:`zipfile` module. The |
| 439 | zipfile content *must* include a file called ``__main__.py`` (which must be |
| 440 | in the "root" of the zipfile - i.e., it cannot be in a subdirectory). The |
| 441 | zipfile data can be compressed or uncompressed. |
| 442 | |
| 443 | If an application archive has a shebang line, it may have the executable bit set |
| 444 | on POSIX systems, to allow it to be executed directly. |
| 445 | |
| 446 | There is no requirement that the tools in this module are used to create |
| 447 | application archives - the module is a convenience, but archives in the above |
| 448 | format created by any means are acceptable to Python. |
Brett Cannon | 64e4f7f | 2015-03-13 10:42:08 -0400 | [diff] [blame] | 449 | |