From 83ae4a58a654164ffb34619e0aa23a48285ea7e4 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Thu, 20 Jul 2017 22:12:48 +1000 Subject: [PATCH] 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 --- pep-0517.txt | 73 ++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/pep-0517.txt b/pep-0517.txt index 980fbbebf..92521cd0e 100644 --- a/pep-0517.txt +++ b/pep-0517.txt @@ -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) - else: - backend.build_wheel(output_dir, config_settings) - touch(output_dir / "PIP_ALREADY_BUILT_WHEELS") - unzip_metadata(output_dir/*.whl) + 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: + 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) - else: - backend.build_wheel(output_dir, config_settings, metadata_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.)