Skip to content

Commit b875991

Browse files
authored
PEP 660: build_wheel_for_editable (#1944)
1 parent 11debc3 commit b875991

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ pep-0655.rst @gvanrossum
513513
pep-0656.rst @brettcannon
514514
pep-0657.rst @pablogsal @isidentical @ammaraskar
515515
pep-0658.rst @brettcannon
516+
pep-0660.rst @pfmoore
516517
# ...
517518
# pep-0666.txt
518519
# ...

pep-0660.rst

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
PEP: 660
2+
Title: Editable installs for PEP 517 style build backends
3+
Author: Daniel Holth <dholth@gmail.com>, Stéphane Bidoul <stephane.bidoul@gmail.com>
4+
Sponsor: Paul Moore <p.f.moore@gmail.com>
5+
Discussions-To: https://discuss.python.org/t/draft-pep-editable-installs-for-pep-517-style-build-backends/8510
6+
Status: Draft
7+
Type: Standards Track
8+
Content-Type: text/x-rst
9+
Created: 30-Mar-2021
10+
Post-History:
11+
12+
13+
Abstract
14+
========
15+
16+
This document describes a PEP 517 style method for the installation of packages
17+
in editable mode.
18+
19+
Motivation
20+
==========
21+
22+
Python programmers want to be able to develop packages without having to
23+
install (i.e. copy) them into ``site-packages``, for example, by working in a
24+
checkout of the source repository.
25+
26+
While this can be done by adding the relevant source directories to
27+
``PYTHONPATH``, ``setuptools`` provides the ``setup.py develop`` mechanism that
28+
makes the process easier, and also installs dependencies and entry points such
29+
as console scripts. ``pip`` exposes this mechanism via its ``pip install
30+
--editable`` option.
31+
32+
The installation of projects in such a way that the python code being
33+
imported remains in the source directory is known as the *editable*
34+
installation mode.
35+
36+
Now that PEP 517 provides a mechanism to create alternatives to setuptools, and
37+
decouple installation front ends from build backends, we need a new mechanism
38+
to install packages in editable mode.
39+
40+
Rationale
41+
=========
42+
43+
PEP 517 deferred "Editable installs", meaning non-``setup.py``
44+
distributions lacked that feature. The only way to retain ``editable`` installs
45+
for these distributions was to provide a compatible ``setup.py develop``
46+
implementation. By definining an editable hook other build frontends gain
47+
parity with ``setup.py``.
48+
49+
Terminology and goals
50+
=====================
51+
52+
The editable installation mode implies that the source code of the project
53+
being installed is available in a local directory.
54+
55+
Once the project is installed in editable mode, users expect that changes to
56+
the project *python* code in the local source tree become effective without the
57+
need of a new installation step.
58+
59+
Some kind of changes, such as the addition or modification of entry points, or
60+
the addition of new dependencies, require a new installation step to become
61+
effective. These changes are typically made in build backend configuration
62+
files (such as ``pyproject.toml``), so it is consistent with the general user
63+
expectation that *python* source code is imported from the source tree.
64+
65+
The modification of non-python source code such a C extension modules obviously
66+
require a compilation and/or installation step to become effective. The exact
67+
steps to perform will remain specific to the build backend used.
68+
69+
When a project is installed in editable mode, users expect the installation to
70+
behave identically as a regular installation. Depending on the way build
71+
backends implement this specification, some minor differences may be visible
72+
such as the presence of additional files that are in the source tree and would
73+
not be part of a regular install. Build backends are encouraged to document
74+
such potential differences.
75+
76+
The Mechanism
77+
=============
78+
79+
This PEP adds a single optional hook to the PEP 517 backend interface. The hook
80+
is used to build a wheel that, when installed, allows that distribution to be
81+
imported from its source folder.
82+
83+
build_wheel_for_editable
84+
------------------------
85+
86+
::
87+
88+
def build_wheel_for_editable(
89+
wheel_directory,
90+
scheme=scheme,
91+
config_settings=None):
92+
...
93+
94+
``scheme``: a dictionary of installation categories ``{ 'purelib':
95+
'/home/py/.../site-packages', 'platlib': '...'}``. This makes it possible to
96+
use relative paths to the source code, which might help the interpreter find
97+
the package after the root path changes with ``chroot`` or similar.
98+
99+
Must build a ``.whl`` file, and place it in the specified ``wheel_directory``.
100+
It must return the basename (not the full path) of the .whl file it creates, as
101+
a unicode string.
102+
103+
May do an in-place build of the distribution as a side effect so that any
104+
extension modules or other built artifacts are ready to be used.
105+
106+
The .whl file must comply with the Wheel binary file format specification (PEP
107+
427). In particular it must contain a compliant .dist-info directory.
108+
Metadata must be identical as the one that would have been produced by
109+
``build_wheel`` or ``prepare_metadata_for_build_wheel``, except for
110+
``Requires-Dist`` which may differ slightly as explained below.
111+
112+
Build-backends must produce wheels that have the same dependencies
113+
(``Requires-Dist`` metadata) as wheels produced by the ``build_wheel`` hook,
114+
with the exception that they can add dependencies necessary for their editable
115+
mechanism to function at runtime (such as `editables`_).
116+
117+
The filename for the “editable” wheel needs to be PEP 427 compliant too. It
118+
does not need to use the same tags as ``build_wheel`` but it must be tagged as
119+
compatible with the system.
120+
121+
An “editable” wheel uses the wheel format not for distribution but as ephemeral
122+
communication between the build system and the front end. This avoids having
123+
the build backend install anything directly. This wheel must not be exposed
124+
to end users, nor cached, nor distributed.
125+
126+
get_requires_for_build_wheel_for_editable
127+
-----------------------------------------
128+
129+
::
130+
131+
def get_requires_for_build_wheel_for_editable(config_settings=None):
132+
...
133+
134+
This hook MUST return an additional list of strings containing PEP 508
135+
dependency specifications, above and beyond those specified in the
136+
``pyproject.toml`` file, to be installed when calling the
137+
``build_wheel_for_editable`` hooks.
138+
139+
If not defined, the default implementation is equivalent to ``return []``.
140+
141+
142+
What to put in the wheel
143+
------------------------
144+
145+
Build backends may use different techniques to achive the goals of an editable
146+
install. This section provides examples and is not normative.
147+
148+
* Build backends may choose to place a ``.pth`` file at the root of the ``.whl`` file,
149+
containing the root directory of the source tree. This approach is simple but
150+
not very precise, although it may be considered good enough (especially when
151+
using the ``src`` layout) and is similar to what ``setup.py develop``
152+
currently does.
153+
* The `editables`_ library shows how to build proxy modules that
154+
provide a high quality editable installation. It accepts a list of modules
155+
to include, and hide. When imported, these proxy modules replace themselves
156+
with the code from the source tree. Path-based methods make all scripts under
157+
a path importable, often including the project's own ``setup.py`` and other
158+
scripts that would not be part of a normal installation. The proxy strategy
159+
can achieve a higher level of fidelity than path-based methods.
160+
161+
Frontend requirements
162+
---------------------
163+
164+
Frontends must install editable wheels in the same way as regular wheels.
165+
This also means uninstallation of editables does not require any special treatment.
166+
167+
Frontends must create a ``direct_url.json`` file in the ``.dist-info``
168+
directory of the installed distribution, in compliance with PEP 610. The
169+
``url`` value must be a ``file://`` url pointing to the project directory
170+
(i.e. the directory containing ``pyproject.toml``), and the ``dir_info`` value
171+
must be ``{'editable': true}``.
172+
173+
Frontends must execute ``get_requires_for_build_wheel_for_editable`` hooks in
174+
an environment which contains the bootstrap requirements specified in the
175+
``pyproject.toml`` file.
176+
177+
Frontends must execute the ``build_wheel_for_editable`` hook in an environment
178+
which contains the bootstrap requirements from ``pyproject.toml`` and those
179+
specified by the ``get_requires_for_build_wheel_for_editable`` hook.
180+
181+
Frontends must not rely on the ``prepare_metadata_for_build_wheel`` hook when
182+
installing in editable mode. They must use ``build_wheel_for_editable`` and
183+
inspect the resulting wheel.
184+
185+
Frontends must not expose the wheel obtained from ``build_wheel_for_editable``
186+
to end users. The wheel must be discarded after installation and must not be
187+
cached nor distributed.
188+
189+
Rejected ideas
190+
==============
191+
192+
The ideas of having build backends append or modify the local version
193+
identifier to include the ``editable`` string has been rejected because it
194+
would not satisfy ``==`` version speicifier that include the local version
195+
identifier. In other workds ``pkg==1.0+local`` is not satisfied by version
196+
``1.0+local.editable``.
197+
198+
References
199+
==========
200+
201+
.. _`editables`: https://pypi.org/project/editables/
202+
203+
Copyright
204+
=========
205+
206+
This document is placed in the public domain or under the
207+
CC0-1.0-Universal license, whichever is more permissive.
208+
209+
210+
211+
..
212+
Local Variables:
213+
mode: indented-text
214+
indent-tabs-mode: nil
215+
sentence-end-double-space: t
216+
fill-column: 70
217+
coding: utf-8
218+
End:

0 commit comments

Comments
 (0)