Using a `json.JSONDecoder` fails when simplejson is present
See original GitHub issueIt appears that when simplejson
is in the environment requests
preferentially imports it. However, the arguments accepted by JSONDecoder
are inconsistent between the standard library json
and simplejson
leading to errors when using the standard json.JSONDecoder
when simplejson
is in the environment.
Your documentation for response.json()
says:
Parameters: | **kwargs – Optional arguments that json.loads takes.
The documentation for json.loads
says:
json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
and
To use a custom JSONDecoder subclass, specify it with the cls kwarg; otherwise JSONDecoder is used. Additional keyword arguments will be passed to the constructor of the class.
I expected to be able to use a custom json.JSONDecoder
without issue and indeed this works on Python 2.7, but in Python 3.7 it fails.
I can see that the issue of preferentially importing simplejson
has been raised a few times e.g.
https://github.com/requests/requests/pull/2516
https://github.com/requests/requests/issues/3052
and that it is slated for removal in Requests 3, which I guess will resolve this issue.
If it is not possible to resolve this issue some other way in Requests 2.x then it would be nice if the documentation around response.json()
was updated to make it clear that the arguments to json.loads
could be either simplejson.loads
or the standard lib json.loads
depending on the environment since the preferential import is effectively undocumented and non-obvious.
Expected Result
A successful JSON load when using r.json(cls=json.JSONDecoder)
.
Actual Result
print(r.json(cls=json.JSONDecoder))
File ".../python3.7/site-packages/requests/models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File ".../python3.7/site-packages/simplejson/__init__.py", line 535, in loads
return cls(encoding=encoding, **kw).decode(s)
TypeError: __init__() got an unexpected keyword argument 'encoding'
Reproduction Steps
pip install requests
pip install simplejson
import json
import requests
r = requests.get('http://localhost:5984')
print(r.json(cls=json.JSONDecoder))
System Information
Note this issue does not occur in Python 2.7.x.
$ python -m requests.help
{
"chardet": {
"version": "3.0.4"
},
"cryptography": {
"version": ""
},
"idna": {
"version": "2.7"
},
"implementation": {
"name": "CPython",
"version": "3.7.0"
},
"platform": {
"release": "18.0.0",
"system": "Darwin"
},
"pyOpenSSL": {
"openssl_version": "",
"version": null
},
"requests": {
"version": "2.20.0"
},
"system_ssl": {
"version": "1000210f"
},
"urllib3": {
"version": "1.24"
},
"using_pyopenssl": false
}
Issue Analytics
- State:
- Created 5 years ago
- Reactions:8
- Comments:14 (3 by maintainers)
Top GitHub Comments
I ran into this problem when we added a third-party library that had a transitive dependency on
simplejson
. That consequently broke all of our error handling, becauserequests
now started throwingsimplejson.errors.JSONDecodeError
instead ofjson.JSONDecodeError
that we had catches for. Judging from the referenced issues above, more users are affected.Having the same issue as the user above.
requests
should just be using one or the another. Using either or conditionally only creates confusion.