434 lines
34 KiB
HTML
434 lines
34 KiB
HTML
|
||
<!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> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </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 <dholth at gmail.com>, Stéphane Bidoul <stephane.bidoul at gmail.com></dd>
|
||
<dt class="field-even">Sponsor<span class="colon">:</span></dt>
|
||
<dd class="field-even">Paul Moore <p.f.moore at gmail.com></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 project’s 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> |