Projects that aren't meant to generate a wheel and `pyproject.toml`

Perhaps I’m looking at this too broadly (not just in the context of “projects that aren’t meant to generate a wheel”; though one way of looking at this discussion is that pyproject.toml has outgrown the “just the wheel, please” pattern); I was referring to

My point was that a putative [run] table could also be a candidate for projects that do create wheels.

Basically I responded to what I saw as a possible avenue for further unifying the various diverging scenarios. Ideally we could avoid something “like project.optional-dependencies”, and actually provide the same interface regardless of use-case.

I don’t want to turn your proposal into something you did not intend, but I found the [run] idea very appealing, and a new table is also an opportunity to make this API (more) consistent. Also, [library] and [application] already got mentioned, so I figured a bit of a wider angle is fair game.

We currently have at least: build-system.requires, project.python-requires, project.dependencies & project.optional-dependencies. and now potentially run.{...}. What I’m saying is that it might be possible to slice & dice this in a better way[1]. Obviously touching this for existing use-cases would mean migration pain (and we’d have to manage that), but I’m trying to take the long-term view here.

As a complete strawman for unifying the things under discussion:

[dependencies.build]     # optional; for projects building a wheel; ~= [build-system]
backend = "setuptools"   # PEP 517
requires = [...]         # PEP 518
[dependencies.run]       # PEP 621 & PEP 723
python = ">=3.9"
requires = [...]         # for wheel metadata (if applicable); for applications:
                         # base constraints that can be used to compile lock file
[dependencies.optional]  # PEP 621, resp. your proposal's run.dev-dependencies
tests = ["pytest"]
# your proposed extension for self-references
coverage = [".[tests]", "spam[tests]", "coverage"]

I was even tempted to put [dependencies.lock] in there, if only for exposition[2] :stuck_out_tongue_winking_eye:

That way, [dependencies.run] could be shared between libraries, applications & scripts, and scripts could reuse [dependencies.optional] where necessary.

It would be a fair criticism to say that the above strawman bites off more than a PEP might reasonably chew, but this is the kind of unification that I think pays off even such an effort in the long term (and that users are asking for).


  1. I re-read PEP 517/518/621 again, and those were solving crucial problems at the time, though that space was still brandnew, so it’s unrealistic to expect an eternal API from v1. ↩︎

  2. scripts will want to be able to lock dependencies too right? Should still stay single-file presumably, and with TOML we could inject the equivalent of PEP 665’s .pylock.toml very easily. ↩︎

2 Likes