Repository navigation
Description
setuptools version
74.1.3 and 76.0.0
Python version
Python 3.13
OS
Fedora Linux
Additional environment information
No response
Description
I recently discovered that if a project has keywords specified as a multiline string, the METADATA file generated from it is invalid in the sense that the headers/body split happens on the wrong line.
Example project: https://foss.heptapod.net/python-libs/passlib/-/blob/branch/stable/setup.py?ref_type=heads#L93
But you can find more like this here: https://grep.app/search?f.lang=Python&q=keywords%3D%22%22%22
Metadata generated with setuptools 74.1.3:
Provides-Extra: bcrypt
Requires-Dist: bcrypt >=3.1.0 ; extra == 'bcrypt'
Provides-Extra: build_docs
Requires-Dist: sphinx >=1.6 ; extra == 'build_docs'
Requires-Dist: sphinxcontrib-fulltoc >=1.2.0 ; extra == 'build_docs'
Requires-Dist: cloud-sptheme >=1.10.1 ; extra == 'build_docs'
Provides-Extra: totp
Requires-Dist: cryptography ; extra == 'totp'
crypt md5-crypt
sha256-crypt sha512-crypt pbkdf2 argon2 scrypt bcrypt
apache htpasswd htdigest
totp 2fa
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Natural Language :: English
…
Here, the empty line ends the headers part, and the key/value pair below it are unreachable in a Message instance parsed by email.parser.
Metadata generated with setuptools 76.0.0:
Name: passlib
Version: 1.7.4
Summary: comprehensive password hashing framework supporting over 30 schemes
Home-page: https://passlib.readthedocs.io
Download-URL: https://pypi.python.org/packages/source/p/passlib/passlib-1.7.4.tar.gz
Author: Eli Collins
Author-email: [email protected]
License: BSD
Keywords: password secret hash security
crypt md5-crypt
sha256-crypt sha512-crypt pbkdf2 argon2 scrypt bcrypt
apache htpasswd htdigest
totp 2fa
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
…
There is no empty line here but the keyword header is not properly folded as a multiline header according to RFC 822 and therefore the result is the same - unreachable key/value pairs below it.
I know there were several discussions about the formatting of different fields so I'm not sure this is something to fix here or not. The documentation says that keywords can be:
comma-separated string providing descriptive meta-data.
so multiline string does not seem to be prohibited.
Expected behavior
setuptools could either fail with an error message saying that keywords are improperly formatted or automatically replace all newlines with a space.
How to Reproduce
- Build a wheel from one of the projects mentioned above.
- Unpack the wheel.
- Parse the
METADATAfile manually and check available keys.
Output
See the above examples.
Activity
abravalheri commentedon Mar 17, 2025
Hi @frenzymadness thank you very much for the report, would you like to submit a PR implementing the option
setuptools could either fail with an error message saying that keywords are improperly formatted?frenzymadness commentedon Mar 17, 2025
I'll take a look.
Ignore newlines when processing keywords/platforms
frenzymadness commentedon Mar 18, 2025
It turned out it's much easier to fix the behavior and it seems to be backward compatible as well. Also, stripping of the empty characters already happens during the processing if the newer specification with the commas is followed so this change should not break anything, fixes the broken behavior, and will annoy nobody.
Ignore newlines when processing keywords/platforms
Ignore newlines when processing keywords/platforms
Repair newline-separated keywords/platforms and deprecate the behavior
python3-setuptools: upgrade 83.0.0 -> 84.0.0
python3-setuptools: upgrade 83.0.0 -> 84.0.0
python3-setuptools: upgrade 83.0.0 -> 84.0.0
python3-setuptools: upgrade 83.0.0 -> 84.0.0
python3-setuptools: upgrade 83.0.0 -> 84.0.0
42 remaining items
MAINT: Bump the pip-deps group across 1 directory with 2 updates (#215)
Bump the python group in /python with 3 updates (#6686)
Bump setuptools from 83.0.0 to 84.0.0 (#283)
build(deps-dev): bump setuptools from 83.0.0 to 84.0.0 (#121)
build(deps): bump setuptools from 83.0.0 to 84.0.0 in /libs/unstructu…
Bump the python group in /python with 3 updates (#6686)
build(deps-dev): update setuptools requirement from >=77 to >=84.0.0 …
Build(deps-dev): Bump setuptools from 83.0.0 to 84.0.0 (frequenz-flos…
chore(deps-dev): bump setuptools from 83.0.0 to 84.0.0 (frequenz-flos…
build(deps-dev): bump setuptools from 83.0.0 to 84.0.0 (frequenz-flos…
chore(deps-dev): bump setuptools from 83.0.0 to 84.0.0 (frequenz-flos…
Bump setuptools from 82.0.1 to 84.0.0 (frequenz-floss#1452)
deps(deps-dev): update setuptools requirement from <82,>=80 to >=80,<…
chore(llamaindex-algenta): Update setuptools requirement from >=68.0 …
chore(maf-algenta): Update setuptools requirement from >=68.0 to >=84…