Commit ec8ec89a authored by Xavier Thompson's avatar Xavier Thompson

[feat] Prevent pip installing build dependencies

By default pip installs build dependencies (e.g. setuptools, poetry)
in a temporary folder and temporarily adds it to sys.path in order
to proceed to build the distribution. But we want all distributions
to be installed with buildout and respect pinned versions, so we aim
to prevent pip from installing build dependencies.

Instead, we will install the build dependencies first and pass them
explicitly to zc.recipe.egg via the setup-eggs option.

This commit prevents pip from installing the build dependencies listed
by the `build-system.requires` key in the pyproject.toml file.

It may prevent pip from installing PEP 517 dynamic build dependencies
or setuptools' setup_requires dependencies.
See https://peps.python.org/pep-0517/#get-requires-for-build-wheel
parent 825daa85
......@@ -427,7 +427,7 @@ class Installer(object):
tmp = tempfile.mkdtemp(dir=dest)
try:
paths = call_pip_wheel(spec, tmp)
paths = call_pip_wheel(spec, tmp, self)
dists = []
env = pkg_resources.Environment(paths)
......@@ -459,7 +459,7 @@ class Installer(object):
result = []
for d in dists:
result.append(_move_to_eggs_dir_and_compile(d, dest))
result.append(_move_to_eggs_dir_and_compile(d, dest, self))
return result
......@@ -587,7 +587,7 @@ class Installer(object):
raise zc.buildout.UserError(
"Couldn't download distribution %s." % avail)
dists = [_move_to_eggs_dir_and_compile(dist, self._dest)]
dists = [_move_to_eggs_dir_and_compile(dist, self._dest, self)]
for _d in dists:
if _d not in ws:
ws.add(_d, replace=True)
......@@ -1731,7 +1731,7 @@ class IncompatibleConstraintError(zc.buildout.UserError):
IncompatibleVersionError = IncompatibleConstraintError # Backward compatibility
def call_pip_wheel(spec, dest):
def call_pip_wheel(spec, dest, options):
"""
Call `pip wheel` from a subprocess to install a
distribution specified by `spec` into `dest`.
......@@ -1744,6 +1744,12 @@ def call_pip_wheel(spec, dest):
else:
args.append('-v')
# Try to prevent pip from installing build dependencies implicitly
# and without respecting pinned versions, on the fly
if not options._allow_picked_versions:
args.append('--no-index')
args.append('--no-build-isolation')
args.append(spec)
try:
......@@ -1839,7 +1845,7 @@ def _get_matching_dist_in_location(dist, location):
if dist_infos == [(dist.project_name.lower(), dist.parsed_version)]:
return dists.pop()
def _move_to_eggs_dir_and_compile(dist, dest):
def _move_to_eggs_dir_and_compile(dist, dest, options):
"""Move distribution to the eggs destination directory.
And compile the py files, if we have actually moved the dist.
......@@ -1880,7 +1886,7 @@ def _move_to_eggs_dir_and_compile(dist, dest):
unpacker(dist.location, tmp_dest)
[tmp_loc] = glob.glob(os.path.join(tmp_dest, '*'))
else:
[tmp_loc] = call_pip_wheel(dist.location, tmp_dest)
[tmp_loc] = call_pip_wheel(dist.location, tmp_dest, options)
installed_with_pip = True
# We have installed the dist. Now try to rename/move it.
......
......@@ -143,7 +143,8 @@ class TestEasyInstall(unittest.TestCase):
result = zc.buildout.easy_install._move_to_eggs_dir_and_compile(
dist,
dest
dest,
None, # ok because we don't fallback to pip
)
self.assertIsNotNone(result)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment