Commit 3eda85fb authored by Xavier Thompson's avatar Xavier Thompson

[feat] Use pip install --editable in easy_install.develop

Instead of running python setup.py develop directly. This will allow
using zc.buildout.easy_install.develop on recent projects that have
only a pyproject.toml. It also fixes develop leaving build artifacts
in the source directory that caused later runs to do nothing, e.g.
preventing develop-eggs to be rebuilt when a build dependency passed
in setup-eggs option of zc.recipe.egg:develop changed.

A verbosity parameter to tune verbosity of pip is added, with adjusted
values for the case of buildout:develop and of zc.recipe.egg:develop,
so as to remain close to the previous behavior with regards to logs.

Technical details:

For packages using PEP-660-style editable installs, supported by more
recent versions of pip, pip will not delegate to `setup.py develop` -
enabling editable installs for pure pyproject.toml projects - and will
instead generate a .dist-info metadata folder but not a .egg-link.

Since buildout currently requires a .egg-link, as it does not support
PEP 660's mechanism that relies on having a sites-packages directory,
we need to create this .egg-link after the fact. The tricky part is
finding out where the .egg-link should point: the path containing the
pyproject.toml, or a subdirectory?

For this we make use of *.dist-info/top_level.txt to first determine
the list of top-level packages, and then importlib to extract info
from the PEP-660-style install.

If top_level.txt does not exist or is empty, fallback to the path of
the folder that contains the pyproject.toml as the .egg-link target.
If it lists multiple packages that resolve to different import paths,
arbitrarily use the first one and emit a warning.

Support namespace packages where `spec.submodule_search_locations` is
a `_NamespacePath` object instead of a simple `list` and also support
cases where the layout of the source project does not follow the same
structure as the package tree - meaning some custom magic might be
involved in making editable imports work as intended.
parent c22e43c8
...@@ -1131,7 +1131,8 @@ class Buildout(DictMixin): ...@@ -1131,7 +1131,8 @@ class Buildout(DictMixin):
for setup in files: for setup in files:
self._logger.info("Develop: %r", setup) self._logger.info("Develop: %r", setup)
__doing__ = 'Processing develop directory %r.', setup __doing__ = 'Processing develop directory %r.', setup
zc.buildout.easy_install.develop(setup, dest) zc.buildout.easy_install.develop(setup, dest,
verbosity=-20)
except: except:
# if we had an error, we need to roll back changes, by # if we had an error, we need to roll back changes, by
# removing any files we created. # removing any files we created.
......
This diff is collapsed.
...@@ -348,7 +348,7 @@ reporting that a version was picked automatically: ...@@ -348,7 +348,7 @@ reporting that a version was picked automatically:
zc.buildout.easy_install DEBUG zc.buildout.easy_install DEBUG
Fetching demoneeded 1.1 from: http://.../demoneeded-1.1.zip Fetching demoneeded 1.1 from: http://.../demoneeded-1.1.zip
zc.buildout.easy_install DEBUG zc.buildout.easy_install DEBUG
Running pip install:... Running pip wheel...
zc.buildout.easy_install INFO zc.buildout.easy_install INFO
Got demoneeded 1.1. Got demoneeded 1.1.
zc.buildout.easy_install DEBUG zc.buildout.easy_install DEBUG
......
...@@ -204,8 +204,7 @@ We should be able to deal with setup scripts that aren't setuptools based. ...@@ -204,8 +204,7 @@ We should be able to deal with setup scripts that aren't setuptools based.
... # doctest: +ELLIPSIS ... # doctest: +ELLIPSIS
Installing... Installing...
Develop: '/sample-buildout/foo' Develop: '/sample-buildout/foo'
... Running pip install --editable /sample-buildout/foo
Installed /sample-buildout/foo
... ...
>>> ls('develop-eggs') >>> ls('develop-eggs')
...@@ -216,10 +215,9 @@ We should be able to deal with setup scripts that aren't setuptools based. ...@@ -216,10 +215,9 @@ We should be able to deal with setup scripts that aren't setuptools based.
... # doctest: +ELLIPSIS ... # doctest: +ELLIPSIS
Installing... Installing...
Develop: '/sample-buildout/foo' Develop: '/sample-buildout/foo'
in: '/sample-buildout/foo' Running pip install --editable /sample-buildout/foo
... -q develop -mN -d /sample-buildout/develop-eggs/... ... -m pip install -t ... --editable /sample-buildout/foo
...
""" """
def buildout_error_handling(): def buildout_error_handling():
......
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