PEP 621: round 3

OK, I don’t get to lay claim to the first PEP 621 package, then. Congrats to both of you!

Fairly naively. Following the recommendation in PEP 621, authors with email addresses go in Author-Email, and authors with just a name go in Author. So in that case, it wouldn’t be obvious in the resulting METADATA file that they were meant to be for two different people. You can see the relevant code in flit here.

Once PEP 621 is more widely adopted, someone who wants to automate getting author metadata might be better off fetching sdists and parsing the pyproject.toml, rather than trying to make sense of the essentially free-text fields in a METADATA file. So I’m not going to lose too much sleep over the potential ambiguity once it’s translated into METADATA.

1 Like

Either of you care to share how PEP 621 has worked for you? Other than all of us (re)discovering ambiguities in METADATA, has PEP 621 made sense, seemed to work well, etc.? I.e. did I help write a horrible PEP or does it seem okay? :wink:

1 Like

So far, I’ve been pretty happy with it. We’ll see how it goes as more people try to use it.

One question that I wondered about: what should a tool like Flit do if there are extra keys in the [project] table which it doesn’t recognise? I.e. is it meant to be extensible, and if so, will it be OK for implementations to ignore new keys, or should they bail out if there’s anything they don’t understand? For now, I’ve gone for a warning (“Unexpected names under [project]”) but no error.

Flit isn’t doing much with the license field at present - it includes a file if one is specified, but doesn’t put anything in the metadata for it. I understand we’re waiting on PEP 639 to define more precise ways of describing licenses in metadata (let’s not get into that question on this thread).

1 Like

The PEP says on this subject:

Tools MUST specify fields defined by this PEP in a table named [project]. No tools may add fields to this table which are not defined by this PEP or subsequent PEPs.

That to me says “error”, but you’re right it doesn’t explicitly say “error out”. @pf_moore what do you think?

IMO, the section you quoted, in conjunction with the paragraph just above that

When specifying project metadata, tools MUST adhere and honour the metadata as specified in this PEP. If metadata is improperly specified then tools MUST raise an error to notify the user about their mistake.

says to me that tools should flag an error if they see anything not defined by the PEP.

However, I think we could have an issue soon, because there’s no versioning of the format, so when a new metadata field is added (for example, License-Expression) we’re going to have to work out how to add that to pyproject.toml in a backward compatible manner. I’m sorry I didn’t spot this when I was reviewing the PEP for approval.

Getting a fix for this issue into the spec before too many people have implemented it might be worthwhile - we may have a small window where we can reach out to tools that have implemented the existing PEP without too much difficulty, so we may be able to manage the backward compatibility requirements somewhat.

We should also consider who is responsible for updating the PEP 621 definition when a new metadata item is added - maybe we should formally document the process for adding new metadata items, so it’s clear that pyproject.toml needs to be considered as well as the core metadata specs.

2 Likes

Do we need to?

Older tool versions not understanding newer keys and failing because of them is a much cleaner split (for explaining and understanding) than having it work the wrong way due to a subtlety.

As an example from our domain, older versions of pip don’t understand yanking (which causes it to not ignore those versions). This regularly shows up in discussions online and in pip’s issue tracker as a source of user confusion.

The trouble of the chicken-egg problem for adoption of new keys in this case is… fine?

The most troublesome tooling that would fail due to this is build tools, and those are opted into by the user (and their versions can be constrained with build-system.requires). Realistically, any supporting tooling would likely not be thoroughly validating all the values anyway, so it should be A-OK on that front as well?

FWIW, once a tool supports the newer keys of the format, it’ll still be able to read from older [project] tables; given that all new keys will definitely be optional. (if they aren’t, we can add a new key to denote the version when we make that change).

This should all be fine if you’re constraining the backend versions in build-system.requires, which is already showing up as best-practice among the various build backends anyway.

Mostly, I agree. But if flit (for example) were to say “projects specify their metadata using the [project] key in pyproject.toml (insert link to spec here)”, and a user looked at that spec, found license-expression, added it and got an error, they’d be justified in being confused and annoyed.

Maybe all that’s needed is for flit to document that it supports metadata 2.2, and when flit 3.3 is released, update the docs and have a changelog entry saying “Now supports metadata 2.3”. Along with a requirement that additions to the metadata spec must also update Declaring project metadata — Python Packaging User Guide to say what the pyproject.toml name of the new field is, that’s probably sufficient.

Yeah, OK. I was probably over-reacting (it was late when I posted!)

1 Like

I agree with Thomas. I’m not sure I would have done anything differently.

2 Likes

Will it be possible to use project.scripts section as scripts like in project.scripts. It would be nice to write pip run dev and got running dev server without bind onto a framework.

Kind of. Instead of doing it directly, you can add an extra for it and then make the entrypoint depend on that extra.

https://packaging.python.org/specifications/entry-points/#file-format

Unfortunately, this is not flexible enough. Also, this required from the install project. Can’t use it for Django projects as they won’t install.

license is not clear to me, quote from the specification:

The text key has a string value which is the license of the project.

It is unclear whether it is the full-text content or the license name. Core metadata recommends using trove classifiers instead of giving the license name in license field and I guess flit is following this. But both setuptools and poetry allows a short name in license field. And what names are legal is up to the package manager.

PEP 621 is in comparison to Core metadata which appears in the METADATA file in the wheel. However npm’s project scripts are not related to the distribution but development. So I think it is better to leave it to the package manager to define it, under [tool.<tool_nam>] namespace.

pdm has the support of user scripts in [tool.pdm.scripts] table:
https://pdm.fming.dev/usage/project.html#run-scripts-in-isolated-environment
and those scripts won’t appear as console_scripts in the distributon.

PEP 621 project.scripts is analogous to package.json’s bin field, not scripts. The analogous of scripts is for project management tools to define, and different tools use different tables; pdm uses tool.pdm.scripts as mentioned above.

It’s whatever Core metadata specifications - Python Packaging User Guide means to you. There’s a separate topic in PEP 639: Improving license clarity with better package metadata about more specific license metadata.

This also tripped me up when reading through the PEP so I think clarifying this sentence would be helpful. It is not clear to a reader without context what kind of text should or should not be put there.

Perhaps

The text key has a string value which is the license of the project. This may be anything the core metadata specification allows [link], such as a simple SPDX license identifier like “MIT”.

But assume that for everything in that PEP, it’s just a way to store stuff in TOML that will end up in the accompanying/specified field in METADATA.