mirror of https://github.com/pypa/pip
Rework PEP 518 requirement logic
This commit is contained in:
parent
a25cb53d02
commit
0eb566fa82
|
@ -95,31 +95,33 @@ class IsSDist(DistAbstraction):
|
|||
def prep_for_dist(self, finder, build_isolation):
|
||||
# Before calling "setup.py egg_info", we need to set-up the build
|
||||
# environment.
|
||||
build_requirements, isolate = self.req.get_pep_518_info()
|
||||
should_isolate = build_isolation and isolate
|
||||
|
||||
minimum_requirements = ('setuptools', 'wheel')
|
||||
missing_requirements = set(minimum_requirements) - set(
|
||||
pkg_resources.Requirement(r).key
|
||||
for r in build_requirements
|
||||
)
|
||||
if missing_requirements:
|
||||
def format_reqs(rs):
|
||||
return ' and '.join(map(repr, sorted(rs)))
|
||||
logger.warning(
|
||||
"Missing build time requirements in pyproject.toml for %s: "
|
||||
"%s.", self.req, format_reqs(missing_requirements)
|
||||
)
|
||||
logger.warning(
|
||||
"This version of pip does not implement PEP 517 so it cannot "
|
||||
"build a wheel without %s.", format_reqs(minimum_requirements)
|
||||
)
|
||||
build_requirements = self.req.get_pep_518_info()
|
||||
should_isolate = build_isolation and build_requirements is not None
|
||||
|
||||
if should_isolate:
|
||||
# Haven't implemented PEP 517 yet, so spew a warning about it if
|
||||
# build-requirements don't include setuptools and wheel.
|
||||
missing_requirements = {'setuptools', 'wheel'} - {
|
||||
pkg_resources.Requirement(r).key for r in build_requirements
|
||||
}
|
||||
if missing_requirements:
|
||||
logger.warning(
|
||||
"Missing build requirements in pyproject.toml for %s.",
|
||||
self.req,
|
||||
)
|
||||
logger.warning(
|
||||
"This version of pip does not implement PEP 517 so it "
|
||||
"cannot build a wheel without %s.",
|
||||
" and ".join(map(repr, sorted(missing_requirements)))
|
||||
)
|
||||
|
||||
# Isolate in a BuildEnvironment and install the build-time
|
||||
# requirements.
|
||||
self.req.build_env = BuildEnvironment()
|
||||
self.req.build_env.install_requirements(
|
||||
finder, build_requirements,
|
||||
"Installing build dependencies")
|
||||
"Installing build dependencies"
|
||||
)
|
||||
|
||||
self.req.run_egg_info()
|
||||
self.req.assert_source_matches_version()
|
||||
|
|
|
@ -560,42 +560,40 @@ class InstallRequirement(object):
|
|||
return pp_toml
|
||||
|
||||
def get_pep_518_info(self):
|
||||
"""Get a list of the packages required to build the project, if any,
|
||||
and a flag indicating whether pyproject.toml is present, indicating
|
||||
that the build should be isolated.
|
||||
"""Get PEP 518 build-time requirements.
|
||||
|
||||
Build requirements can be specified in a pyproject.toml, as described
|
||||
in PEP 518. If this file exists but doesn't specify build
|
||||
requirements, pip will default to installing setuptools and wheel.
|
||||
Returns the list of the packages required to build the project,
|
||||
specified as per PEP 518 within the package. If `pyproject.toml` is not
|
||||
present, returns None to signify not using the same.
|
||||
"""
|
||||
if os.path.isfile(self.pyproject_toml):
|
||||
with io.open(self.pyproject_toml, encoding="utf-8") as f:
|
||||
pp_toml = pytoml.load(f)
|
||||
if not os.path.isfile(self.pyproject_toml):
|
||||
return None
|
||||
|
||||
build_system = pp_toml.get('build-system', {})
|
||||
if "requires" not in build_system:
|
||||
raise InstallationError(
|
||||
"{} does not comply with PEP 518 as it since it's "
|
||||
"pyproject.toml file does not have a '[build-system]' "
|
||||
"table with a 'requires' key."
|
||||
.format(self)
|
||||
)
|
||||
with io.open(self.pyproject_toml, encoding="utf-8") as f:
|
||||
pp_toml = pytoml.load(f)
|
||||
|
||||
requires = build_system["requires"]
|
||||
# Extract the build requirements
|
||||
requires = pp_toml.get("build-system", {}).get("requires", None)
|
||||
|
||||
# Error out if it's not valid
|
||||
error_reason = None
|
||||
if requires is None:
|
||||
error_reason = "is missing."
|
||||
else:
|
||||
is_list_of_str = isinstance(requires, list) and all(
|
||||
isinstance(req, str) for req in requires
|
||||
isinstance(req, six.string_types) for req in requires
|
||||
)
|
||||
if not is_list_of_str:
|
||||
raise InstallationError(
|
||||
"{} does not comply with PEP 518 as it since it's "
|
||||
"pyproject.toml file contains [build-system].requires "
|
||||
"which is not a list of strings."
|
||||
.format(self)
|
||||
)
|
||||
error_reason = "not a list of strings."
|
||||
if error_reason is not None:
|
||||
msg = (
|
||||
"{} does not comply with PEP 518 since pyproject.toml does "
|
||||
"not contain a valid '[build-system].requires' key: {}"
|
||||
).format(self, error_reason)
|
||||
raise InstallationError(msg)
|
||||
|
||||
return requires, True
|
||||
|
||||
return (['setuptools', 'wheel'], False)
|
||||
# If control flow reaches here, we're good to go.
|
||||
return requires
|
||||
|
||||
def run_egg_info(self):
|
||||
assert self.source_dir
|
||||
|
|
Loading…
Reference in New Issue