Skip to content

Commit 359768b

Browse files
Makefile: stop leaking legacy-editable into third party builds
The .venv target exported SETUPTOOLS_ENABLE_FEATURES="legacy-editable" across the whole "pipenv sync", where it leaked into pip's PEP 517 isolated build environments. setuptools always lists the PEP 660 hooks in build_meta.__all__ but only defines them when that feature is off, so any third party sdist whose backend does "from setuptools.build_meta import *" dies with AttributeError: module 'setuptools.build_meta' has no attribute 'get_requires_for_build_editable' This only bites when pip actually has to build from source, which made it look distro specific: pillow 12.3.0 dropped the manylinux2014 wheels, so sles-12sp5 (glibc 2.22) is the only distro in the matrix below the manylinux_2_28 floor and the only one that builds it from an sdist. Run the sync without the variable and give our own packages their mypy-friendly layout afterwards instead. editable_mode=compat is setuptools' supported replacement for the feature flag: it writes the same plain path .pth that mypy needs (mypy still cannot follow the PEP 660 import hook, see python/mypy#13392), but goes through the regular build_editable hook. So it neither leaks into anybody else's build nor depends on pip's "setup.py develop" fallback, which pip >= 26 removed - keeping legacy-editable here would have worked on CI, whose venv seeds pip 23.3.1, while failing on newer developer setups with ERROR: Project ... uses a build backend that is missing the 'build_editable' hook Change-Id: If140d7875134e5a0c9ac2f62324607ab26ee7753
1 parent 32a84dc commit 359768b

1 file changed

Lines changed: 21 additions & 3 deletions

File tree

Makefile

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,23 @@ Pipfile.lock: Pipfile
429429
# This is extremely fast since the dependencies do not have to be resolved.
430430
# Cleanup partially created pipenv. This makes us able to automatically repair
431431
# broken virtual environments which may have been caused by network issues.
432-
# SETUPTOOLS_ENABLE_FEATURES="legacy-editable" is needed for mypy being able to
433-
# type check a package that's installed editable:
432+
#
433+
# The sync must no longer run with SETUPTOOLS_ENABLE_FEATURES="legacy-editable":
434+
# setuptools only defines the PEP 660 hooks when that feature is off, but always
435+
# lists them in build_meta.__all__. Any third party sdist whose build backend
436+
# does "from setuptools.build_meta import *" (e.g. pillow) therefore dies with
437+
# "AttributeError: module 'setuptools.build_meta' has no attribute
438+
# 'get_requires_for_build_editable'" once pip has to build it from source. That
439+
# only bites on distros without a matching wheel, which made it look like a
440+
# sles-12sp5 specific failure.
441+
#
442+
# We still need our own packages laid out so that mypy can type check them:
434443
# https://github.com/python/mypy/issues/13392
444+
# --config-settings editable_mode=compat is setuptools' supported replacement
445+
# for the feature flag. It writes the same plain path .pth mypy can follow, but
446+
# goes through the regular PEP 660 build_editable hook, so it neither relies on
447+
# pip's removed "setup.py develop" fallback nor leaks into anybody else's build.
448+
# --no-build-isolation makes them use the .venv's own (pinned) setuptools.
435449
.venv: Pipfile.lock .python-$(PYTHON_MAJOR_DOT_MINOR)-stamp
436450
@( \
437451
echo "Creating .venv..." ; \
@@ -441,5 +455,9 @@ Pipfile.lock: Pipfile
441455
echo "Cleaning up .venv before sync..."; \
442456
$(RM) -r .venv; \
443457
fi; \
444-
( PIP_CONSTRAINT=temporary_pipenv_constraints.txt SKIP_MAKEFILE_CALL=1 SETUPTOOLS_ENABLE_FEATURES="legacy-editable" VIRTUAL_ENV="" $(PIPENV) sync --python $(PYTHON_MAJOR_DOT_MINOR) --dev && touch .venv ) || ( $(RM) -r .venv ; exit 1 ) \
458+
( PIP_CONSTRAINT=temporary_pipenv_constraints.txt SKIP_MAKEFILE_CALL=1 VIRTUAL_ENV="" $(PIPENV) sync --python $(PYTHON_MAJOR_DOT_MINOR) --dev \
459+
&& echo "Reinstalling editable packages in compat mode..." \
460+
&& .venv/bin/python -m pip install --quiet --no-deps --no-build-isolation --config-settings editable_mode=compat \
461+
$$(.venv/bin/python -c 'import json; print(" ".join("-e " + e["path"] for s in ("default", "develop") for e in json.load(open("Pipfile.lock"))[s].values() if e.get("editable")))') \
462+
&& touch .venv ) || ( $(RM) -r .venv ; exit 1 ) \
445463
) $(LOCK_FD)>$(LOCK_PATH)

0 commit comments

Comments
 (0)