|
1 | | -Development Mode |
2 | | -================ |
3 | | - |
4 | | -Under normal circumstances, the ``setuptools`` assume that you are going to |
5 | | -build a distribution of your project, not use it in its "raw" or "unbuilt" |
6 | | -form. However, if you were to use the ``setuptools`` to build a distribution, |
7 | | -you would have to rebuild and reinstall your project every time you made a |
8 | | -change to it during development. |
9 | | - |
10 | | -Another problem that sometimes comes is that you may |
11 | | -need to do development on two related projects at the same time. You may need |
12 | | -to put both projects' packages in the same directory to run them, but need to |
13 | | -keep them separate for revision control purposes. How can you do this? |
14 | | - |
15 | | -Setuptools allows you to deploy your projects for use in a common directory or |
16 | | -staging area, but without copying any files. Thus, you can edit each project's |
17 | | -code in its checkout directory, and only need to run build commands when you |
18 | | -change files that need to be compiled or the provided metadata and setuptools configuration. |
19 | | - |
20 | | -You can perform a ``pip`` installation passing the ``-e/--editable`` |
21 | | -flag (e.g., ``pip install -e .``). It works very similarly to |
22 | | -``pip install .``, except that it doesn't actually install anything. |
23 | | -Instead, it creates a special ``.egg-link`` file in the target directory |
24 | | -(usually ``site-packages``) that links to your project's source code. |
25 | | -It may also update an existing ``easy-install.pth`` file |
26 | | -to include your project's source code, thereby making |
27 | | -it available on ``sys.path`` for all programs using that Python installation. |
28 | | - |
29 | | -You can deploy the same project to multiple staging areas, e.g., if you have |
30 | | -multiple projects on the same machine that are sharing the same project you're |
31 | | -doing development work. |
| 1 | +Development Mode (a.k.a. "Editable Installs") |
| 2 | +============================================= |
| 3 | + |
| 4 | +When creating a Python project, developers usually want to implement and test |
| 5 | +changes iteratively, before cutting a release and preparing a distribution archive. |
| 6 | + |
| 7 | +In normal circumstances this can be quite cumbersome and require the developers |
| 8 | +to manipulate the ``PATHONPATH`` environment variable or to continuous re-build |
| 9 | +and re-install the project. |
| 10 | + |
| 11 | +To facilitate iterative exploration and experimentation, setuptools allows |
| 12 | +users to instruct the Python interpreter and its import machinery to load the |
| 13 | +code under development directly from the project folder without having to |
| 14 | +copy the files to a different location in the disk. |
| 15 | +This means that changes in the Python source code can immediately take place |
| 16 | +without requiring a new installation. |
| 17 | + |
| 18 | +You can enter this "development mode" by performing an :doc:`editable installation |
| 19 | +<pip:topics/local-project-installs>` inside of a :term:`virtual environment`, |
| 20 | +using :doc:`pip's <pip:cli/pip_install>` ``-e/--editable`` flag, as shown bellow: |
| 21 | + |
| 22 | +.. code-block:: bash |
| 23 | +
|
| 24 | + $ cd your-python-project |
| 25 | + $ python -m venv .venv |
| 26 | + # Activate your environemt with: |
| 27 | + # `source .venv/bin/activate` on Unix/macOS |
| 28 | + # or `.venv\Scripts\activate` on Windows |
| 29 | +
|
| 30 | + $ pip install --editable . |
| 31 | +
|
| 32 | + # Now you have access to your package |
| 33 | + # as if it was installed in .venv |
| 34 | + $ python -c "import your_python_project" |
| 35 | +
|
| 36 | +
|
| 37 | +An "editable installation" works very similarly to a regular install with |
| 38 | +``pip install .``, except that it only installs your package dependencies, |
| 39 | +metadata and wrappers for :ref:`console and GUI scripts <console-scripts>`. |
| 40 | +Under the hood, setuptools will try to create a special :mod:`.pth file <site>` |
| 41 | +in the target directory (usually ``site-packages``) that extends the |
| 42 | +``PYTHONPATH`` or install a custom :doc:`import hook <python:reference/import>`. |
32 | 43 |
|
33 | 44 | When you're done with a given development task, you can simply uninstall your |
34 | 45 | package (as you would normally do with ``pip uninstall <package name>``). |
| 46 | + |
| 47 | +Please note that, by default an editable install will expose at least all the |
| 48 | +files that would be available in a regular installation. However, depending on |
| 49 | +the file and directory organization in your project, it might also expose |
| 50 | +as a side effect files that would not be normally available. |
| 51 | +This is allowed so you can iteratively create new Python modules. |
| 52 | +Please have a look on the following section if you are looking for a different behaviour. |
| 53 | + |
| 54 | +.. admonition:: Virtual Environments |
| 55 | + |
| 56 | + You can think about virtual environments as "isolated Python runtime deployments" |
| 57 | + that allow users to install different sets of libraries and tools without |
| 58 | + messing with the global behaviour of the system. |
| 59 | + |
| 60 | + They are a safe way of testing new projects and can be created easily |
| 61 | + with the :mod:`venv` module from the standard library. |
| 62 | + |
| 63 | + Please note however that depending on your operating system or distribution, |
| 64 | + ``venv`` might not come installed by default with Python. For those cases, |
| 65 | + you might need to use the OS package manager to install it. |
| 66 | + For example, in Debian/Ubuntu-based systems you can obtain it via: |
| 67 | + |
| 68 | + .. code-block:: bash |
| 69 | +
|
| 70 | + sudo apt install python3-venv |
| 71 | +
|
| 72 | + Alternatively, you can also try installing :pypi:`virtualenᴠ`. |
| 73 | + More information is available on the Python Packaging User Guide on |
| 74 | + :doc:`PyPUG:guides/installing-using-pip-and-virtual-environments`. |
| 75 | + |
| 76 | +.. note:: |
| 77 | + .. versionchanged:: v64.0.0 |
| 78 | + Editable installation hooks implemented according to :pep:`660`. |
| 79 | + Support for :pep:`namespace packages <420>` is still **EXPERIMENTAL**. |
| 80 | + |
| 81 | + |
| 82 | +"Strict" editable installs |
| 83 | +-------------------------- |
| 84 | + |
| 85 | +When thinking about editable installations, users might have the following |
| 86 | +expectations: |
| 87 | + |
| 88 | +1. It should allow developers to add new files (or split/rename existing ones) |
| 89 | + and have them automatically exposed. |
| 90 | +2. It should behave as close as possible to a regular installation and help |
| 91 | + users to detect problems (e.g. new files not being included in the distribution). |
| 92 | + |
| 93 | +Unfortunately these expectations are in conflict with each other. |
| 94 | +To solve this problem ``setuptools`` allows developers to choose a more |
| 95 | +*"strict"* mode for the editable installation. This can be done by passing |
| 96 | +a special *configuration setting* via :pypi:`pip`, as indicated bellow: |
| 97 | + |
| 98 | +.. code-block:: bash |
| 99 | +
|
| 100 | + pip install -e . --config-settings editable_mode=strict |
| 101 | +
|
| 102 | +In this mode, new files **won't** be exposed and the editable installs will |
| 103 | +try to mimic as much as possible the behavior of a regular install. |
| 104 | +Under the hood, ``setuptools`` will create a tree of file links in an auxiliary |
| 105 | +directory (``$your_project_dir/build``) and add it to ``PYTHONPATH`` via a |
| 106 | +:mod:`.pth file <site>`. (Please be careful to not delete this repository |
| 107 | +by mistake otherwise your files may stop being accessible). |
| 108 | + |
| 109 | +.. warning:: |
| 110 | + Strict editable installs require auxiliary files to be placed in a |
| 111 | + ``build/__editable__.*`` directory (relative to your project root). |
| 112 | + |
| 113 | + Please be careful to not remove this directory while testing your project, |
| 114 | + otherwise your editable installation may be compromised. |
| 115 | + |
| 116 | + You can remove the ``build/__editable__.*`` directory after uninstalling. |
| 117 | + |
| 118 | + |
| 119 | +.. note:: |
| 120 | + .. versionadded:: v64.0.0 |
| 121 | + Added new *strict* mode for editable installations. |
| 122 | + The exact details of how this mode is implemented may vary. |
| 123 | + |
| 124 | + |
| 125 | +Limitations |
| 126 | +----------- |
| 127 | + |
| 128 | +- The *editable* term is used to refer only to Python modules |
| 129 | + inside the package directories. Non-Python files, external (data) files, |
| 130 | + executable script files, binary extensions, headers and metadata may be |
| 131 | + exposed as a *snapshot* of the version they were at the moment of the |
| 132 | + installation. |
| 133 | +- Adding new dependencies, entry-points or changing your project's metadata |
| 134 | + require a fresh "editable" re-installation. |
| 135 | +- Console scripts and GUI scripts **MUST** be specified via :doc:`entry-points |
| 136 | + </userguide/entry_point>` to work properly. |
| 137 | +- *Strict* editable installs require the file system to support |
| 138 | + either :wiki:`symbolic <symbolic link>` or :wiki:`hard links <hard link>`. |
| 139 | + This installation mode might also generate auxiliary files under the project directory. |
| 140 | +- There is *no guarantee* that the editable installation will be performed |
| 141 | + using a specific technique. Depending on each project, ``setuptools`` may |
| 142 | + select a different approach to ensure the package is importable at runtime. |
| 143 | +- There is *no guarantee* that files outside the top-level package directory |
| 144 | + will be accessible after an editable install. |
| 145 | +- There is *no guarantee* that attributes like ``__path__`` or ``__file__`` |
| 146 | + will correspond to the exact location of the original files (e.g., |
| 147 | + ``setuptools`` might employ file links to perform the editable installation). |
| 148 | + Users are encouraged to use tools like :mod:`importlib.resources` or |
| 149 | + :mod:`importlib.metadata` when trying to access package files directly. |
| 150 | +- Editable installations may not work with |
| 151 | + :doc:`namespaces created with pkgutil or pkg_resouces |
| 152 | + <PyPUG:guides/packaging-namespace-packages>`. |
| 153 | + Please use :pep:`420`-style implicit namespaces [#namespaces]_. |
| 154 | +- Support for :pep:`420`-style implicit namespace packages for |
| 155 | + projects structured using :ref:`flat-layout` is still **experimental**. |
| 156 | + If you experience problems, you can try converting your package structure |
| 157 | + to the :ref:`src-layout`. |
| 158 | + |
| 159 | +.. attention:: |
| 160 | + Editable installs are **not a perfect replacement for regular installs** |
| 161 | + in a test environment. When in doubt, please test your projects as |
| 162 | + installed via a regular wheel. There are tools in the Python ecosystem, |
| 163 | + like :pypi:`tox` or :pypi:`nox`, that can help you with that |
| 164 | + (when used with appropriate configuration). |
| 165 | + |
| 166 | + |
| 167 | +Legacy Behavior |
| 168 | +--------------- |
| 169 | + |
| 170 | +If your project is not compatible with the new "editable installs" or you wish |
| 171 | +to replicate the legacy behavior, for the time being you can also perform the |
| 172 | +installation in the ``compat`` mode: |
| 173 | + |
| 174 | +.. code-block:: bash |
| 175 | +
|
| 176 | + pip install -e . --config-settings editable_mode=compat |
| 177 | +
|
| 178 | +This installation mode will try to emulate how ``python setup.py develop`` |
| 179 | +works (still within the context of :pep:`660`). |
| 180 | + |
| 181 | +.. warning:: |
| 182 | + The ``compat`` mode is *transitional* and will be removed in |
| 183 | + future versions of ``setuptools``, it exists only to help during the |
| 184 | + migration period. |
| 185 | + Also note that support for this mode is limited: |
| 186 | + it is safe to assume that the ``compat`` mode is offered "as is", and |
| 187 | + improvements are unlikely to be implemented. |
| 188 | + Users are encouraged to try out the new editable installation techniques |
| 189 | + and make the necessary adaptations. |
| 190 | + |
| 191 | +If the ``compat`` mode does not work for you, you can also disable the |
| 192 | +:pep:`editable install <660>` hooks in ``setuptools`` by setting an environment |
| 193 | +variable: |
| 194 | + |
| 195 | +.. code-block:: |
| 196 | +
|
| 197 | + SETUPTOOLS_USE_FEATURE="legacy-editable" |
| 198 | +
|
| 199 | +This *may* cause the installer (e.g. ``pip``) to effectively run the "legacy" |
| 200 | +installation command: ``python setup.py develop`` [#installer]_. |
| 201 | + |
| 202 | + |
| 203 | +How editable installations work? |
| 204 | +-------------------------------- |
| 205 | + |
| 206 | +*Advanced topic* |
| 207 | + |
| 208 | +There are many techniques that can be used to expose packages under development |
| 209 | +in such a way that they are available as if they were installed. |
| 210 | +Depending on the project file structure and the selected mode, ``setuptools`` |
| 211 | +will choose one of these approaches for the editable installation [#criteria]_. |
| 212 | + |
| 213 | +A non-exhaustive list of implementation mechanisms is presented below. |
| 214 | +More information is available on the text of :pep:`PEP 660 <660#what-to-put-in-the-wheel>`. |
| 215 | + |
| 216 | +- A static ``.pth`` file [#static_pth]_ can be added to one of the directories |
| 217 | + listed in :func:`site.getsitepackages` or :func:`site.getusersitepackages` to |
| 218 | + extend :obj:`sys.path`. |
| 219 | +- A directory containing a *farm of file links* that mimic the |
| 220 | + project structure and point to the original files can be employed. |
| 221 | + This directory can then be added to :obj:`sys.path` using a static ``.pth`` file. |
| 222 | +- A dynamic ``.pth`` file [#dynamic_pth]_ can also be used to install an |
| 223 | + "import :term:`finder`" (:obj:`~importlib.abc.MetaPathFinder` or |
| 224 | + :obj:`~importlib.abc.PathEntryFinder`) that will hook into Python's |
| 225 | + :doc:`import system <python:reference/import>` machinery. |
| 226 | + |
| 227 | +.. attention:: |
| 228 | + ``Setuptools`` offers **no guarantee** of which technique will be used to |
| 229 | + perform an editable installation. This will vary from project to project |
| 230 | + and may change depending on the specific version of ``setuptools`` being |
| 231 | + used. |
| 232 | + |
| 233 | + |
| 234 | +---- |
| 235 | + |
| 236 | +.. rubric:: Notes |
| 237 | + |
| 238 | +.. [#namespaces] |
| 239 | + You *may* be able to use *strict* editable installations with namespace |
| 240 | + packages created with ``pkgutil`` or ``pkg_namespaces``, however this is not |
| 241 | + officially supported. |
| 242 | +
|
| 243 | +.. [#installer] |
| 244 | + For this workaround to work, the installer tool needs to support legacy |
| 245 | + editable installations. (Future versions of ``pip``, for example, may drop |
| 246 | + support for this feature). |
| 247 | +
|
| 248 | +.. [#criteria] |
| 249 | + ``setuptools`` strives to find a balance between allowing the user to see |
| 250 | + the effects of project files being edited while still trying to keep the |
| 251 | + editable installation as similar as possible to a regular installation. |
| 252 | +
|
| 253 | +.. [#static_pth] |
| 254 | + i.e., a ``.pth`` file where each line correspond to a path that should be |
| 255 | + added to :obj:`sys.path`. See :mod:`Site-specific configuration hook <site>`. |
| 256 | +
|
| 257 | +.. [#dynamic_pth] |
| 258 | + i.e., a ``.pth`` file that starts where each line starts with an ``import`` |
| 259 | + statement and executes arbitrary Python code. See :mod:`Site-specific |
| 260 | + configuration hook <site>`. |
0 commit comments