Not at all. I think that none of the pyproject.toml
related PEPs had any impact (or minor) on the Python interpreter itself. It’s about bringing a shared convention/standard to the tooling ecosystem around it.
But this doesn’t force you into anything, but here it’s about the ecosystem that would like it and leverage it.
I’ve been working for many companies in the last years, only once devcontainer was a thing and it was for compatibility purpose with a library which wasn’t installable on nowdays OSes. The general case I had was:
- n projects, all of them with different tooling, different way of running tasks
.vscode/tasks.json
provided for VSCode users only, PyCharn, neovim, emacs, … users, do what you can (thanks for the VSCode tasks plugins, which by the way perfectly illustrate the benefit of a standard)- sometimes a Makefile, some other a Justfile… but everytime was an issue for windows users, or user not allowed to install some tooling on their computer (for
just
) - migration project on a single tool, tasks management in
pyproject.toml
is a requirement (for discovery and context switch reduction), ends by migrating topdm
orpoetry
+poe
- each newcomer onboarding, we had to spend time helping them just running those tasks (I know, a README should be enough, yes, but not everybody is updating them in case of change, so as the CONTRIBUTING, they are not always up to date)
On open-source side, contributing start by reading the CONTRIBUTING.{rst,md}
, half of the time, it’s not up to date. When it is, we often fallback on the previous case: platform specific tooling, mega-scripts not allowing to run just one tasks…
The point is not about requiring or expecting tools to exist, the point is about allowing tools willing to share a standard way of describing tasks. In the gist I shared, I compared 4 tools defining the same thing in a slightly different way. Since then, I have seen 3 more, which all have their definitions. So we have 7 redefined ways of expressing the same general concept, and they redefine each time because it’s missing (same as project metadata before PEP 621).
As a consequence, not a single tool tries to integrate those tasks.
If you look at the JavaScript world, all the tools without exception are using package.json
scripts
:
- IDE can discover and execute them
- general tooling document how to add their tool as a script
- CI jobs accept a
script
parameter yarn
,pnpm
,lerna
or any project management tool did not redefine tasks, they just usepackage.json
scripts
I can also give a real example, because tox
is often coming in the discussion. I use it mostly for testing against multiple Python versions. To do that and avoid duplicating both dependencies and scripts, I use the tox-pdm
plugin (I wrote the pdm
script integration). Since dependency-groups
were officialized with PEP 735, I can use the same dependency declaration because both pdm
and tox
integrated it (while none of them were forced to). Since then, I only relied on tox-pdm
for script integration. There are 2 issues there:
- to do that, you actually need 1 plugin by package manager/script runner because without a common spec, you have to integrate each task definition model
- it creates extra maintenance with double upstream changes (
tox-pdm
needs to follow bothpdm
andtox
changes)
Having an official tasks
section definition would allow tox
to reuse tasks independently of the package manager used.
Note that the effort duplication on integration is not specific to tox
, you can see the same thing for VSCode tasks runners plugins, PyCharm…
On the dependencies’ topic, which I tried not to integrate (and I still think standardizing scripts does not involve their dependencies), I would say the way to go is to reuse as much as possible dependency groups. So I think it should look like one of:
# Only reusing dependency groups
[tasks.my_task]
dependencies = ["group1", "group2"]
# Allowing the full dependency group syntax
[tasks.other_task]
dependencies = [
"tox",
{use = "test"}
]
Personally, I prefer the first one as there is something entirely defined for that, and allowing the full syntax is more complexity and duplication of purpose.
I also, I think for this to work, “running tests” shouldn’t the only use case. In the company I work, we projects have between 10 and 20 tasks, running tests is only one of them and most definitively the special one as people want to run them quickly in integration with their specific IDE test tooling, CI often have a dedicated phase for it… Tests are a special case here and should be the base for specifying what is a development task (and they might need a PEP on their own if testing need to be standardized).
I can provide lots of use cases where tasks don’t involve testing and the operator is not necessarily a developer who has the ability to write full Python scripts (datascience being one of them).