Apologies for the late reply here, but I only noticed it when @konstin was working on an implementation of this in uv.
I believe one limitation or perhaps ambiguity of the glob syntax defined here is that it’s not clear how to match literals like [ or ]. The usual way to escape things in a glob is, e.g., [*]. But if you want to match [ or ], then that becomes a bit awkward. One simple work-around is to treat [ or ] at the beginning of as literals. For example, [[] would match [ and []] would match ].
Matching a [ or a ] literal is a bit of an odd case though. So it might also be justifiable to say that it isn’t supported.
I’m waiting to hear Windows forbids [ somehow in a file path.
I think it’s okay to say that case is not generally supported and you might need special support from your build back-end (and when I say “special”, I mean something in the tool section of pyproject.toml).
Two questions working on this for pyproject-metadata:
If license.file is specified and the metadata version is 2.4+, the build backend is supposed to issue a warning and fill License-File with the file path. But what should it do with License? Also fill it with the contents, or leave it off? Unless I’m mistaken, the PEP seems to miss this detail.
The PEP states the license-files must be in the source distributions, but it also states:
The specified relative path MUST be consistent between project source trees, source distributions (sdists), built distributions (Wheels) and installed projects.
In the wheel and installed project, the base is technically different (dist-info/license), assuming this is accounted for. Just found it a little confusing.
Related question for the old License field, which gets filled with indented text when you read from a file (and is an email header, which technically doesn’t allow multiple lines of text) - would you except a trailing newline to be respected in the field, or would you expect the file to be stripped first? I changed the behavior in the upcoming release but am wondering if I should revert.
Yes, I can’t find a straightforward answer to this question in the PEP.
If you’re dealing with the obsolete dictionary values of the license key in pyproject.toml, License-Expression (which conflicts with the deprecated License) field will never happen. PEP doesn’t forbid performing the “legacy” transformations as they were done so far, so in my opinion you could generate License field as usual and optionally (but encouraged by SHOULD) use the file to populate the License-File field.
root license directory is defined in the PEP glossary as
Defined to be the project root directory for a project source tree or source distribution; and a subdirectory named licenses of the directory containing the built metadata— i.e., the .dist-info/licenses directory— for a Built Distribution or installed project.
The PEP states that license files are relative to the root license directory. So the base may be different and that’s accounted for, but the relative part of the path must be consistent across the artifacts.
That’s probably best visible in the examples: Appendix: Licensing Examples | peps.python.org
I don’t know if I would classify it as “missed” so much as “doesn’t take a position”.
The question is whether not defining it in dynamic in any way influences things? Since you can’t fill in both if you specify license in dynamic then I think it’s a gray area. I personally think back-ends can fill it in or leave it out.
But I will say the License field is a bit of a mess due to the lack of clear specification of how to do multi-line strings in METADATA (we really need to start transitioning to JSON).
We saw our first PEP 639 upload this morning, but unfortunately it appears that the handling of License-File metadata didn’t go as expected.
I opened an issue at PEP 639 followup · Issue #17105 · pypi/warehouse · GitHub to describe what happened and discuss what the correct handling should be. The summary is that PyPI expects a license_files field in the POST on upload and hatch (at least) is sending license_file.
While testing PEP 639 support in meson-python, I’ve tried to upload a package using Metadata 2.4 to testpypi and I discovered that twine does not support the latest metadata version yet. What ways exist to upload packages using Metadata 2.4 to PyPI?
Provisional is an optional “allow for lower overhead spec bug fixing” state prior to full acceptance, so it’s possible for there to be extra steps before the implementation is considered final (such as additional clients supporting a new feature).
In this case, the criteria for graduation from provisional status were comprehensive enough that the PEP can reasonably be considered final (since PyPI supports it and uploads have occurred using it).
Then we can either bother moving the PEP to Accepted now and move to Final once we have a successful upload or simply wait for that first success and jump straight to Final; either is fine with me.
Before moving to Final, we also need the spec merging into the Python Packaging User Guide, and the PEP updated with a banner pointing to the canonical spec:
Should we also wait for the PyPA recommended tools to upload packages to PyPI to be updated to support metadata version 2.4? As of now, twine does not support metadata version 2.4, thus gh-action-pypi-publish does not either. uv publish can upload packages using metadata 2.4, but it does not send the license-expression or license-file form fields, thus licensing information does not show up on PyPI.
We are ready for a new release of meson-python supporting PEP 639, but that would start to generate packages that cannot be uploaded to PyPI (or that can be uploaded without the metadata added by PEP 639 being visible on the package page on PyPI) making most of our users unhappy.
Working on metadata version 2.4 support in twine I found that, with the default configuration, setuptools generates metadata that is considered invalid by packaging and thus by PyPI. When setuptools find a file in the package matching any of these glob patterns LICEN[CS]E*, COPYING*, NOTICE*, AUTHORS*, it generates a corresponding License-File metadata field, however it sets Metadata-Version to 2.1. Same thing if pyproject.toml contains the provisional tool.setuptools.license-filesfield pointing to an existing file.
I don’t know how for how long the problem exists nor many packages are affected by this.
If PyPI keeps data about failed uploads, it could be interesting to see if how many failed for this reason.