Commit 085baf94 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 df5da4d7
...@@ -427,7 +427,7 @@ class Installer(object): ...@@ -427,7 +427,7 @@ class Installer(object):
tmp = tempfile.mkdtemp(dir=dest) tmp = tempfile.mkdtemp(dir=dest)
try: try:
paths = call_pip_wheel(spec, tmp) paths = call_pip_wheel(spec, tmp, self)
dists = [] dists = []
env = pkg_resources.Environment(paths) env = pkg_resources.Environment(paths)
...@@ -459,7 +459,7 @@ class Installer(object): ...@@ -459,7 +459,7 @@ class Installer(object):
result = [] result = []
for d in dists: 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 return result
...@@ -587,7 +587,7 @@ class Installer(object): ...@@ -587,7 +587,7 @@ class Installer(object):
raise zc.buildout.UserError( raise zc.buildout.UserError(
"Couldn't download distribution %s." % avail) "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: for _d in dists:
if _d not in ws: if _d not in ws:
ws.add(_d, replace=True) ws.add(_d, replace=True)
...@@ -1731,7 +1731,7 @@ class IncompatibleConstraintError(zc.buildout.UserError): ...@@ -1731,7 +1731,7 @@ class IncompatibleConstraintError(zc.buildout.UserError):
IncompatibleVersionError = IncompatibleConstraintError # Backward compatibility 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 Call `pip wheel` from a subprocess to install a
distribution specified by `spec` into `dest`. distribution specified by `spec` into `dest`.
...@@ -1744,6 +1744,12 @@ def call_pip_wheel(spec, dest): ...@@ -1744,6 +1744,12 @@ def call_pip_wheel(spec, dest):
else: else:
args.append('-v') 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) args.append(spec)
try: try:
...@@ -1839,7 +1845,7 @@ def _get_matching_dist_in_location(dist, location): ...@@ -1839,7 +1845,7 @@ def _get_matching_dist_in_location(dist, location):
if dist_infos == [(dist.project_name.lower(), dist.parsed_version)]: if dist_infos == [(dist.project_name.lower(), dist.parsed_version)]:
return dists.pop() 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. """Move distribution to the eggs destination directory.
And compile the py files, if we have actually moved the dist. 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): ...@@ -1880,7 +1886,7 @@ def _move_to_eggs_dir_and_compile(dist, dest):
unpacker(dist.location, tmp_dest) unpacker(dist.location, tmp_dest)
[tmp_loc] = glob.glob(os.path.join(tmp_dest, '*')) [tmp_loc] = glob.glob(os.path.join(tmp_dest, '*'))
else: else:
[tmp_loc] = call_pip_wheel(dist.location, tmp_dest) [tmp_loc] = call_pip_wheel(dist.location, tmp_dest, options)
installed_with_pip = True installed_with_pip = True
# We have installed the dist. Now try to rename/move it. # We have installed the dist. Now try to rename/move it.
......
...@@ -143,7 +143,8 @@ class TestEasyInstall(unittest.TestCase): ...@@ -143,7 +143,8 @@ class TestEasyInstall(unittest.TestCase):
result = zc.buildout.easy_install._move_to_eggs_dir_and_compile( result = zc.buildout.easy_install._move_to_eggs_dir_and_compile(
dist, dist,
dest dest,
None, # ok because we don't fallback to pip
) )
self.assertIsNotNone(result) 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