gunicorn
gunicorn copied to clipboard
unhandled exception via invalid configuration
Whenever "string %r" % single_arg is used, the string formatting can raise confusing exception whenever single_arg is a tuple with more than one item.
This is exposed via invalid configuration read from a python configuration file, or more likely and seriously because of the switched Exception argument type in https://github.com/benoitc/gunicorn/commit/7ebe442d089a6fe0c51abb19a598b3d0d6a6d128 whenever refusing requests based on their (parsed) version tuple. The latter affecting only the case where gunicorn can receive such requests (read: not sitting behind Nginx) and only the 22.0.0 release.
Solution: Make the argument string-only again, and for good measure wrap the string argument in a tuple unconditionally, which also helps with automatically converting it to "string {!r}".format(single_arg) or even f"string {single_arg!r}" later on.
- Fixes: https://github.com/benoitc/gunicorn/issues/3195
- Suggested merge order: merge https://github.com/benoitc/gunicorn/pull/3196 first (note: now that this is applied, this PR is reduced to stylistic issues and rare edge cases)
@pajod I think this PR should be merged instead of mine https://github.com/benoitc/gunicorn/pull/3196
What are the next steps to merge it?
@washeck I saw yours and would like to leave the maintainer with the option of applying your minimal fix + test, with or without bundling more extensive changes resolving much less important (and in most instances, purely stylistic) problems.
I suppose while no other steps are requested, it never hurts to review, test or discuss any of the other 99 open pull requests.
"string %r" % single_arg is used, the string formatting can raise confusing exception whenever single_arg is a tuple with more than one item.
I agree for this but why for %s ? I think using a tuple where we expect a simple string is kind of a little more confusing, verbose and not natural there when you read it.
I agree for this but why for
%s?
The magic happening for single-arg percent-formatting is not unique to %r:
Python 3.12.4 on linux
>>> "repr %r" % (1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
>>> "str %s" % (1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
verbose and not natural there when you read it
Agreed. Though %-formatting was never very natural to read, with arguments far away from where they go in the template. The good thing about at least using the unambiguous %-formatting is: that you can then view it in whichever form you want using automatic formatting - percent, string.format or f-string become interchangeable.