This document describes aPEP 517 style method for the installation of packagesin editable mode.
Python programmers want to be able to develop packages without having toinstall (i.e. copy) them intosite-packages, for example, by working in acheckout of the source repository.
While this can be done by adding the relevant source directories toPYTHONPATH,setuptools provides thesetup.pydevelop mechanism thatmakes the process easier, and also installs dependencies and entry points suchas console scripts.pip exposes this mechanism via itspipinstall--editable option.
The installation of projects in such a way that the python code beingimported remains in the source directory is known as theeditableinstallation mode.
Now thatPEP 517 provides a mechanism to create alternatives to setuptools, anddecouple installation front ends from build backends, we need a new mechanismto install packages in editable mode.
PEP 517 deferred “Editable installs”, meaning non-setup.pydistributions lacked that feature. The only way to retaineditable installsfor these distributions was to provide a compatiblesetup.pydevelopimplementation. By defining an editable hook other build frontends gainparity withsetup.py.
The editable installation mode implies that the source code of the projectbeing installed is available in a local directory.
Once the project is installed in editable mode, users expect that changes tothe projectpython code in the local source tree become effective without theneed of a new installation step.
Some kind of changes, such as the addition or modification of entry points, orthe addition of new dependencies, require a new installation step to becomeeffective. These changes are typically made in build backend configurationfiles (such aspyproject.toml), so it is consistent with the general userexpectation thatpython source code is imported from the source tree.
The modification of non-python source code such a C extension modules obviouslyrequire a compilation and/or installation step to become effective. The exactsteps to perform will remain specific to the build backend used.
When a project is installed in editable mode, users expect the installation tobehave identically as a regular installation. In particular the code must beimportable by other code, and metadata must be available to standard mechanismssuch asimportlib.metadata.
Depending on the way build backends implement this specification, some minordifferences may be visible such as the presence of additional files that are inthe source tree and would not be part of a regular install. Build backends areencouraged to document such potential differences.
This PEP adds three optional hooks to thePEP 517 backend interface. These hooksare used to build a wheel that, when installed, allows that distribution to beimported from its source folder.
defbuild_editable(wheel_directory,config_settings=None,metadata_directory=None):...
Must build a.whl file, and place it in the specifiedwheel_directory.It must return the basename (not the full path) of the .whl file it creates, asa unicode string.
May do an in-place build of the distribution as a side effect so that anyextension modules or other built artifacts are ready to be used.
The .whl file must comply with the Wheel binary file format specification (PEP427). In particular it must contain a compliant .dist-info directory.Metadata must be identical as the one that would have been produced bybuild_wheel orprepare_metadata_for_build_wheel, except forRequires-Dist which may differ slightly as explained below.
Build-backends must produce wheels that have the same dependencies(Requires-Dist metadata) as wheels produced by thebuild_wheel hook,with the exception that they can add dependencies necessary for their editablemechanism to function at runtime (such aseditables).
The filename for the “editable” wheel needs to bePEP 427 compliant too. Itdoes not need to use the same tags asbuild_wheel but it must be tagged ascompatible with the system.
If the build frontend has previously calledprepare_metadata_for_build_editableand depends on the wheel resulting from this call to have metadatamatching this earlier call, then it should provide the path to the created.dist-info directory as themetadata_directory argument. If thisargument is provided, thenbuild_editable MUST produce a wheel with identicalmetadata. The directory passed in by the build frontend MUST beidentical to the directory created byprepare_metadata_for_build_editable,including any unrecognized files it created.
An “editable” wheel uses the wheel format not for distribution but as ephemeralcommunication between the build system and the front end. This avoids havingthe build backend install anything directly. This wheel must not be exposedto end users, nor cached, nor distributed.
defget_requires_for_build_editable(config_settings=None):...
This hook MUST return an additional list of strings containingPEP 508dependency specifications, above and beyond those specified in thepyproject.toml file, to be installed when calling thebuild_editable hooks.
If not defined, the default implementation is equivalent toreturn[].
defprepare_metadata_for_build_editable(metadata_directory,config_settings=None):...
Must create a.dist-info directory containing wheel metadatainside the specifiedmetadata_directory (i.e., creates a directorylike{metadata_directory}/{package}-{version}.dist-info/). Thisdirectory MUST be a valid.dist-info directory as defined in thewheel specification, except that it need not containRECORD orsignatures. The hook MAY also create other files inside thisdirectory, and a build frontend MUST preserve, but otherwise ignore, such files;the intentionhere is that in cases where the metadata depends on build-timedecisions, the build backend may need to record these decisions insome convenient format for re-use by the actual wheel-building step.
This must return the basename (not the full path) of the.dist-infodirectory it creates, as a unicode string.
If a build frontend needs this information and the method isnot defined, it should callbuild_editable and look at the resultingmetadata directly.
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 editableinstall. This section provides examples and is not normative.
.pth file at the root of the.whl file,containing the root directory of the source tree. This approach is simple butnot very precise, although it may be considered good enough (especially whenusing thesrc layout) and is similar to whatsetup.pydevelopcurrently does.setup.py and otherscripts that would not be part of a normal installation. The proxy strategycan achieve a higher level of fidelity than path-based methods.wheel specification does not supportsymbolic links, they are not directly usable to set-up symbolic links in thetarget environment. It is however possible for the backend to create asymlink structure in somebuild directory of the source tree, and addthat directory to the python path via a.pth file in the “editable”wheel. If some files linked in this manner depend on python implementation orversion, ABI or platform, care must be taken to generate the link structurein different directories depending on compatibility tags, so the same projecttree can be installed in editable mode in multiple environments.Frontends must install “editable” wheels in the same way as regular wheels.This also means uninstallation of editables does not require any special treatment.
Frontends must create adirect_url.json file in the.dist-infodirectory of the installed distribution, in compliance withPEP 610. Theurl value must be afile:// url pointing to the project directory(i.e. the directory containingpyproject.toml), and thedir_info valuemust be{'editable':true}.
Frontends must executeget_requires_for_build_editable hooks inan environment which contains the bootstrap requirements specified in thepyproject.toml file.
Frontends must execute theprepare_metadata_for_build_editable andbuild_editable hooks in an environment which contains the bootstraprequirements frompyproject.toml and those specified by theget_requires_for_build_editable hook.
Frontends must not expose the wheel obtained frombuild_editableto end users. The wheel must be discarded after installation and must not becached nor distributed.
With regard to the wheel.data directory, this PEP focuses on making thepurelib andplatlib categories (installed into site-packages)“editable”. It does not make special provision for the other categories such asheaders,data andscripts. Package authors are encouraged to useconsole_scripts, make theirscripts tiny wrappers around libraryfunctionality, or manage these from the source checkout during development.
At the time of writing this PEP, several prototype implementations areavailable in various frontends and backends. We provide links below toillustrate possible approaches.
Frontends:
Build backends:
editable local version identifierThe ideas of having build backends append or modify the local versionidentifier to include theeditable string has been rejected because itwould not satisfy== version speicifier that include the local versionidentifier. In other wordspkg==1.0+local is not satisfied by version1.0+local.editable.
Another approach was proposed inPEP 662, wherethe build backend returns a mapping from source files and directories to theinstalled layout. It is then up to the installer frontend to realize theeditable installation by whatever means it deems adequate for its users.
In terms of capabilities, both proposals provide the core “editable” feature.
The key difference is thatPEP 662 leaves it to the frontend to decide how theeditable installation will be realized, while with this PEP, the choice must bemade by the backend. Both approaches can in principle provide several editableinstallation methods for a given project, and let the developer choose one atinstall time.
At the time of writing this PEP, it is clear that the community has a widerange of theoretical and practical expectations about editable installs. Thereality is that the only one there is wide experience with is path insertionvia .pth (i.e. what setup.py develop does).
We believe thatPEP 660 better addresses these “unknown unknowns” today in themost reliable way, by letting project authors select the backend or implementthe method that provides the editable mechanism that best suit theirrequirements, and test it works correctly. Since the frontend has no latitudeinhow to install the “editable” wheel, in case of issue, there is only oneplace to investigate: the build backend.
WithPEP 662, issues need to be investigated in the frontend,the backend and possiblty the specification. There is also a high probabilitythat different frontends, implementing the specification in different ways,will produce installations that behave differently than project authorsintended, creating confusion, or worse, projects that only work with specificfrontends or IDEs.
Aprototype was made thatcreated an unpacked wheel in a temporary directory, to be copied to the targetenvironment by the frontend. This approach was not pursued because a wheelarchive is easy to create for the backend, and using a wheel as communicationmechanism is a better fit with thePEP 517 philosophy, and therefore keepsthings simpler for the frontend.
This document is placed in the public domain or under theCC0-1.0-Universal license, whichever is more permissive.
Source:https://github.com/python/peps/blob/main/peps/pep-0660.rst
Last modified:2025-02-01 08:55:40 GMT