[Distutils]Possible change to PEP 517: look up the backend as $BACKEND.__build_backend__?
![](https://secure.gravatar.com/avatar/97c543aca1ac7bbcfb5279d0300c8330.jpg?s=120&d=mm&r=g)
Hi all, I had a thought for something that might be a simple way to improve dev experience with custom build backends. A PEP 517 build backend is a Python object that has some special methods on it. And the way a project picks which object to use, is via pyproject.toml: [build-system] build-backend = "module1.module2:object" Currently, this means that the build backend is the Python object: module1.module2.object Here's my idea: what if change it, so that the above config is interpreted as meaning that the build backend is the Python object: module1.module2.object.__build_backend__ (I.e., we tack a "__build_backend__" on the end before looking it up.) Why does this matter? Well, with the current system, if you want to use flit [1] as your build backend, you have to write: build-backend = "flit.buildapi" And if you want to use intreehooks [2],you have to writ: build-backend = "intreehooks:loader" These names are slightly awkward, because these projects don't want to just jam all the PEP 517 methods directly onto the top-level module object, so they each have to invent some ad hoc sub-object to put the methods on. And then that's exposed to all their users as a bit of random cruft you have to copy-paste. The idea of __build_backend__ is that these projects could rename the 'buildapi' and 'loader' objects to be '__build_backend__' instead, and then users could write: build-backend = "flit" build-backend = "intreehooks" build-backend = "setuptools" and it just feels nicer. Right now PEP 517 is still marked provisional, and pip hasn't shipped support yet, so I think changing this is still pretty easy. (It would mean a small amount of work for projects like flit that have already implemented backends.) What do you think? (Thomas, I'd love your thoughts in particular :-).) -n [1] https://github.com/takluyver/flit/ [2] https://github.com/takluyver/intreehooks -- Nathaniel J. Smith -- https://vorpus.org
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
On 24 June 2018 at 16:19, Nathaniel Smith <njs@pobox.com> wrote:
Hi all,
I had a thought for something that might be a simple way to improve dev experience with custom build backends.
A PEP 517 build backend is a Python object that has some special methods on it. And the way a project picks which object to use, is via pyproject.toml:
[build-system] build-backend = "module1.module2:object"
Currently, this means that the build backend is the Python object:
module1.module2.object
Here's my idea: what if change it, so that the above config is interpreted as meaning that the build backend is the Python object:
module1.module2.object.__build_backend__
(I.e., we tack a "__build_backend__" on the end before looking it up.)
Allowing `__build_backend__` as an override attribute seems fine to me, but I think it would be a problem if direct references like `build-backend = "flit.buildapi"` didn't work. That is, the override check would be: backend = getattr(backend_ref, "__build_backend__", backend_ref) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
![](https://secure.gravatar.com/avatar/90a3b7816edd170b002641ade072b52a.jpg?s=120&d=mm&r=g)
On Sun, Jun 24, 2018, at 7:19 AM, Nathaniel Smith wrote:
What do you think? (Thomas, I'd love your thoughts in particular :-).)
I agree that it looks nicer, but I'm not sure that it's worth the added complexity: is 'flit' equivalent to 'flit.__build_api__' (i.e. from flit import __build_api__), or to 'flit:__build_api__' (import flit and get an attribute called __build_api__)? For Flit, I treat the buildsystem table as boilerplate, and 'flit init' inserts it automatically. So the extra word in 'flit.buildapi' is a very minor inconvenience. There's also an argument that the explicit 'flit.builapi' is preferable for understanding it: most packaging tools will use the name 'build' in various places, so it's not necessarily obvious that __build_api__ is what's exposed to the frontend. But that could largely be solved by docs and comments. So I'm -0, but I'm probably biased: I would need to update various bits of code and docs if we changed it (flit, intreehooks, the pep517 module). I agree that if we do want to make changes like this, it's still feasible to do so at the moment. Thomas
![](https://secure.gravatar.com/avatar/f3ba3ecffd20251d73749afbfa636786.jpg?s=120&d=mm&r=g)
On 24 June 2018 at 17:47, Thomas Kluyver <thomas@kluyver.me.uk> wrote:
On Sun, Jun 24, 2018, at 7:19 AM, Nathaniel Smith wrote:
What do you think? (Thomas, I'd love your thoughts in particular :-).)
I agree that it looks nicer, but I'm not sure that it's worth the added complexity: is 'flit' equivalent to 'flit.__build_api__' (i.e. from flit import __build_api__), or to 'flit:__build_api__' (import flit and get an attribute called __build_api__)?
For Flit, I treat the buildsystem table as boilerplate, and 'flit init' inserts it automatically. So the extra word in 'flit.buildapi' is a very minor inconvenience.
Explicitly encouraging build systems to provide an `init` command that configures the `build-requires` table appropriately (creating `pyproject.toml` if necessary) would be another way of addressing Nathaniel's UX concern (and has the virtue of keeping PEP 517 as simple as we can reasonably make it). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
![](https://secure.gravatar.com/avatar/97c543aca1ac7bbcfb5279d0300c8330.jpg?s=120&d=mm&r=g)
On Sun, Jun 24, 2018 at 12:47 AM, Thomas Kluyver <thomas@kluyver.me.uk> wrote:
On Sun, Jun 24, 2018, at 7:19 AM, Nathaniel Smith wrote:
What do you think? (Thomas, I'd love your thoughts in particular :-).)
I agree that it looks nicer, but I'm not sure that it's worth the added complexity: is 'flit' equivalent to 'flit.__build_api__' (i.e. from flit import __build_api__), or to 'flit:__build_api__' (import flit and get an attribute called __build_api__)?
I'd say the latter (flit:__build_api__). It doesn't make much difference in practice, because if you do want to make it a submodule, then flit/__init__.py can just do 'from . import __build_api__' (or 'from . import buildapi as __build_api__'). And this only affects build system designers, who already have to jump through a bunch of small but slightly fiddly hoops -- it's sort of inherent in implementing this kind of API.
For Flit, I treat the buildsystem table as boilerplate, and 'flit init' inserts it automatically. So the extra word in 'flit.buildapi' is a very minor inconvenience.
Yes, but pyproject.toml is something that every python dev will be looking at on a regular basis, and "Beautiful is better than ugly". (What does 'flit init' do if someone already has a pyproject.toml, by the way?) -n -- Nathaniel J. Smith -- https://vorpus.org
![](https://secure.gravatar.com/avatar/90a3b7816edd170b002641ade072b52a.jpg?s=120&d=mm&r=g)
On Sun, Jun 24, 2018, at 9:30 AM, Nathaniel Smith wrote:
(What does 'flit init' do if someone already has a pyproject.toml, by the way?)
At present, it prompts you to overwrite it or cancel. I guess that will need to change at some point as more tools use pyproject.toml.
participants (3)
-
Nathaniel Smith
-
Nick Coghlan
-
Thomas Kluyver