PEP 517: update backend example (#310)
- update hook names and signatures - clearly separate sdist building & wheel building - add support for out-of-tree wheel builds - clarify build_wheel spec based on updated example - be explicit that out-of-tree builds should match the results of building via sdist
This commit is contained in:
parent
20c110f591
commit
0189da7b60
112
pep-0517.txt
112
pep-0517.txt
|
@ -190,25 +190,38 @@ 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_wheel_metadata``,
|
||||||
including any unrecognized files it created.
|
including any unrecognized files it created.
|
||||||
|
|
||||||
If build_directory is not None, it is a unicode string containing the
|
Backends which do not provide the ``prepare_wheel_metadata`` hook may either
|
||||||
path to a directory where intermediate build artifacts may be stored.
|
silently ignore the ``metadata_directory`` parameter to ``build_wheel``, or
|
||||||
This may be empty, or it may contain artifacts from a previous build to
|
else raise an exception when it is set to anything other than ``None``.
|
||||||
be used as a cache. The backend is responsible for determining whether
|
|
||||||
any cached artifacts are outdated. When a build_directory is provided,
|
|
||||||
the backend should not create or modify any files in the source
|
|
||||||
directory (the working directory where the hook is called). If the
|
|
||||||
backend cannot reliably avoid modifying the directory it builds from, it
|
|
||||||
should copy any files it needs to build_directory and perform the build
|
|
||||||
there.
|
|
||||||
|
|
||||||
If build_directory is None, the backend may do an 'in place' build which
|
If ``build_directory`` is not None, it is a unicode string containing the
|
||||||
modifies the source directory. The semantics of this are not specified
|
path to a directory other than the source directory (the working directory where
|
||||||
here.
|
the hook is called) where intermediate build artifacts may be stored.
|
||||||
|
|
||||||
Whatever the value of build_directory, the backend may also store intermediates
|
These out-of-tree builds should have the same result as first building an sdist
|
||||||
in other cache locations or temporary directories, which it is responsible for
|
and then building a wheel from that sdist. If the backend cannot otherwise
|
||||||
managing. The presence or absence of any caches should not make a
|
ensure that unexpected files won't end up in the built wheel archive, it should
|
||||||
material difference to the final result of the build.
|
copy any essential input files it needs to ``build_directory`` and perform the
|
||||||
|
build there.
|
||||||
|
|
||||||
|
The provided build directory may be empty, or it may contain artifacts from a
|
||||||
|
previous build to be used as a cache. The backend is responsible for determining
|
||||||
|
whether any cached artifacts are outdated.
|
||||||
|
|
||||||
|
If ``build_directory`` is None, the backend may do an 'in place' build which
|
||||||
|
modifies the source directory and may produce different results from those that
|
||||||
|
would be obtained by exporting an sdist first. The exact semantics of this will
|
||||||
|
depend on the build system in use, and hence are not specified here.
|
||||||
|
|
||||||
|
To guard against frontends that are not fully compliant with this specification,
|
||||||
|
defensively coded backends may treat
|
||||||
|
``os.path.samefile(build_directory, os.getcwd())`` as a request for an in place
|
||||||
|
build.
|
||||||
|
|
||||||
|
Whatever the value of ``build_directory``, the backend may also store
|
||||||
|
intermediate artifacts in other cache locations or temporary directories, which
|
||||||
|
it is responsible for managing. The presence or absence of any caches should not
|
||||||
|
make a material difference to the final result of the build.
|
||||||
|
|
||||||
build_sdist
|
build_sdist
|
||||||
-----------
|
-----------
|
||||||
|
@ -618,16 +631,15 @@ build backend::
|
||||||
# mypackage_custom_build_backend.py
|
# mypackage_custom_build_backend.py
|
||||||
import os.path
|
import os.path
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import shutil
|
||||||
|
|
||||||
def get_build_requires(config_settings, config_directory):
|
SDIST_NAME = "mypackage-0.1"
|
||||||
return ["wheel"]
|
SDIST_FILENAME = SDIST_NAME + ".tar.gz"
|
||||||
|
WHEEL_FILENAME = "mypackage-0.1-py2.py3-none-any.whl"
|
||||||
|
|
||||||
def build_wheel(wheel_directory, config_settings, config_directory=None):
|
#################
|
||||||
from wheel.archive import archive_wheelfile
|
# sdist creation
|
||||||
filename = "mypackage-0.1-py2.py3-none-any"
|
#################
|
||||||
path = os.path.join(wheel_directory, filename)
|
|
||||||
archive_wheelfile(path, "src/")
|
|
||||||
return filename
|
|
||||||
|
|
||||||
def _exclude_hidden_and_special_files(archive_entry):
|
def _exclude_hidden_and_special_files(archive_entry):
|
||||||
"""Tarfile filter to exclude hidden and special files from the archive"""
|
"""Tarfile filter to exclude hidden and special files from the archive"""
|
||||||
|
@ -636,14 +648,54 @@ build backend::
|
||||||
return archive_entry
|
return archive_entry
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def build_sdist(sdist_dir, config_settings):
|
def _make_sdist(sdist_dir):
|
||||||
sdist_subdir = "mypackage-0.1"
|
"""Make an sdist and return both the Python object and its filename"""
|
||||||
sdist_path = pathlib.Path(sdist_dir) / (sdist_subdir + ".tar.gz")
|
sdist_path = pathlib.Path(sdist_dir) / SDIST_FILENAME
|
||||||
sdist = tarfile.open(sdist_path, "w:gz", format=tarfile.PAX_FORMAT)
|
sdist = tarfile.open(sdist_path, "w:gz", format=tarfile.PAX_FORMAT)
|
||||||
# Tar up the whole directory, minus hidden and special files
|
# Tar up the whole directory, minus hidden and special files
|
||||||
sdist.add(os.getcwd(), arcname=sdist_subdir,
|
sdist.add(os.getcwd(), arcname=SDIST_NAME,
|
||||||
filter=_exclude_hidden_and_special_files)
|
filter=_exclude_hidden_and_special_files)
|
||||||
return sdist_subdir + ".tar.gz"
|
return sdist, SDIST_FILENAME
|
||||||
|
|
||||||
|
def build_sdist(sdist_dir, config_settings):
|
||||||
|
"""PEP 517 sdist creation hook"""
|
||||||
|
sdist, sdist_filename = _make_sdist(sdist_dir)
|
||||||
|
return sdist_filename
|
||||||
|
|
||||||
|
#################
|
||||||
|
# wheel creation
|
||||||
|
#################
|
||||||
|
|
||||||
|
def get_requires_for_build_wheel(config_settings):
|
||||||
|
"""PEP 517 wheel building dependency definition hook"""
|
||||||
|
# As a simple static requirement, this could also just be
|
||||||
|
# listed in the project's build system dependencies instead
|
||||||
|
return ["wheel"]
|
||||||
|
|
||||||
|
def _prepare_out_of_tree_build(build_directory):
|
||||||
|
"""Prepare out-of-tree build by way of unpacking the sdist"""
|
||||||
|
sdist, sdist_filename = _make_sdist(build_directory)
|
||||||
|
os.chdir(build_directory)
|
||||||
|
if os.path.exists(SDIST_NAME):
|
||||||
|
# Prevent caching of stale input files
|
||||||
|
shutil.rmtree(SDIST_NAME)
|
||||||
|
sdist.extractall()
|
||||||
|
os.remove(sdist_filename)
|
||||||
|
os.chdir(SDIST_NAME)
|
||||||
|
|
||||||
|
def build_wheel(wheel_directory, build_directory=None,
|
||||||
|
metadata_directory=None, config_settings=None):
|
||||||
|
"""PEP 517 wheel creation hook"""
|
||||||
|
# First check if the frontend has requested an out-of-tree build
|
||||||
|
out_of_tree_build = (build_directory is not None and
|
||||||
|
not os.path.samefile(build_directory, os.getcwd())
|
||||||
|
if out_of_tree_build:
|
||||||
|
_prepare_out_of_tree_build(build_directory)
|
||||||
|
# Continue with assembling the wheel archive
|
||||||
|
from wheel.archive import archive_wheelfile
|
||||||
|
path = os.path.join(wheel_directory, WHEEL_FILENAME)
|
||||||
|
archive_wheelfile(path, "src/")
|
||||||
|
return WHEEL_FILENAME
|
||||||
|
|
||||||
Of course, this is a *terrible* build backend: it requires the user to
|
Of course, this is a *terrible* build backend: it requires the user to
|
||||||
have manually set up the wheel metadata in
|
have manually set up the wheel metadata in
|
||||||
|
|
Loading…
Reference in New Issue