The key point that I left out of the message with the backend-bootstrap-location proposal in it, is that I started out intending to have that message be in support of Option 1 and suggest a possible syntax for that approach, but actually trying to spec out the details convinced me that @njs has a valid point regarding the relative ease of explaining Option 3.
The starting point for that exploration was the location of setuptools.build_meta in the setuptools repo: setuptools/setuptools/build_meta.py at main · pypa/setuptools · GitHub
With my proposed Option 3 spelling above, it’s fairly easy to follow how the bootstrapping is supposed to work: the repo root directory (".") gets added to the front of sys.path, then the setuptools.build_meta backend gets imported the same way it would for any other package that declared it as its build backend. This is also how @takluyver’s intreehooks helper backend for bootstrapping flit already works, so we have prior art for it being a viable bootstrapping option.
We also know from the open pip 19.0.x PRs that it isn’t that hard to add a sys.path[0] injection feature to the pep517 support library (I wouldn’t do it the way I did in those PRs as a public API, but that’s just a matter of replacing an environment variable with a command line argument and a magic prefix with a normal function parameter)
But what happens if we try to specify the location of the build backend directly? How would it be spelled in pyproject.toml? What are frontends actually supposed to do with that information? How would folks introspecting project metadata determine which build backend is actually being bootstrapped? (that one’s not a functional requirement, it would just be nice to have)
Suppose we denoted a bootstrapped backend this way:
[build-backend]
requires=[]
bootstrap-build-backend="./setuptools/build_meta.py"
Should a frontend run that file as a script? Should it run it with runpy.run_path()? Should it import it as a module, using the appropriate version dependent incantation to do so?
What are the implications for how build_meta.py is written? Will explicit relative imports work? Will setuptools.* absolute imports work? Will __name__ be "__main__", or "build_meta" or "setuptools.build_meta"?
There are (somewhat) reasonable answers available to all of those questions, but I didn’t think any of them were as elegant as the idea of just switching to a slightly more constrained version of Option 3 such that you specified where in the tree the backend implementation could be found, specified build-backend as normal, and then the backend itself executed in just the same way as it would for any other project.
The other thing I realised is that the “What if non-backends use the backend bootstrapping option to add an extra in-tree path to their hook execution environment?” concern with Option 3 applies just as much to Option 1, as either way you can make a custom in-tree backend that includes from my_real_build_backend import * as one of its lines and runs arbitrary code (including sys.path adjustments) before and after that, and that’s something that intreehooks already allows with PEP 517 today.