diff options
| author | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-08-11 22:13:08 +0100 |
|---|---|---|
| committer | Anderson Bravalheri <andersonbravalheri@gmail.com> | 2022-08-11 22:13:08 +0100 |
| commit | d3167b675cd54370a298ab90c255f2efc72f25c3 (patch) | |
| tree | 0e2f52dfccbd9722d703e58da427c9dbf4bfd2d7 /setuptools | |
| parent | 5bc39a30e051111675043b1dbafe7d012d244dfa (diff) | |
| parent | e2fb005beed79dba58ec0ecfa9bcdadf03d6666a (diff) | |
| download | python-setuptools-git-d3167b675cd54370a298ab90c255f2efc72f25c3.tar.gz | |
Prevent errors in editable install and external ``.egg-info`` (#3503)
Diffstat (limited to 'setuptools')
| -rw-r--r-- | setuptools/command/build_py.py | 21 | ||||
| -rw-r--r-- | setuptools/tests/test_editable_install.py | 37 |
2 files changed, 54 insertions, 4 deletions
diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 923a3232..8b1a3320 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -11,7 +11,7 @@ import itertools import stat import warnings from pathlib import Path -from typing import Dict, Iterator, List, Optional, Tuple +from typing import Dict, Iterable, Iterator, List, Optional, Tuple from setuptools._deprecation_warning import SetuptoolsDeprecationWarning from setuptools.extern.more_itertools import unique_everseen @@ -52,7 +52,6 @@ class build_py(orig.build_py): def run(self): """Build modules, packages, and copy data files to build directory""" - # if self.editable_mode or not (self.py_modules and self.packages): if not (self.py_modules or self.packages) or self.editable_mode: return @@ -175,15 +174,17 @@ class build_py(orig.build_py): getattr(self, 'existing_egg_info_dir', None) and Path(self.existing_egg_info_dir, "SOURCES.txt").exists() ): - manifest = Path(self.existing_egg_info_dir, "SOURCES.txt") + egg_info_dir = self.existing_egg_info_dir + manifest = Path(egg_info_dir, "SOURCES.txt") files = manifest.read_text(encoding="utf-8").splitlines() else: self.run_command('egg_info') ei_cmd = self.get_finalized_command('egg_info') + egg_info_dir = ei_cmd.egg_info files = ei_cmd.filelist.files check = _IncludePackageDataAbuse() - for path in files: + for path in _filter_absolute_egg_info(files, egg_info_dir): d, f = os.path.split(assert_relative(path)) prev = None oldf = f @@ -346,3 +347,15 @@ class _IncludePackageDataAbuse: msg = textwrap.dedent(self.MESSAGE).format(importable=importable) warnings.warn(msg, SetuptoolsDeprecationWarning, stacklevel=2) self._already_warned.add(importable) + + +def _filter_absolute_egg_info(files: Iterable[str], egg_info: str) -> Iterator[str]: + """ + ``build_meta`` may try to create egg_info outside of the project directory, + and this can be problematic for certain plugins (reported in issue #3500). + This function should filter this case of invalid files out. + """ + egg_info_name = Path(egg_info).name + for file in files: + if not (egg_info_name in file and os.path.isabs(file)): + yield file diff --git a/setuptools/tests/test_editable_install.py b/setuptools/tests/test_editable_install.py index 8ab17b3c..ea31cb46 100644 --- a/setuptools/tests/test_editable_install.py +++ b/setuptools/tests/test_editable_install.py @@ -721,6 +721,43 @@ def test_compat_install(tmp_path, venv): assert "cannot import name 'subpackage'" in out +def test_pbr_integration(tmp_path, venv, editable_opts): + """Ensure editable installs work with pbr, issue #3500""" + files = { + "pyproject.toml": dedent("""\ + [build-system] + requires = ["setuptools"] + build-backend = "setuptools.build_meta" + """), + "setup.py": dedent("""\ + __import__('setuptools').setup( + pbr=True, + setup_requires=["pbr"], + ) + """), + "setup.cfg": dedent("""\ + [metadata] + name = mypkg + + [files] + packages = + mypkg + """), + "mypkg": { + "__init__.py": "", + "hello.py": "print('Hello world!')", + }, + "other": {"test.txt": "Another file in here."}, + } + venv.run(["python", "-m", "pip", "install", "pbr"]) + + with contexts.environment(PBR_VERSION="0.42"): + install_project("mypkg", venv, tmp_path, files, *editable_opts) + + out = venv.run(["python", "-c", "import mypkg.hello"]) + assert b"Hello world!" in out + + def install_project(name, venv, tmp_path, files, *opts): project = tmp_path / name project.mkdir() |
