On Fri, Jul 14, 2017 at 4:00 AM, Nick Coghlan <ncogh...@gmail.com> wrote: > On 14 July 2017 at 20:18, Nathaniel Smith <n...@pobox.com> wrote: >> On Fri, Jul 7, 2017 at 8:27 PM, Nick Coghlan <ncogh...@gmail.com> wrote: >> Some possible problems that I've seen mentioned in the thread include: >> >> - pip doesn't trust build systems to properly support incremental >> builds, so it wants to force it to throw away the build artifacts >> after every build > > It's less that, and more pip wanting to ensure that the default > publisher experience is reasonable close to the default end user > experience, in order to increase the likelihood that publishers ship > working sdists and wheel files, even if they haven't learned about the > full suite of available pre-release testing tools yet (or have chosen > not to use them).
This is exactly the opposite of what Paul says in his message posted at about the same time as yours... AFAICT his argument is that build artifact leakage is exactly what pip is worried about, and if anything he's annoyed at me because he thinks I'm downplaying the problem :-). (My impression is that Donald's position might be closer to what you wrote, though.) >> - pip wants to enforce builds going via sdists > > This isn't a requirement, just an option we want to enable (and can't > avoid enabling). Donald sure seemed to be insisting on it as a requirement earlier, at least. And the *entire cause* of this whole discussion was conflict between this requirement and flit not wanting to support building sdists from unpacked sdists, so characterizing it as some automatic thing that doesn't even need to be talked about seems really weird. >> - Thomas / Ralf / I are frustrated at the idea of not supporting >> incremental builds > > This is why we're allowing frontends to request in-place builds. Wait, what? That's not what any of us asked for at all. Ralf and I want incremental builds, which is orthogonal to the in-place versus out-of-place distinction, and Thomas wants pip not to call sdist due to some combination of inefficiency and lack-of-support-in-some-cases, which is also orthogonal to the in-place versus out-of-place distinction. (In retrospect I probably shouldn't have lumped Thomas / Ralf / I together there, those really are different motivations, though they lead to similar places.) You're trying to shut me down by making these pronouncements about what PEP 517 is going to be, and yet you don't seem to even understand what requirements people are talking about. I'm sorry if that's rude, and I'm not angry at you personally or anything, but I am frustrated and I don't understand why I seem to have to keep throwing myself in front of these ideas that seem so poorly motivated. > And that's been the main discovery of the last round of discussions - > we'd been talking past each other, and what we actually wanted was for > the backend interface to accurately model the in-place/out-of-tree > discussion that has been common to most build systems at least since > autotools (hence my catalog of them earlier in the thread). This statement seems just... completely wrong to me. I can't see any way that the in-place/out-of-place distinction matches anything we were talking about earlier. Have we been reading the same threads? There was the whole thing about pip copying trees, of course, but that's a completely different thing. The motivation there is that they want to make sure that two builds don't accidentally influence each other. If they don't trust the build system, then this requires copying to a new tree (either via copytree or sdist). If they do trust the build system, then there are other options -- you can do an in-place build, or have a flag saying "please 'make clean' before this build", or something. So out-of-place builds are either insufficient or unnecessary for what pip wants. Copying the source tree and out-of-place builds are completely different things with different use cases; they happen to both involve external directories, but that's mostly a false similarity I think. And as for flit, it doesn't even have a distinction between in-place and out-of-place builds... > This means we're no longer attempting to invent anything new, we're > just copying the extensive prior art around out-of-tree builds, and > will deal with the consequences. Forcing all build systems to support both in-place builds and out-of-place builds adds substantial additional complexity, introduces multiple new failure modes, and AFAICT is not very well suited to the problems people have been worrying about. > Regarding your questions: > > 1. What if backends get their out-of-tree support wrong? > > That's fine, it can be reported as a bug, fixed, and frontends and > redistributors can use pip constraint files to enforce minimum > versions even if publishers don't update their pyproject.toml files > (plus frontends will grab the latest version of build backends by > default). > > 2. What happens if re-using build directories isn't tested properly? > > I'd be genuinely surprised if any frontend ever did this by default > (excluding in-place builds). Instead, it would be application > integrators doing it as part of something like BitBucket Pipelines or > OpenShift ImageStreams, and if it didn't work properly, they'd stop > caching that particular directory. > > 3. What happens if an upgrade breaks incremental builds? > > The same thing that happens if an upgrade straight-up breaks: either > it gets reported as a bug and fixed, or else end users figure out a > workaround and move on. > > 4. Do we enforce not modifying the source directory? > > No. We don't even enforce backends not doing "rm -rf ~". If folks want > anything like that enforced, then they still need to use ephemeral > build servers. These first 4 answers might be reasonable if it wasn't for the fact that the *entire alleged motivation* for this feature is to reduce the chance of accidental breakage. You can't justify it like that and then hand-wave away all the new potential sources of accidental breakage that it introduces... > 5. What happens if you try to switch from in-place to out-of-place in > one tree and it breaks? > > Don't do that, then (this is a publisher-only issue that won't impact > end users). This will certainly affect developers. The symptom is that you do the equivalent of 'python setup.py build' in a source tree, and then later do 'pip install .' in a source tree, and get screwy undefined behavior because you're using a mainstream build system like cmake. At the very least the PEP needs some language like "Frontends MUST NOT assume that a given source tree can switch between in-place and out-of-place builds; once they've issued one type of build against a given source tree, they MUST stick with that type. One consequence of this is that when given an arbitrary pre-existing source tree whose history is unknown, frontends MUST NOT assume that they can perform either in-place or out-of-place builds using that tree. In practice, this means that frontends MUST explicitly query the user for which type of build to use, because anything else risks either producing corrupt builds or breaking the user's source tree with common build systems." Or, well, that sounds pretty unusable, so maybe instead we would want to go with the alternative: "Backends MUST support free switching between in-place and out-of-place builds in the same directory" -- but that's a whole 'nother likely source of weird problems, and breaks the idea that this is something that existing build systems all support already. But IMO the one thing the PEP can't do is just stay silent on this and pretend that everything will work out even if frontends and backends are using incompatible interpretations. That'd be, like, malpractice. > 6. Is native out-of-tree build support common in practice? > > Yes, as they're a requirement for inclusion in Debian. Huh, interesting! Do you have a cite for this? I tried to find more information, and all I found this advice for upstreams, which explicitly discusses what they need from build systems that don't support out-of-tree builds. It would be odd to include that if such build systems were forbidden: https://wiki.debian.org/UpstreamGuide#Cleaning_the_Tree In any case, there's a huge difference between Debian wanting to take a single static snapshot and build it several times from scratch, and what's specified in the PEP right now which apparently allows for incrementally re-using the same build tree while also incrementally evolving the source being built. Most of the underspecified edge cases that I brought up are ones that simply don't arise in Debian's use case, but do arise in the PEP. This is why I'm unconvinced by the argument that we're just adopting some old well-known idea -- when you look at the details this proposal as written is much more ambitious than any deployed system I'm aware of. > 7. Why include in-place support in the API then? > > Because some folks (including you) would like to include incremental > build support, and because if we don't support it explicitly backends > will still have to deal with the "wheel_directory == build_directory" > case. Out-of-tree builds as currently specified are required to handle incremental out-of-tree builds... maybe that's a mistake, but that's what the text says. I don't understand the second half of your sentence. > 8. But what if we make a design mistake and can't fix it? > > Like all other recent PyPA specifications, PEP 517 will go through a > Provisional acceptance period where it is accepted for implementation > in the default toolset, but explicitly subject to revision based on > that real world feedback. > > But even if something does still get through that second period of > review, the whole reason we opted for the Python backend API over the > CLI based one is that it's much easier to evolve (since we can do > getattr checks and so forth, as well as straight up declarations of > API version support) It's *dramatically* easier to add than to remove, though. > 9. Why not wait and then add a new backend capability requirement later? > > Waiting to add the requirement won't provide us with any more data > than we already have, but may give backend implementors the impression > they don't need to care about out-of-tree build support. This is also > our first, last, and only chance to make out-of-tree build support a > *mandatory* backend requirement that frontends can rely on - if we add > it later, it will necessarily only be optional. AFAICT making it optional is better for everyone, so not sure why that's seen as a bad thing. Analysis: - If you're an eager backend dev who loves this stuff, you'll implement it anyway, so it doesn't matter whether it's optional - If you're a just-trying-to-hack-something-together backend dev maybe constrained by some ugly legacy build system, then you'd much rather it be optional because then you don't have to deal with hacking up some fake "out-of-tree build" using copytree, and maybe getting it wrong - If you're pip, then AFAICT you're more worried about lazy backend devs screwing things up than anything else, in which case you don't want them hacking up their own fake "out-of-tree build" using copytree, you want to take responsibility for that so you know that you get it right - If you're an automatic building pipeline, then knowing which backends support "real" out-of-tree builds is *super valuable information* because it means you don't have to waste disk/bandwidth caching the "build tree" for backends that are just going to throw it all away anyway -n -- Nathaniel J. Smith -- https://vorpus.org _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org https://mail.python.org/mailman/listinfo/distutils-sig