-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Newlines in the description
field produce a malformed PKG-INFO
#1390
Comments
I looked at this for about 10 minutes, and I'm still not sure where validation should happen for these options/metadata fields. From what I can tell, only a few of the options do any sort of validation, and even then only in distutils. So while I agree it would be nice for Setuptools to reject invalid metadata fields, it may not even have a good hook point to do so. Perhaps a hook could be added in Distribution.finalize_options. |
Do you think this would be best fixed in distutils? Such a fix would take (much) longer to reach users, but I don't think this foot-gun is very dangerous. |
@mgedmin I think at this point things are not really being fixed much in distutils. Some time soon we'll be removing setuptools' dependency on distutils and distutils will be deprecated entirely. |
Just wanted to point out that this is not limited to just the |
@di That's not great. I think we could reasonably add I see the options as:
I think I prefer 1 as least disruptive, but I'm ambivalent between 2 and 3. 2 is more explicit, but 3 creates less "churn" (since this will just be auto-magically fixed). |
I think #1 is probably not the right thing to do here, as the resulting field would still contain the extra (albeit escaped) newline characters, which would not be what the user wants. I think if we could do #2, it would be easy enough to just do #3 and avoid a possibly-confusing error message. |
@mgedmin @di Even a single newline at the end of the See https://pypi.org/project/zc.relation/1.1.post1/#files for such a malformed |
#262 was another case where a single newline at the end breaks I tend to think that "newlines are not allowed in that field" would be a clear enough error message to support option (2) for that case. However, if you go for the explicit options (1 or 3), note that |
We should fail hard for configurations that are invalid. There should be an error message that gives a clear indication on how to fix the problem. This is a developer API, and developers should deal with their broken code. We shouldn't try to guess-fix broken stuff. Do the fields/kwargs have an explicit specification of the data they expect? This should be enforced. The fields $ python3 setup.py sdist
ERROR: The "description" field requires a single line of text. Multi-line text was supplied.
Aborting. |
OK, anyone who wants to submit a PR, let's go with a hard-failure if newlines are found in fields other than I think the easiest way to do this is to implement the check right before |
I can do this -- if no-one else has already started. IIUC, I have to adapt the write_pkg_file pseudo-method, which is used to monkey patch the distutils implementation from the Python standard library. I'd really prefer to introduce a class for this that can encapsulate the validation logic for all values. It feels too much like spaghetti code, otherwise. I hope that's fine. |
One of my top priorities for this weekend's sprint is to move metadata validation logic out of Warehouse and into pypa/packaging for reuse elsewhere, and this would be a good example of "elsewhere". The API will likely behave a lot like how it's currently being used in Warehouse: there will be a class which is initialized with a If you want to move ahead with that assumption, we can probably just connect the dots later. |
@di I have some difficulties with the idea of passing in only a (flat) def write_pkg_file(self, file):
"""Write the PKG-INFO format data to a file object."""
metadata = Metadata(dict(
name=self.get_name(),
version=self.get_version(),
description=self.get_description(),
# ...
))
metadata.validate(throw_exception=True)
version = get_metadata_version(self)
file.write('Metadata-Version: %s\n' % version)
file.write('Name: %s\n' % metadata.name)
file.write('Version: %s\n' % metadata.version)
file.write('Summary: %s\n' % metadata.description)
# ... To avoid setting a validator for every single value we may set a "default" validator, and set individual validators with method calls, e.g. # ...
))
metadata.add_validator('default', single_line)
metadata.add_validator('long_description', multi_line)
metadata.add_validator('requires', check_requirements)
metadata.validate(throw_exception=True) Note that this splits up the value and its validation specification, and duplicates the metadata key. Instead, I'd rather specify the validator together with with the metadata item, e.g. metadata = Metadata(dict(
name=Value(self.get_name(), validator=single_line),
version=Value(self.get_version(), validator=single_line),
description=Value(self.get_description(), validator=multi_line),
# ...
)) Obviously, this is not particularly beautiful, but value and validation would be visible next to each other. Maybe there is a similar but better way. Any ideas? I've also noticed that there are quite a few |
@bittner Not sure I follow... The validator(s) would be part of the |
According to the TODO comment in the source, it's time to turn the warning into an exception. |
Try to fix this issue cookiecutter#1614 Info to fix find in: * https://setuptools.pypa.io/en/latest/userguide/declarative_config.html?highlight=setup.cfg * pypa/setuptools#1390 (reference)
Lots of our builds are AGAIN broken since this release, for various dependencies. I would have expect that setuptools does not hardly break for a simple escape all |
It seems like an unfortunate wart to carry to support transforming To be sure, Setuptools is not happy about breaking the builds. It's conceivable we could back out the removal and restore the Deprecation warning for an extended period. Would that help? |
IMHO, no need to act. Package maintainer should be able to fix it, is not that we didn't see this coming. |
It's not true, maintainers of those package can fix current code, but that will be only for "future" releases of one package, and not the already released one. It means that every other stack that relies on that package needs to be also upgrade their versions pinning to fix their own build pipelines. Indeed, as of today, builds are broken for nothing but a little metadata violation, i agree. So, yes, the best option indeed is a forever(and not an extent of the deprecation period) warning, i would be really fine with that. |
To make things clear, maybe a solution would be that what is not already uploaded to pypi can not be accepted, but what's already released should continue to be installable as it is already used in the wild. |
…uptools Currently many builds are broken with the newest setuptools This is because of pypa/setuptools#2870 See e.g. pypa/setuptools#1390 pypa/setuptools#2895 pypa/setuptools#2893
We discovered this accidentally by way of zopefoundation/zc.relation#4 (comment): if you pass a string containing newlines to the
description
argument ofsetup()
, setuptools will generate a malformed PKG-INFO.To reproduce:
(The contents of
blah.py
do not matter, but the file should exist.)Run
python setup.py sdist
and the inspecttest_package.egg-info/PKG-INFO
. For me, with setuptools 39.1.0, it looks like this:The extra newlines lead tools to treat the rest of the PKG-INFO as a long_description.
I would expect
setuptools
to complain about the newlines in thedescription
field, or at least escape them properly (i.e. prepend whitespace, like it does for thelong_description
field).The text was updated successfully, but these errors were encountered: