|
| 1 | +Understanding the ``zip_safe`` flag |
| 2 | +=================================== |
| 3 | + |
| 4 | +The ``zip_safe`` flag is a ``setuptools`` configuration mainly associated |
| 5 | +with the ``egg`` distribution format |
| 6 | +(which got replaced in the ecosystem by the newer ``wheel`` format) and the |
| 7 | +``easy_install`` command (deprecated in ``setuptools`` v58.3.0). |
| 8 | + |
| 9 | +It is very unlikely that the values of ``zip_safe`` will affect modern |
| 10 | +deployments that use :pypi:`pip` for installing packages. |
| 11 | +Moreover, new users of ``setuptools`` should not attempt to create egg files |
| 12 | +using the deprecated ``build_egg`` command. |
| 13 | +Therefore, this flag is considered **obsolete**. |
| 14 | + |
| 15 | +This document, however, describes what was the historical motivation behind |
| 16 | +this flag, and how it was used. |
| 17 | + |
| 18 | +Historical Motivation |
| 19 | +--------------------- |
| 20 | + |
| 21 | +For some use cases (such as bundling as part of a larger application), Python |
| 22 | +packages may be run directly from a zip file. |
| 23 | +Not all packages, however, are capable of running in compressed form, because |
| 24 | +they may expect to be able to access either source code or data files as |
| 25 | +normal operating system files. |
| 26 | + |
| 27 | +In the past, ``setuptools`` would install a project distributed |
| 28 | +as a zipfile or a directory (via the ``easy_install`` command or |
| 29 | +``python setup.py install``), |
| 30 | +the default choice being determined by the project's ``zip_safe`` flag. |
| 31 | + |
| 32 | +How the ``zip_safe`` flag was used? |
| 33 | +----------------------------------- |
| 34 | + |
| 35 | +To set this flag, a developer would pass a boolean value for the ``zip_safe`` argument to the |
| 36 | +``setup()`` function, or omit it. When omitted, the ``bdist_egg`` |
| 37 | +command would analyze the project's contents to see if it could detect any |
| 38 | +conditions that preventing the project from working in a zipfile. |
| 39 | + |
| 40 | +This was extremely conservative: ``bdist_egg`` would consider the |
| 41 | +project unsafe if it contained any C extensions or datafiles whatsoever. This |
| 42 | +does *not* mean that the project couldn't or wouldn't work as a zipfile! It just |
| 43 | +means that the ``bdist_egg`` authors were not yet comfortable asserting that |
| 44 | +the project *would* work. If the project did not contain any C or data files, and did not |
| 45 | +attempt to perform ``__file__`` or ``__path__`` introspection or source code manipulation, then |
| 46 | +there was an extremely solid chance the project will work when installed as a |
| 47 | +zipfile. (And if the project used ``pkg_resources`` for all its data file |
| 48 | +access, then C extensions and other data files shouldn't be a problem at all. |
| 49 | +See the :ref:`Accessing Data Files at Runtime` section for more information.) |
| 50 | + |
| 51 | +The developer could manually set ``zip_safe`` to ``True`` to perform tests, |
| 52 | +or to override the default behaviour (after checking all the warnings and |
| 53 | +understanding the implications), this would allow ``setuptools`` to install the |
| 54 | +project as a zip file. Alternatively, by setting ``zip_safe`` to ``False``, |
| 55 | +developers could force ``setuptools`` to always install the project as a |
| 56 | +directory. |
| 57 | + |
| 58 | +Modern ways of loading packages from zip files |
| 59 | +---------------------------------------------- |
| 60 | + |
| 61 | +Currently, popular Python package installers (such as :pypi:`pip`) and package |
| 62 | +indexes (such as PyPI_) consider that distribution packages are always |
| 63 | +installed as a directory. |
| 64 | +It is however still possible to load packages from zip files added to |
| 65 | +:obj:`sys.path`, thanks to the :mod:`zipimport` module |
| 66 | +and the :mod:`importlib` machinery provided by Python standard library. |
| 67 | + |
| 68 | +When working with modules loaded from a zip file, it is important to keep in |
| 69 | +mind that values of ``__file__`` and ``__path__`` might not work as expected. |
| 70 | +Please check the documentation for :mod:`importlib.resources`, if file |
| 71 | +locations are important for your use case. |
| 72 | + |
| 73 | + |
| 74 | +.. _PyPI: https://pypi.org |
0 commit comments