PEP 621: round 3

Awesome. So, assuming that the sdist metadata discussion goes through, and we drop the “update pyproject.toml file” section from this draft; would we be good to go here?

My main reservation remains “is this sufficiently useful to standardise”? Remember, this is being proposed as a standards-track PEP, so it’s saying that backends must respect it. We know that Poetry won’t be doing so for some time yet, and setuptools has major backward compatibility reasons to take quite some time to fully switch, so it feels like it could be another PEP that sits around with limited support for ages.

Even without backends enriching the data, I don’t think there’s anything wrong with the proposal.

I guess I’m just concerned that as a community, Python packaging is generating PEPs faster than we’re implementing them, and I don’t think that gives us a good image in terms of stability.

1 Like

setuptools has major backward compatibility reasons to take quite some time to fully switch

I think setuptools can add support for this fairly quickly[citation needed] but the adoption will obviously be slower, which is expected and A-OK to me. I don’t expect that all the world will be on this format in 20251 even if we adopt+implement+publicise it in 2020. I think improvements taking a while to percolate out is the nature of things here and shouldn’t be why we can’t introduce a fully-backwards-compatible improvement (we’re still supporting Python 2 in pip!).

Even if poetry doesn’t adopt this, it’ll be a yet-another case of poetry not complying with the specs, which is also fine by me. flit, hatch etc can still add support for it.

1 Yes, of course, I’m assuming that human civilization makes it to 2025 fairly intact. :slight_smile:

This is true, though it would be good to message it as “each PEP is a discussion about one aspect, not recreating the whole system”.

This is probably something to clarify, but I never thought that this PEP should be mandatory and binding on backends, just that this is the spec for the [project] table. In other words, in order to be a backend you don’t need to support PEP 621, but if you use the [project] table you must implement the whole spec.

I don’t really think it needs to be mandatory — I think that the benefits of standardization will accrue to both the authors of backends (free documentation, possibly free implementation, etc) and individual users (their data is easier to parse for their own personal reasons or for things like dependabot) to a sufficient degree that using the PEP 621 spec will be a natural choice for most if not all backends anyway, with possibly poetry and flit being the exceptions, since they already have declarative configuration in pyproject.toml that they may already be satisfied with.

I don’t think setuptools will be able to make this “the only way to do things” for an absurdly long time if ever because setuptools still needs to be able to build random projects on PyPI and github that are unmaintained or under-maintained. That said, we can try to provide tools that would automatically convert setup.cfg and/or over to pyproject.toml inputs, and generally try and make some noise about converting.

My reading of the “room” is that even with the sdist bit pulled out, PEP 621 is, at best, a recommended format for tools to use in their pyproject.toml, but otherwise lacks enthusiasm enough to keep it going. As such, I am planning to reject my PEP by Friday before I finish at the core dev sprints unless people can convince me not to do that.

If projects choose to take PEP 621 for inspiration for how to lay out their metadata, great! If the dynamic idea and this discussion leads to finally standardizing sdists, great! Either of those outcomes makes the past 7.5 months of working on this not (entirely) wasted.

But my takeaway will be that trying to standardize anything that involves UX is a no-go in Python’s packaging ecosystem. And that’s fine and at least a lesson learned in general. That does mean that probably focusing standards towards build artifacts like standardizing sdists and APIs like PEP 517 to drive tools are a better use of time going forward.


Can we at least turn it into an Informational PEP that can be updated? It’s bonkers that when new metadata fields are added all backend maintainers will individually be burdened with how to name, represent, etc. or form some mechanism to talk to each other to form consensus.

I’d say that there is a standing expectation that “all build tools are expected to accept this format as input”. If they don’t, they’re not PEP 621 compliant and cannot use the [project] for metadata. This is similar to how certain tools don’t follow certain interoperability specifications (eg: poetry + PEP 440).

The difference between your phrasing and mine, AFAICT, is that tools are expected to implement this standard.

@brettcannon I don’t think this PEP should be rejected, and would request you to reconsider. It is already status-quo that certain tools may not adopt new standards immediately, and we don’t need to make this the “only possible way” for specifying metadata for tooling.

I’ve been thinking of this as a “tools are expected to implement this” standard and serving as the way we all agree to represent metadata in a pyproject.toml file. If some backends don’t implement them, they’re not following an interoperability standard, which is a choice all backends have always had a choice to make. They can’t use the project table in exchange.

