-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Breaking change in 2.28.0 when using string enums as Headers (working in v2.27.1) #6159
Comments
I know it is easily solvable by making use of the |
Thanks for the report, @bonastreyair! So I think this is on the edge of support. Headers have always been defined to be a In the meantime, Requests has no special logic for Enums, so casting it to a string prior to calling Requests will not affect behavior. That would be the recommendation while we gauge impact. Otherwise, 2.27.1 will continue to work as it did originally. |
Here's another instance fwiw: taverntesting/tavern#788 |
We also have similar issues in company internal tools. |
No. It's not contradicting that because any time we magically convert things for users, it tends to be wrong about 50% of the time. Being explicit in our documentation hasn't been effective and these validity checks are designed to help users not send junk that will almost certainly not do what they want. Much of what has been explicitly described above either for narrow cases but not for everyone. Enums for example are not required to have a string values. How does one consistently string-ify it then? Support for people subclassing built-in types notorious for breaking those subclasses is also not a logical choice because again it will surprise people who try it by breaking in a weird way it doing the opposite of what they expect |
We encountered this same issue when passing header values whose type is a subclass of |
I wrote up a patch for this on Friday. I've been waiting to see how widely this approach is used, because we've only had 4 reports with ~75% of downloads (50 million/week) now using 2.28.0. I think this falls into a very niche usage, but I agree We're going to monitor for any other issues in 2.28.0 to determine if we need a patch release. I'd be willing to merge the fix above into that with a heavy caveat that this isn't strictly supported. Any breakages due to subclasses deviating in behavior from the base Long term, I think we're going to continue taking a much firmer stance on inputs because people do crazy things when the values aren't |
In our case we're interacting with Salesforce, whose API consists of XML messages. We parse a session ID out of the response from the authentication endpoint using Our fix was to cast the session ID to an actual |
Just want to add support for this issue by saying we are also having this issue. Our use is basically:
|
Using enums for header names is a common (and generally regarded as a good) practice. +1. In the Anyway, just trying to add one to the 'user engagement' since that was mentioned as a consideration in the 2.28.1 release. |
I don't believe anything in this change precludes the use of enums in your code. Requests is being explicit of what we accept. |
Also seeing this in an Ansible collection, since the test containers updated their requirements to allow a newer version of |
As explained in #6232 -> we use a string subclass to prevent secrets leaking in certain circumstances, i.e. in Stack Traces. Just converting them to |
To be clear, to convert it to a Also, you seem to be relying on this class to avoid leaking secrets in stack traces and assuming you/your colleagues will always remember to use it rather than looking for secrets in stack traces before allowing them to be printed to logs by using a formatter to ensure no secrets are printed ever (just to be safe). Defense in depth is always better than expecting a library to do something for you at one or two layers below you. |
Actually the Secret class is of course one of multiple layers. And of course we use loggers/formatters that prevent leaking secrets but enforcing that is much harder then wrapping secrets. Also other libraries follow a similar approach. For instance httpx for URLs: And actually requests does not (as far I found) convert the special class back to a normal string. def test_header_validation(self, httpbin):
"""Ensure prepare_headers regex isn't flagging valid header contents."""
class StringSubClass(str):
def __repr__(self):
return "Secret"
valid_headers = {
"foo": "bar baz qux",
"bar": b"fbbq",
"baz": "",
"qux": "1",
"sub": StringSubClass("VerySecret")
}
r = requests.get(httpbin("get"), headers=valid_headers)
for key in valid_headers.keys():
valid_headers[key] == r.request.headers[key]
# Ensure type is not modified
assert type(valid_headers[key]) == type(r.request.headers[key]) This modified test works as expected. Even the function So requests does not have to handle the secret any special. Consider the opposite: We tell our devs to use the To make the case more general again: Subclasses of strings are common for a number of reason, i.e. a json/xml/yaml libary that uses it to track formatting of a string, a a string enum, mark stuff a secret etc... I do not see a case in which both the I know that users of libs do crazy stuff but could you elaborate what kind of wrong "stringification" could happen if both checks are valid? |
@nateprewitt any news here? I really would love to see your patch applied. |
Quick ping here, looking over the proposed patch I don't see a good reason not to apply it, especially given that this kind of behavior actually violates the Python principle of 'duck typing'. It's unclear why Requests needs to be deeply coupled beyond |
you can resolve this issue by converting to a string before parsing it as a key to the headers directory headers = {CustomEnum.TRACE_ID: "90e85293-afd1-4b48-adf0-fa6daf02359e"} |
When using string enums as key values for the
headers
dict parameter withrequests.get()
function inv2.28.0
it raises anInvalidHeader
error but using previous versionv2.27.1
works well without any error. It seems there was an unexpected breaking change with that release.Expected Result
Dict keys for the headers parameter when using
requests.get()
are still valid if a string enum is used.Actual Result
Instead it raises an
InvalidHeader
error stating that:Reproduction Steps
System Information
The text was updated successfully, but these errors were encountered: