PEP 517: remove prepare_wheel_metadata references (#311)

- replace with prepare_metadata_for_build_wheel where appropriate
- update the API evolution example to be based on build_sdist
  rather than prepare_wheel_metadata
- also clarified the frontend example code covering one way to
  handle prepare_metadata_for_build_wheel being optional
This commit is contained in:
Nick Coghlan 2017-07-20 22:12:48 +10:00 committed by GitHub
parent 1a92d6ea0d
commit 83ae4a58a6
1 changed files with 39 additions and 34 deletions

View File

@ -181,18 +181,18 @@ Must build a .whl file, and place it in the specified ``wheel_directory``. It
must return the basename (not the full path) of the ``.whl`` file it creates,
as a unicode string.
If the build frontend has previously called ``prepare_wheel_metadata`` and
depends on the wheel resulting from this call to have metadata
If the build frontend has previously called ``prepare_metadata_for_build_wheel``
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
``.dist-info`` directory as the ``metadata_directory`` argument. If this
argument is provided, then ``build_wheel`` MUST produce a wheel with identical
metadata. The directory passed in by the build frontend MUST be
identical to the directory created by ``prepare_wheel_metadata``,
identical to the directory created by ``prepare_metadata_for_build_wheel``,
including any unrecognized files it created.
Backends which do not provide the ``prepare_wheel_metadata`` hook may either
silently ignore the ``metadata_directory`` parameter to ``build_wheel``, or
else raise an exception when it is set to anything other than ``None``.
Backends which do not provide the ``prepare_metadata_for_build_wheel`` hook may
either silently ignore the ``metadata_directory`` parameter to ``build_wheel``,
or else raise an exception when it is set to anything other than ``None``.
If ``build_directory`` is not None, it is a unicode string containing the
path to a directory other than the source directory (the working directory where
@ -744,12 +744,13 @@ across the ecosystem.
more powerful options for evolving this specification in the future.
For concreteness, imagine that next year we add a new
``prepare_wheel_metadata2`` hook, which replaces the current
``prepare_wheel_metadata`` hook with something that produces more data, or a
different metadata format. In order to
manage the transition, we want it to be possible for build frontends
to transparently use ``prepare_wheel_metadata2`` when available and fall
back onto ``prepare_wheel_metadata`` otherwise; and we want it to be
``build_sdist_from_vcs`` hook, which provides an alternative to the current
``build_sdist`` hook where the frontend is responsible for passing
version control tracking metadata to backends (including indicating when all
on disk files are tracked), rather than individual backends having to query that
information themselves. In order to manage the transition, we'd want it to be
possible for build frontends to transparently use ``build_sdist_from_vcs`` when
available and fall back onto ``build_sdist`` otherwise; and we'd want it to be
possible for build backends to define both methods, for compatibility
with both old and new build frontends.
@ -767,11 +768,11 @@ achieve. Because ``pip`` controls the code that runs inside the child
process, it can easily write it to do something like::
command, backend, args = parse_command_line_args(...)
if command == "prepare_wheel_metadata":
if hasattr(backend, "prepare_wheel_metadata2"):
backend.prepare_wheel_metadata2(...)
elif hasattr(backend, "prepare_wheel_metadata"):
backend.prepare_wheel_metadata(...)
if command == "build_sdist":
if hasattr(backend, "build_sdist_from_vcs"):
backend.build_sdist_from_vcs(...)
elif hasattr(backend, "build_sdist"):
backend.build_sdist(...)
else:
# error handling
@ -786,28 +787,32 @@ any change can go live, and that any changes will necessarily be
restricted to new releases.
One specific consequence of this is that in this PEP, we're able to
make the ``prepare_wheel_metadata`` command optional. In our design, this
can easily be worked around by a tool like ``pip``, which can put code
in its subprocess runner like::
make the ``prepare_metadata_for_build_wheel`` command optional. In our design,
this can be readily handled by build frontends, which can put code in
their subprocess runner like::
def prepare_wheel_metadata(output_dir, config_settings):
if hasattr(backend, "prepare_wheel_metadata"):
backend.prepare_wheel_metadata(output_dir, config_settings)
def dump_wheel_metadata(backend, output_dir, config_settings):
if hasattr(backend, "prepare_metadata_for_build_wheel"):
backend.prepare_metadata_for_build_wheel(output_dir, config_settings)
else:
backend.build_wheel(output_dir, config_settings)
touch(output_dir / "PIP_ALREADY_BUILT_WHEELS")
unzip_metadata(output_dir/*.whl)
wheel_fname = backend.build_wheel(output_dir, config_settings)
(output_dir / "ALREADY_BUILT_WHEEL").write_text(wheel_fname)
unzip_metadata(output_dir / wheel_fname)
def build_wheel(output_dir, config_settings, metadata_dir):
if os.path.exists(metadata_dir.parent / "PIP_ALREADY_BUILT_WHEELS"):
copy(metadata_dir.parent / *.whl, output_dir)
def ensure_wheel_is_built(backend, output_dir, config_settings, metadata_dir):
already_built = metadata_dir.parent / "ALREADY_BUILT_WHEEL"
if already_built.exists():
wheel_fname = already_built.read_text()
copy(metadata_dir.parent / wheel_fname, output_dir)
else:
backend.build_wheel(output_dir, config_settings, metadata_dir)
and thus expose a totally uniform interface to the rest of ``pip``,
and thus expose a totally uniform interface to the rest of the frontend,
with no extra subprocess calls, no duplicated builds, etc. But
obviously this is the kind of code that you only want to write as part
of a private, within-project interface.
of a private, within-project interface (e.g. the given example assumes that
all filesystem paths are supplied as ``pathlib.Path`` instances, rather than
as plain strings).
(And, of course, making the ``metadata`` command optional is one piece
of lowering the barrier to entry, as discussed above.)