How quickly this gets adopted is also a function of the amount of effort + disruption that the changes could have (eg: PEP 592 – yanked – took quite a while to get implemented on PyPI’s end), and not really a reason to reject this PEP.

All the reasons for working on and collaborating on this specification are still unchanged as far as I can tell. Certain build backend have stated that they’ll be slow to implement this but I don’t think anyone has out-right opposed this PEP in it’s overall form. I still think with a few changes, this PEP will be good-to-go.


Sure, it could be like Sweden adopting the Euro, but that’s not an outcome I want. (And for those of you who don’t know the reference, Sweden joined the EU with legal requirement of adopting the Euro, but they left off a due date for that transition, so the expectation is Sweden will never actually switch to the Euro.)

But there is also non-zero cost to accepting the PEP as well. Not only do we take a table name in pyproject.toml, but we will have to keep the spec updated. If build tools choose not to adopt this in any time horizon then it’s a lot of wasted effort to keep it going.

Basically I don’t want this PEP accepted and me be implicitly expected to help keep it up-to-date for new metadata unless there’s a reasonable expectation of uptake someday. And this does somewhat hit you, @pradyunsg, in case we choose to upstream code to help manage reading this data in ‘packaging’ (i.e. provide the code to translate metadata from PEP 621 -> sdist -> wheel).

Anyway, I’ll think about it.

These seem like two contradictory statements. The first one indicates that everyone is expected to use PEP 621, but the second one indicates that the consequence of not being “PEP 621 compliant” is that they can’t implement PEP 621.

At the end of the day, I think what matters is whether we are going to build anything on top of this later that expects you to use PEP 621. If not, I don’t think we need to try and mandate an input format for every build tool out there, since we’re not exactly going to enforce it, and it will just be another thing for people to use as a cudgel against OSS maintainers doing their best. “You don’t use PEP 621, but PEP 621 says all build backends are expected to accept it as input!” Making proclamations of that sort instead of promoting our tool and letting it be taken up organically on its merits feels like it’s taking a shortcut that is not likely to win us any friends.

If there’s some plausible reason that we think we can’t move forward with the ecosystem unless everyone is using this thing, then I suppose it makes sense to require everyone to use it (and condition whatever these benefits are on it), but I think any such possibility is sufficiently remote and unlikely to occur that we can forego the requirement of adopting PEP 621 out of respect for backend authors’ right to choose the interface they want for their users.

And that’s the general feeling I was getting and why I was suggesting just rejecting the PEP.

The only other way I can think of phrasing this is PEP 621 is the suggested way projects let users specify metadata. Then any tooling coming from the PyPA that’s build-tool-agnostic would revolve around PEP 621 (without be exclusionary). If we tackle it from that perspective such that we assume newer build back-ends like Hatch from @ofek or whatever @steve.dower has cooked up use PEP 621 and the tooling we can provide to them for “free”, then that’s currently the only way I can see making PEP 621 worth it.

1 Like

Yes, I agree that that’s the way it would be “worth it”. PEP 621 would be saying, "You may use the project table to store your metadata if you do it this way.

Assuming a big backend like setuptools adopts PEP 621 (and I think if we can get @jaraco’s assent we can even put it in the PEP that at least setuptools will adopt this as a valid input method, to sweeten the pot), smaller backends can ride for free on some of the tooling that gets built around that (including implementation of a parser, etc). The benefit of making it a spec would be effectively imposing constraints on setuptools or other popular parsers that choose to implement the spec, in order to make it easier for competitors to provide a compatible product.

The counter-balancing narrative here would be that the same arguments could be made for standardizing everything about the packaging UX, so why are we doing this specifically for metadata and nothing else? The most satisfactory answer to that I have is that 90% of metadata is easy enough that most of us are mostly indifferent as to how it is specified, since it’s not a dimension we want or need any flexibility on.

We also have the option to turn this into a “community spec” as well. Even without an accepted PEP, we could turn this into a living document somewhere and get some backends to sign on to the “metadata charter”. The only difference would be that for the “community spec” we’d need to pick a different table name (and actually, we could probably just use a common table name in the tool namespace: tool.metadata or tool.project or something).


PEP 518 suggests that tool.x is owned by project x. If someone created a library for parsing PEP 621 metadata, they could use the library’s namespace for the metadata. Then any backends using that library don’t only get a parser, they also get a common namespace.

Regarding withdrawal¹ of the PEP, I think the uncertainty about how much backends are expected/required/allowed to implement the spec makes it fairly clear that we don’t have a good consensus on how to view that aspect of the PEP. Whether that’s the final blow to the PEP, I’m not yet sure - but I’d hope we don’t lose all of the work done in agreeing on the format. A community agreed format backed by a canonical library implementation would be a good way of ensuring that doesn’t happen.

¹ @brettcannon technically I think you would withdraw the PEP rather than rejecting it, as a process detail


So just to confirm, we’re recommending the PEP 621 format but tools will use their own namespace, is that right?

I think if this PEP gets rejected / withdrawn, I think the two best options are:

  1. Create a new tool called project, metadata or project-metadata that implements PEP 621, and then have everyone adopt [tool.project] / [tool.project-metadata] / whatever as the name for the table. It will be a bit awkward because people would only indirectly be using the nominal “tool”, but it would allow us to use a common table name.
  2. Move PEP 621 into a community repo as a versioned spec and recommend that people adopt it either as [tool.<backend>.project] or [tool.<backend>.metadata].

The upside to both of these is that by giving the PEP 621 format its own namespace rather than having it integrated into the namespace of the backend along with other backend options, it allows the spec to add fields in a purely backwards-compatible way (since we know that no one else is using them).

The downside to both of these is that I don’t think users have a great separation in their mind between what is “metadata” and what is project-specific configuration. This always confuses me in setup.cfg, where some stuff is specified in the [metadata] table and other stuff is specified in the [options] table, but I hope that for the most part people will be populating these tables from templates or something anyway, so hopefully it won’t be so bad.

The third option is to frame it as “if you’re a tool developer, here are the fields in [project] you may use. If you’re a user looking for help with your tool, don’t read this spec, go and read their documentation”.

There’s no way that tools are going to converge on the same place without a standard. Introspection tools are no worse off with the standard than without, and backends are better off because now they only have to come up with their own design for these metadata fields if they want to. I think that would mean reframing the proposal from “tools MUST do x, y, z” to “pyproject.toml’s project table may use these fields”.

The biggest concern is users thinking that this PEP is documentation. All we can do with that is keep telling them over and over again that their tool has the documentation, not the PEP.

This would basically be the “Benefits” section of the PEP. And it still feels weak to me (although I’m not a backend developer). Looking at it in terms of “how would having PEP 621 make a difference to me”, it feels like:

  • As a pip developer, I wouldn’t feel confident adding code to check pyproject.toml for metadata. It’s extra places to check, with what feels like a very low probability of finding something I can use, so overall it’s marginal at best, and likely a loss.
  • As a distribution analysis tool writer, it’s much the same story. I’m checking thousands of packages, looking for a pyproject.toml that’s likely to not be helpful is more overhead than I can accept.

So basically from those perspectives, PEP 621 is irrelevant to me. (In a future where everyone uses PEP 621, things look a little more positive, but the PEP has to get to that point based on other benefits).

I can only infer how backend developers would feel. Clearly setuptools is expecting some non-trivial gains here. Poetry is indifferent at best, actively against at worst. Flit seems mostly neutral (taking silence as “no real opinion”). You and @ofek seem interested.

So the reality feels like “Backends can pick up a pre-made metadata format (and if we’re lucky, a parsing library) for free”. If that is the justification, let’s just say so and see how that works out. As a side-effect, if the PEP is framed as essentially just for backend creators, end users may be less inclined to refer to it.

1 Like

Yep, you’re right.

I’m assuming you’re suggesting this so that it’s discoverable whether a tool is using PEP 621 based solely on the existence of an appropriate table name?

So is that saying withdraw the PEP but write code that implements the PEP so back-end developers have an off-the-shelf solution for letting users specify metadata?

If we go with option 1, where we create a tool that processes the metadata called “metadata” or whatever and use tool.metadata, then yes, that would be a benefit.

For option 2, we can’t know whether tool.<backend>.metadata is actually using PEP 621 or if that backend simply chose to have a table called metadata.

I suppose in the “community spec” we can allow the sub-table to be called something different in every backend, as long as we say that it must be its own sub-table, not simply mixed in with other options for your backend (in which case we run into the problem of namespace collisions if we ever want to add a field to the table).