-
-
Notifications
You must be signed in to change notification settings - Fork 840
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
Form-encoded data with None
as the value gets passed as string "None"
#1500
Comments
Do you consider this a bug, or just "behaves differently"? |
Hi :) For some reason this rings a bell. Are we sure there are no previous issues about this? Otherwise yeah I think the "None" string is a bit surprising. I would advise validating this isn't specifically linked to HTTPBin, eg inspect what the actual request body looks like. |
Not marking as a bug yet because we'd also need to validate if "null values" make sense in the context of HTTP forms at all. If not, consider matching Requests by ignoring None fields? Or raising a loud error as "this is ambiguous"? |
From what I've seen, passing empty string instead of None works fine both for requests and httpx, and round-trips with httpbin. This is a perfectly fine workaround for me. However, for compatibility with requests, converting I've verified that the empty-string workaround works for the project I am currently working on, so it is not only a httpbin issue. I used httpbin to create a reproducible minimal example. Personally, I would be least surprised if httpx followed requests, since this is what the documentation promises. A loud error would be surprising but would not lead to silent failure, so in my view that would be acceptable. |
Relevant discussion for Scrapy appears to do the same as requests:
https://docs.scrapy.org/en/latest/topics/request-response.html#scrapy.http.FormRequest.from_response The async with aiohttp.request('POST', url, data=data) as resp_aiohttp:
pprint(await resp_aiohttp.json()) yields:
|
@pletnes Thanks, those are very useful pointers. :-) As to why this happens: When Lines 106 to 113 in f3c2941
So our behavior essentially boils down to the stdlib doing this: >>> from urllib.parse import urlencode
>>> urlencode({"foo": None, "bar": "baz"})
'foo=None&bar=baz' I think that's somewhat undefined behavior, since the docs read:
>>> class Spy:
... def __str__(self):
... print('Gotcha')
... return 'Spy()'
...
>>> urlencode({'foo': Spy()})
Gotcha
'foo=Spy%28%29' From this, it means that any non-str/bytes value will yield unexpected results, such as passing a custom object (like above), passing Actually the Anyway, I sense head-scratching ahead, so I'd be tempted to keep things as-is for simplicity. (Plus, I believe issues around special-casing values like |
Other relevant threads:
#175 resolved #154 by treating Lines 59 to 71 in c725387
Which we use in Line 450 in 8696405
We might consider applying the same transformation in |
I see several sensible options - clearly the |
Personally I think requests' behaviour here is unintuitive.
Yes that'd be my strong preference too. |
Checklist
master
.Describe the bug
When posting form data using
requests
and the form value isNone
, nothing is passed. Withhttpx
, theNone
is converted to the string"None"
.To reproduce
Expected behavior
requests
, since "broadly" the behavior is expected to match"None"
would be passed, rather e.g. an empty string might make sense?Actual behavior
The passed form-encoded data contains the string "None"
Debugging material
None, but see code example
Environment
Ubuntu 20.04 docker image
Additional context
Writing a PoC to replace
requests
withhttpx
right here.https://github.com/SAP/cloud-pysec/blob/6e3f92fefb2e0dc4f3c99aa7ed5dc2d70e6734ba/sap/xssec/security_context.py#L511
The method
request_token_for_client
passesNone
as a default for "all scopes".The text was updated successfully, but these errors were encountered: