Say we have a package, like h5py, which builds against numpy. It can support a range of numpy versions but, once built, requires numpy at runtime to be the same version that it was built against (more correctly, a binary compatible version - I don’t know how broad that is). With PEP 517 & 518, the sdist would specify a build dependency like
numpy>=1.12, and then the build process would output a dependency like
numpy==1.17.2 based on the numpy version in the build environment,
However, now we want to install h5py with an older version of numpy (e.g. to test compatibility). We create an environment with numpy 1.15.4 (for instance), and then try to install h5py from source. Without build isolation, h5py builds against the numpy version in the target environment. With build isolation, pip creates a build environment with the newest version of numpy compatible with the build requirement. The wheel depends on a newer numpy, and pip either has to report that it’s incompatible, or upgrade numpy in the target environment - which is not what we want.
Clearly we can work around this by avoiding build isolation for now. But build isolation is a good thing overall, and I expect it to gradually get harder to avoid.
One idea that springs to mind is for pip to create the build environment with the same numpy version as the target environment (assuming this meets the build dependencies), rather than the newest version. This would make this use case ‘just work’ again. But it feels like a bit of a hack - some of our environment state leaks into the build environment.
If we had infinite time, we could build wheels with every possible combination of build dependencies, and then select one that needed the fewest upgrades/downgrades of other packages in the target environments. Clearly we’re not going to do that, but maybe it helps think about other solutions.
Looping back to the discussion in Support for build and run time dependencies, maybe build backends need some way to inspect the target environment to choose build dependencies. I don’t think PEP 517 backends currently have any way of knowing about the target environment.