python-peps/pep-0660/index.html

434 lines
34 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="light dark">
<title>PEP 660 Editable installs for pyproject.toml based builds (wheel based) | peps.python.org</title>
<link rel="shortcut icon" href="../_static/py.png">
<link rel="canonical" href="https://peps.python.org/pep-0660/">
<link rel="stylesheet" href="../_static/style.css" type="text/css">
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
<meta property="og:title" content='PEP 660 Editable installs for pyproject.toml based builds (wheel based) | peps.python.org'>
<meta property="og:description" content="This document describes a PEP 517 style method for the installation of packages in editable mode.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://peps.python.org/pep-0660/">
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
<meta property="og:image:alt" content="Python PEPs">
<meta property="og:image:width" content="200">
<meta property="og:image:height" content="200">
<meta name="description" content="This document describes a PEP 517 style method for the installation of packages in editable mode.">
<meta name="theme-color" content="#3776ab">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
<title>Following system colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="9"></circle>
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
<title>Selected dark colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
<title>Selected light colour scheme</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
</svg>
<script>
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
</script>
<section id="pep-page-section">
<header>
<h1>Python Enhancement Proposals</h1>
<ul class="breadcrumbs">
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </li>
<li>PEP 660</li>
</ul>
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
</button>
</header>
<article>
<section id="pep-content">
<h1 class="page-title">PEP 660 Editable installs for pyproject.toml based builds (wheel based)</h1>
<dl class="rfc2822 field-list simple">
<dt class="field-odd">Author<span class="colon">:</span></dt>
<dd class="field-odd">Daniel Holth &lt;dholth&#32;&#97;t&#32;gmail.com&gt;, Stéphane Bidoul &lt;stephane.bidoul&#32;&#97;t&#32;gmail.com&gt;</dd>
<dt class="field-even">Sponsor<span class="colon">:</span></dt>
<dd class="field-even">Paul Moore &lt;p.f.moore&#32;&#97;t&#32;gmail.com&gt;</dd>
<dt class="field-odd">Discussions-To<span class="colon">:</span></dt>
<dd class="field-odd"><a class="reference external" href="https://discuss.python.org/t/draft-pep-editable-installs-for-pep-517-style-build-backends/8510">Discourse thread</a></dd>
<dt class="field-even">Status<span class="colon">:</span></dt>
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
<dt class="field-odd">Type<span class="colon">:</span></dt>
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
<dt class="field-even">Topic<span class="colon">:</span></dt>
<dd class="field-even"><a class="reference external" href="../topic/packaging/">Packaging</a></dd>
<dt class="field-odd">Created<span class="colon">:</span></dt>
<dd class="field-odd">30-Mar-2021</dd>
<dt class="field-even">Post-History<span class="colon">:</span></dt>
<dd class="field-even"><p></p></dd>
<dt class="field-odd">Resolution<span class="colon">:</span></dt>
<dd class="field-odd"><a class="reference external" href="https://discuss.python.org/t/pronouncement-on-peps-660-and-662-editable-installs/9450">Discourse thread</a></dd>
</dl>
<hr class="docutils" />
<section id="contents">
<details><summary>Table of Contents</summary><ul class="simple">
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#motivation">Motivation</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#terminology-and-goals">Terminology and goals</a></li>
<li><a class="reference internal" href="#the-mechanism">The Mechanism</a><ul>
<li><a class="reference internal" href="#build-editable">build_editable</a></li>
<li><a class="reference internal" href="#get-requires-for-build-editable">get_requires_for_build_editable</a></li>
<li><a class="reference internal" href="#prepare-metadata-for-build-editable">prepare_metadata_for_build_editable</a></li>
<li><a class="reference internal" href="#what-to-put-in-the-wheel">What to put in the wheel</a></li>
<li><a class="reference internal" href="#frontend-requirements">Frontend requirements</a></li>
</ul>
</li>
<li><a class="reference internal" href="#limitations">Limitations</a></li>
<li><a class="reference internal" href="#prototypes">Prototypes</a></li>
<li><a class="reference internal" href="#rejected-ideas">Rejected ideas</a><ul>
<li><a class="reference internal" href="#editable-local-version-identifier"><code class="docutils literal notranslate"><span class="pre">editable</span></code> local version identifier</a></li>
<li><a class="reference internal" href="#virtual-wheel">Virtual wheel</a></li>
<li><a class="reference internal" href="#unpacked-wheel">Unpacked wheel</a></li>
</ul>
</li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
</details></section>
<section id="abstract">
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
<p>This document describes a <a class="pep reference internal" href="../pep-0517/" title="PEP 517 A build-system independent format for source trees">PEP 517</a> style method for the installation of packages
in editable mode.</p>
</section>
<section id="motivation">
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
<p>Python programmers want to be able to develop packages without having to
install (i.e. copy) them into <code class="docutils literal notranslate"><span class="pre">site-packages</span></code>, for example, by working in a
checkout of the source repository.</p>
<p>While this can be done by adding the relevant source directories to
<code class="docutils literal notranslate"><span class="pre">PYTHONPATH</span></code>, <code class="docutils literal notranslate"><span class="pre">setuptools</span></code> provides the <code class="docutils literal notranslate"><span class="pre">setup.py</span> <span class="pre">develop</span></code> mechanism that
makes the process easier, and also installs dependencies and entry points such
as console scripts. <code class="docutils literal notranslate"><span class="pre">pip</span></code> exposes this mechanism via its <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span>
<span class="pre">--editable</span></code> option.</p>
<p>The installation of projects in such a way that the python code being
imported remains in the source directory is known as the <em>editable</em>
installation mode.</p>
<p>Now that <a class="pep reference internal" href="../pep-0517/" title="PEP 517 A build-system independent format for source trees">PEP 517</a> provides a mechanism to create alternatives to setuptools, and
decouple installation front ends from build backends, we need a new mechanism
to install packages in editable mode.</p>
</section>
<section id="rationale">
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
<p><a class="pep reference internal" href="../pep-0517/" title="PEP 517 A build-system independent format for source trees">PEP 517</a> deferred “Editable installs”, meaning non-<code class="docutils literal notranslate"><span class="pre">setup.py</span></code>
distributions lacked that feature. The only way to retain <code class="docutils literal notranslate"><span class="pre">editable</span></code> installs
for these distributions was to provide a compatible <code class="docutils literal notranslate"><span class="pre">setup.py</span> <span class="pre">develop</span></code>
implementation. By defining an editable hook other build frontends gain
parity with <code class="docutils literal notranslate"><span class="pre">setup.py</span></code>.</p>
</section>
<section id="terminology-and-goals">
<h2><a class="toc-backref" href="#terminology-and-goals" role="doc-backlink">Terminology and goals</a></h2>
<p>The editable installation mode implies that the source code of the project
being installed is available in a local directory.</p>
<p>Once the project is installed in editable mode, users expect that changes to
the project <em>python</em> code in the local source tree become effective without the
need of a new installation step.</p>
<p>Some kind of changes, such as the addition or modification of entry points, or
the addition of new dependencies, require a new installation step to become
effective. These changes are typically made in build backend configuration
files (such as <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code>), so it is consistent with the general user
expectation that <em>python</em> source code is imported from the source tree.</p>
<p>The modification of non-python source code such a C extension modules obviously
require a compilation and/or installation step to become effective. The exact
steps to perform will remain specific to the build backend used.</p>
<p>When a project is installed in editable mode, users expect the installation to
behave identically as a regular installation. In particular the code must be
importable by other code, and metadata must be available to standard mechanisms
such as <code class="docutils literal notranslate"><span class="pre">importlib.metadata</span></code>.</p>
<p>Depending on the way build backends implement this specification, some minor
differences may be visible such as the presence of additional files that are in
the source tree and would not be part of a regular install. Build backends are
encouraged to document such potential differences.</p>
</section>
<section id="the-mechanism">
<h2><a class="toc-backref" href="#the-mechanism" role="doc-backlink">The Mechanism</a></h2>
<p>This PEP adds three optional hooks to the <a class="pep reference internal" href="../pep-0517/" title="PEP 517 A build-system independent format for source trees">PEP 517</a> backend interface. These hooks
are used to build a wheel that, when installed, allows that distribution to be
imported from its source folder.</p>
<section id="build-editable">
<h3><a class="toc-backref" href="#build-editable" role="doc-backlink">build_editable</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">build_editable</span><span class="p">(</span><span class="n">wheel_directory</span><span class="p">,</span> <span class="n">config_settings</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">metadata_directory</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
<p>Must build a <code class="docutils literal notranslate"><span class="pre">.whl</span></code> file, and place it in the specified <code class="docutils literal notranslate"><span class="pre">wheel_directory</span></code>.
It must return the basename (not the full path) of the .whl file it creates, as
a unicode string.</p>
<p>May do an in-place build of the distribution as a side effect so that any
extension modules or other built artifacts are ready to be used.</p>
<p>The .whl file must comply with the Wheel binary file format specification (PEP
427). In particular it must contain a compliant .dist-info directory.
Metadata must be identical as the one that would have been produced by
<code class="docutils literal notranslate"><span class="pre">build_wheel</span></code> or <code class="docutils literal notranslate"><span class="pre">prepare_metadata_for_build_wheel</span></code>, except for
<code class="docutils literal notranslate"><span class="pre">Requires-Dist</span></code> which may differ slightly as explained below.</p>
<p>Build-backends must produce wheels that have the same dependencies
(<code class="docutils literal notranslate"><span class="pre">Requires-Dist</span></code> metadata) as wheels produced by the <code class="docutils literal notranslate"><span class="pre">build_wheel</span></code> hook,
with the exception that they can add dependencies necessary for their editable
mechanism to function at runtime (such as <a class="reference external" href="https://pypi.org/project/editables/">editables</a>).</p>
<p>The filename for the “editable” wheel needs to be <a class="pep reference internal" href="../pep-0427/" title="PEP 427 The Wheel Binary Package Format 1.0">PEP 427</a> compliant too. It
does not need to use the same tags as <code class="docutils literal notranslate"><span class="pre">build_wheel</span></code> but it must be tagged as
compatible with the system.</p>
<p>If the build frontend has previously called <code class="docutils literal notranslate"><span class="pre">prepare_metadata_for_build_editable</span></code>
and depends on the wheel resulting from this call to have metadata
matching this earlier call, then it should provide the path to the created
<code class="docutils literal notranslate"><span class="pre">.dist-info</span></code> directory as the <code class="docutils literal notranslate"><span class="pre">metadata_directory</span></code> argument. If this
argument is provided, then <code class="docutils literal notranslate"><span class="pre">build_editable</span></code> MUST produce a wheel with identical
metadata. The directory passed in by the build frontend MUST be
identical to the directory created by <code class="docutils literal notranslate"><span class="pre">prepare_metadata_for_build_editable</span></code>,
including any unrecognized files it created.</p>
<p>An “editable” wheel uses the wheel format not for distribution but as ephemeral
communication between the build system and the front end. This avoids having
the build backend install anything directly. This wheel must not be exposed
to end users, nor cached, nor distributed.</p>
</section>
<section id="get-requires-for-build-editable">
<h3><a class="toc-backref" href="#get-requires-for-build-editable" role="doc-backlink">get_requires_for_build_editable</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">get_requires_for_build_editable</span><span class="p">(</span><span class="n">config_settings</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
<p>This hook MUST return an additional list of strings containing <a class="pep reference internal" href="../pep-0508/" title="PEP 508 Dependency specification for Python Software Packages">PEP 508</a>
dependency specifications, above and beyond those specified in the
<code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> file, to be installed when calling the
<code class="docutils literal notranslate"><span class="pre">build_editable</span></code> hooks.</p>
<p>If not defined, the default implementation is equivalent to <code class="docutils literal notranslate"><span class="pre">return</span> <span class="pre">[]</span></code>.</p>
</section>
<section id="prepare-metadata-for-build-editable">
<h3><a class="toc-backref" href="#prepare-metadata-for-build-editable" role="doc-backlink">prepare_metadata_for_build_editable</a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">prepare_metadata_for_build_editable</span><span class="p">(</span><span class="n">metadata_directory</span><span class="p">,</span> <span class="n">config_settings</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="o">...</span>
</pre></div>
</div>
<p>Must create a <code class="docutils literal notranslate"><span class="pre">.dist-info</span></code> directory containing wheel metadata
inside the specified <code class="docutils literal notranslate"><span class="pre">metadata_directory</span></code> (i.e., creates a directory
like <code class="docutils literal notranslate"><span class="pre">{metadata_directory}/{package}-{version}.dist-info/</span></code>). This
directory MUST be a valid <code class="docutils literal notranslate"><span class="pre">.dist-info</span></code> directory as defined in the
wheel specification, except that it need not contain <code class="docutils literal notranslate"><span class="pre">RECORD</span></code> or
signatures. The hook MAY also create other files inside this
directory, and a build frontend MUST preserve, but otherwise ignore, such files;
the intention
here is that in cases where the metadata depends on build-time
decisions, the build backend may need to record these decisions in
some convenient format for re-use by the actual wheel-building step.</p>
<p>This must return the basename (not the full path) of the <code class="docutils literal notranslate"><span class="pre">.dist-info</span></code>
directory it creates, as a unicode string.</p>
<p>If a build frontend needs this information and the method is
not defined, it should call <code class="docutils literal notranslate"><span class="pre">build_editable</span></code> and look at the resulting
metadata directly.</p>
</section>
<section id="what-to-put-in-the-wheel">
<h3><a class="toc-backref" href="#what-to-put-in-the-wheel" role="doc-backlink">What to put in the wheel</a></h3>
<p>Build backends must populate the generated wheel with files that when installed will result in an editable install.
Build backends may use different techniques to achieve the goals of an editable
install. This section provides examples and is not normative.</p>
<ul class="simple">
<li>Build backends may choose to place a <code class="docutils literal notranslate"><span class="pre">.pth</span></code> file at the root of the <code class="docutils literal notranslate"><span class="pre">.whl</span></code> file,
containing the root directory of the source tree. This approach is simple but
not very precise, although it may be considered good enough (especially when
using the <code class="docutils literal notranslate"><span class="pre">src</span></code> layout) and is similar to what <code class="docutils literal notranslate"><span class="pre">setup.py</span> <span class="pre">develop</span></code>
currently does.</li>
<li>The <a class="reference external" href="https://pypi.org/project/editables/">editables</a> library shows how to build proxy modules that
provide a high quality editable installation. It accepts a list of modules
to include, and hide. When imported, these proxy modules replace themselves
with the code from the source tree. Path-based methods make all scripts under
a path importable, often including the projects own <code class="docutils literal notranslate"><span class="pre">setup.py</span></code> and other
scripts that would not be part of a normal installation. The proxy strategy
can achieve a higher level of fidelity than path-based methods.</li>
<li>Symbolic links are another useful mechanism to realize editable installs.
Since, at the time this writing, the <code class="docutils literal notranslate"><span class="pre">wheel</span></code> specification does not support
symbolic links, they are not directly usable to set-up symbolic links in the
target environment. It is however possible for the backend to create a
symlink structure in some <code class="docutils literal notranslate"><span class="pre">build</span></code> directory of the source tree, and add
that directory to the python path via a <code class="docutils literal notranslate"><span class="pre">.pth</span></code> file in the “editable”
wheel. If some files linked in this manner depend on python implementation or
version, ABI or platform, care must be taken to generate the link structure
in different directories depending on compatibility tags, so the same project
tree can be installed in editable mode in multiple environments.</li>
</ul>
</section>
<section id="frontend-requirements">
<h3><a class="toc-backref" href="#frontend-requirements" role="doc-backlink">Frontend requirements</a></h3>
<p>Frontends must install “editable” wheels in the same way as regular wheels.
This also means uninstallation of editables does not require any special treatment.</p>
<p>Frontends must create a <code class="docutils literal notranslate"><span class="pre">direct_url.json</span></code> file in the <code class="docutils literal notranslate"><span class="pre">.dist-info</span></code>
directory of the installed distribution, in compliance with <a class="pep reference internal" href="../pep-0610/" title="PEP 610 Recording the Direct URL Origin of installed distributions">PEP 610</a>. The
<code class="docutils literal notranslate"><span class="pre">url</span></code> value must be a <code class="docutils literal notranslate"><span class="pre">file://</span></code> url pointing to the project directory
(i.e. the directory containing <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code>), and the <code class="docutils literal notranslate"><span class="pre">dir_info</span></code> value
must be <code class="docutils literal notranslate"><span class="pre">{'editable':</span> <span class="pre">true}</span></code>.</p>
<p>Frontends must execute <code class="docutils literal notranslate"><span class="pre">get_requires_for_build_editable</span></code> hooks in
an environment which contains the bootstrap requirements specified in the
<code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> file.</p>
<p>Frontends must execute the <code class="docutils literal notranslate"><span class="pre">prepare_metadata_for_build_editable</span></code> and
<code class="docutils literal notranslate"><span class="pre">build_editable</span></code> hooks in an environment which contains the bootstrap
requirements from <code class="docutils literal notranslate"><span class="pre">pyproject.toml</span></code> and those specified by the
<code class="docutils literal notranslate"><span class="pre">get_requires_for_build_editable</span></code> hook.</p>
<p>Frontends must not expose the wheel obtained from <code class="docutils literal notranslate"><span class="pre">build_editable</span></code>
to end users. The wheel must be discarded after installation and must not be
cached nor distributed.</p>
</section>
</section>
<section id="limitations">
<h2><a class="toc-backref" href="#limitations" role="doc-backlink">Limitations</a></h2>
<p>With regard to the wheel <code class="docutils literal notranslate"><span class="pre">.data</span></code> directory, this PEP focuses on making the
<code class="docutils literal notranslate"><span class="pre">purelib</span></code> and <code class="docutils literal notranslate"><span class="pre">platlib</span></code> categories (installed into site-packages)
“editable”. It does not make special provision for the other categories such as
<code class="docutils literal notranslate"><span class="pre">headers</span></code>, <code class="docutils literal notranslate"><span class="pre">data</span></code> and <code class="docutils literal notranslate"><span class="pre">scripts</span></code>. Package authors are encouraged to use
<code class="docutils literal notranslate"><span class="pre">console_scripts</span></code>, make their <code class="docutils literal notranslate"><span class="pre">scripts</span></code> tiny wrappers around library
functionality, or manage these from the source checkout during development.</p>
</section>
<section id="prototypes">
<h2><a class="toc-backref" href="#prototypes" role="doc-backlink">Prototypes</a></h2>
<p>At the time of writing this PEP, several prototype implementations are
available in various frontends and backends. We provide links below to
illustrate possible approaches.</p>
<p>Frontends:</p>
<ul class="simple">
<li>pip (<a class="reference external" href="https://github.com/pypa/pip/pull/8212">pull request</a>)</li>
</ul>
<p>Build backends:</p>
<ul class="simple">
<li>enscons (<a class="reference external" href="https://github.com/dholth/enscons/pull/9">pull request 1</a>,
<a class="reference external" href="https://github.com/dholth/enscons/pull/21">pull request 2</a>)</li>
<li>flit (<a class="reference external" href="https://github.com/takluyver/flit/pull/400">pull request</a>)</li>
<li>hatchling (<a class="reference external" href="https://pypi.org/project/hatchling/#files">sdist</a>)</li>
<li>pdm (<a class="reference external" href="https://github.com/pdm-project/pdm-pep517/pull/36">pull request</a>)</li>
<li>setuptools (<a class="reference external" href="https://github.com/dholth/setuptools_pep660">setuptools_pep660 repository</a>)</li>
</ul>
</section>
<section id="rejected-ideas">
<h2><a class="toc-backref" href="#rejected-ideas" role="doc-backlink">Rejected ideas</a></h2>
<section id="editable-local-version-identifier">
<h3><a class="toc-backref" href="#editable-local-version-identifier" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">editable</span></code> local version identifier</a></h3>
<p>The ideas of having build backends append or modify the local version
identifier to include the <code class="docutils literal notranslate"><span class="pre">editable</span></code> string has been rejected because it
would not satisfy <code class="docutils literal notranslate"><span class="pre">==</span></code> version speicifier that include the local version
identifier. In other words <code class="docutils literal notranslate"><span class="pre">pkg==1.0+local</span></code> is not satisfied by version
<code class="docutils literal notranslate"><span class="pre">1.0+local.editable</span></code>.</p>
</section>
<section id="virtual-wheel">
<h3><a class="toc-backref" href="#virtual-wheel" role="doc-backlink">Virtual wheel</a></h3>
<p>Another approach was proposed in <a class="pep reference internal" href="../pep-0662/" title="PEP 662 Editable installs via virtual wheels">PEP 662</a>, where
the build backend returns a mapping from source files and directories to the
installed layout. It is then up to the installer frontend to realize the
editable installation by whatever means it deems adequate for its users.</p>
<p>In terms of capabilities, both proposals provide the core “editable” feature.</p>
<p>The key difference is that <a class="pep reference internal" href="../pep-0662/" title="PEP 662 Editable installs via virtual wheels">PEP 662</a> leaves it to the frontend to decide how the
editable installation will be realized, while with this PEP, the choice must be
made by the backend. Both approaches can in principle provide several editable
installation methods for a given project, and let the developer choose one at
install time.</p>
<p>At the time of writing this PEP, it is clear that the community has a wide
range of theoretical and practical expectations about editable installs. The
reality is that the only one there is wide experience with is path insertion
via .pth (i.e. what setup.py develop does).</p>
<p>We believe that <a class="pep reference internal" href="../pep-0660/" title="PEP 660 Editable installs for pyproject.toml based builds (wheel based)">PEP 660</a> better addresses these “unknown unknowns” today in the
most reliable way, by letting project authors select the backend or implement
the method that provides the editable mechanism that best suit their
requirements, and test it works correctly. Since the frontend has no latitude
in <em>how</em> to install the “editable” wheel, in case of issue, there is only one
place to investigate: the build backend.</p>
<p>With <a class="pep reference internal" href="../pep-0662/" title="PEP 662 Editable installs via virtual wheels">PEP 662</a>, issues need to be investigated in the frontend,
the backend and possiblty the specification. There is also a high probability
that different frontends, implementing the specification in different ways,
will produce installations that behave differently than project authors
intended, creating confusion, or worse, projects that only work with specific
frontends or IDEs.</p>
</section>
<section id="unpacked-wheel">
<h3><a class="toc-backref" href="#unpacked-wheel" role="doc-backlink">Unpacked wheel</a></h3>
<p>A <a class="reference external" href="https://github.com/pypa/pip/pull/8154/files">prototype</a> was made that
created an unpacked wheel in a temporary directory, to be copied to the target
environment by the frontend. This approach was not pursued because a wheel
archive is easy to create for the backend, and using a wheel as communication
mechanism is a better fit with the <a class="pep reference internal" href="../pep-0517/" title="PEP 517 A build-system independent format for source trees">PEP 517</a> philosophy, and therefore keeps
things simpler for the frontend.</p>
</section>
</section>
<section id="copyright">
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
<p>This document is placed in the public domain or under the
CC0-1.0-Universal license, whichever is more permissive.</p>
</section>
</section>
<hr class="docutils" />
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0660.rst">https://github.com/python/peps/blob/main/peps/pep-0660.rst</a></p>
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0660.rst">2023-09-09 17:39:29 GMT</a></p>
</article>
<nav id="pep-sidebar">
<h2>Contents</h2>
<ul>
<li><a class="reference internal" href="#abstract">Abstract</a></li>
<li><a class="reference internal" href="#motivation">Motivation</a></li>
<li><a class="reference internal" href="#rationale">Rationale</a></li>
<li><a class="reference internal" href="#terminology-and-goals">Terminology and goals</a></li>
<li><a class="reference internal" href="#the-mechanism">The Mechanism</a><ul>
<li><a class="reference internal" href="#build-editable">build_editable</a></li>
<li><a class="reference internal" href="#get-requires-for-build-editable">get_requires_for_build_editable</a></li>
<li><a class="reference internal" href="#prepare-metadata-for-build-editable">prepare_metadata_for_build_editable</a></li>
<li><a class="reference internal" href="#what-to-put-in-the-wheel">What to put in the wheel</a></li>
<li><a class="reference internal" href="#frontend-requirements">Frontend requirements</a></li>
</ul>
</li>
<li><a class="reference internal" href="#limitations">Limitations</a></li>
<li><a class="reference internal" href="#prototypes">Prototypes</a></li>
<li><a class="reference internal" href="#rejected-ideas">Rejected ideas</a><ul>
<li><a class="reference internal" href="#editable-local-version-identifier"><code class="docutils literal notranslate"><span class="pre">editable</span></code> local version identifier</a></li>
<li><a class="reference internal" href="#virtual-wheel">Virtual wheel</a></li>
<li><a class="reference internal" href="#unpacked-wheel">Unpacked wheel</a></li>
</ul>
</li>
<li><a class="reference internal" href="#copyright">Copyright</a></li>
</ul>
<br>
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0660.rst">Page Source (GitHub)</a>
</nav>
</section>
<script src="../_static/colour_scheme.js"></script>
<script src="../_static/wrap_tables.js"></script>
<script src="../_static/sticky_banner.js"></script>
</body>
</html>