Today I’ve noticed that one of the packages I’m maintaining on Conda-Forge had a new dependency that had no license declared: no license expression in the metadata, no license file in the distributions, no license comment in the code, and no homepage link. I don’t know if this affects PyPI itself, but to the best of my knowledge, redistributing such a package is problematic at least downstream.
This made me wonder: given that PEP 639 provides a clear way to declare package licenses, should we aim for PyPI to start rejecting uploads that do not declare any license information? I can’t think of a really good reason why anybody would upload a new distribution without license information declared, and this should prevent people from mistakenly missing that; especially that it may take some time before anybody actually looks close enough to notice a missing license.
No, PyPI has provisions in their terms that override the lack of license to allow at least redistribution (not necessarily modification or integration).
It’s complicated. Arguably the PyPI license covers “all other users of the Service” and so you could further redistribute if you got it from PyPI[1], but there’s probably no getting around someone finding the owner and asking for a license, either specifically for Conda-Forge, or one that the owner chooses to apply for all potential users.
Personally, I don’t want any more ways for uploads to fail.
A big ugly warning on the PyPI page and a simple follow-up instruction (“contact the package author if you need a license”) would have much the same effect.
The old version of the terms did not include the “all other users” grant, and I’m not sure whether it would actually work or not. You need a lawyer for that one. ↩︎
Not if the offending package is included in some other package’s dependencies. uv and pip will just happily install it without showing that warning to the user who initiated the install. (And that may not reach anyone when run in CI.)
Absolutely correct, but the same applies if someone adds a dependency on something that’s GPL (or stronger), and suddenly the “safe” package you chose to install has made it so your entire project must be distributed under the GPL.[1] This is part of how companies like Anaconda make their money - by auditing licenses and reporting everything that your users install, not just the top-level ones.
For PyPI, it’s really on the consumer to do the audit, but at some point in this whole process somebody looked at the offending package and chose whether they (and hence, their users) could use it or not. That’s the point where the label on the PyPI page helps.
It’s true that policing what people upload to PyPI in the first place would also help, but I’m not sure that license metadata would be considered legally binding anyway.[2] And if people start adding License-Expression: Unknown or Custom or whatever by default to avoid PyPI failing to upload, that is IMHO (slightly) worse than status quo - definitely not better.
There’s also clearly packages that already do this. Making their update uploads start to fail isn’t nice at all, and I’d rather we didn’t start with that approach.
Which I believe isn’t actually that scary, certainly since most Python code is naturally source-included, and there’s nothing stopping you redistributing your part under whatever license you want, provided you don’t bundle the dependencies. But that doesn’t mean your company lawyers don’t get scared. ↩︎
Certainly our $work lawyers use higher standards and independent data to determine the actual license of open-source software. ↩︎
As Steve says, my understanding is license metadata is at best “at a glance” informational. And users who have hard legal requirements should not use it beyond a fast dismissal of packages that claim to have licenses they are not compatible with.
I can’t speak for PyPI, but I don’t think making hard requirements on such nice to have metadata fields makes sense. But as a pip maintainer, I suspect we wouldn’t ever put a warning on such packages, I think it wouldl confuse users who don’t have any defined legal requirements, and users who do have defined legal requirements should be looking beyond the metadata anyway.
Usually the problem is I (or one of the users I represent) haven’t pinned their build backend version, and a new version comes out that aggressively enforces some change and the automated build breaks.[1]
There’s no real difference between whether the build backend fails or PyPI rejects the upload - only those who have been bitten before will make the packaging step part of their library’s test stage rather than their publishing stage, which is usually not going to be triggered until after everything is tagged/approved/etc. Changing the source code to fix it means restarting that entire process, and often leaves some dangling artifacts (such as source archives or symbols that were never released).
The best approach so far has been when PyPI sends an email after upload about a deprecated feature being used. I’d be quite okay with that happening for packages with no license metadata (even though I’m already the person who handles almost every single PyPI email for $work’s 1000+ packages).
Users filing bugs complaining about the lack of metadata is just as good as the emails from PyPI. Warnings during package build are okay, but don’t always get surfaced well (more my[/$work’s] fault rather than the build backends’, since their warnings probably are surfaced but are buried by our own noise that we haven’t taken care of).
So basically, I’d like it to be more reliable by the build backends doing and changing less, and more of these issues being treated as notifiable deprecations for as long as possible before they are actually broken.
Though this is also challenging because of the two “security” factions constantly fighting between “always pin all your dependencies” and “always update all your dependencies”… ↩︎