Skip to content
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

TypeError: CaseInsensitiveDict is not JSON serializable #1380

Closed
woozyking opened this issue May 22, 2013 · 7 comments
Closed

TypeError: CaseInsensitiveDict is not JSON serializable #1380

woozyking opened this issue May 22, 2013 · 7 comments

Comments

@woozyking
Copy link

The recent change that makes header case insensitive dict makes it impossible to dump request headers into a JSON object.

To reproduce this issue:

>>> import requests
>>> r = requests.get("http://google.com")
>>> r.headers
CaseInsensitiveDict({'x-xss-protection': '1; mode=block', 'transfer-encoding': 'chunked', 'set-cookie': 'PREF=ID=12d7ece5ef3bf530:FF=0:TM=1369254983:LM=1369254983:S=c6aSx8zzedxojmb5; expires=Fri, 22-May-2015 20:36:23 GMT; path=/; domain=.google.ca, NID=67=pu4Hj0vWxZzqQ1L48tpF50mv0AI3igxPOMqq4AkfeLSORhKgdxMC8Eyv2iSm84UflzVXSTSaaddKx6KPM4NAWGd2JYIm95YPC3BWiJMZsSkj652Mvs4i5hk94weAz6Xz; expires=Thu, 21-Nov-2013 20:36:23 GMT; path=/; domain=.google.ca; HttpOnly', 'expires': '-1', 'server': 'gws', 'cache-control': 'private, max-age=0', 'date': 'Wed, 22 May 2013 20:36:23 GMT', 'p3p': 'CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."', 'content-type': 'text/html; charset=ISO-8859-1', 'x-frame-options': 'SAMEORIGIN'})
>>> import json
>>> json.dumps(r.headers)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 243, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: CaseInsensitiveDict({'x-xss-protection': '1; mode=block', 'transfer-encoding': 'chunked', 'set-cookie': 'PREF=ID=12d7ece5ef3bf530:FF=0:TM=1369254983:LM=1369254983:S=c6aSx8zzedxojmb5; expires=Fri, 22-May-2015 20:36:23 GMT; path=/; domain=.google.ca, NID=67=pu4Hj0vWxZzqQ1L48tpF50mv0AI3igxPOMqq4AkfeLSORhKgdxMC8Eyv2iSm84UflzVXSTSaaddKx6KPM4NAWGd2JYIm95YPC3BWiJMZsSkj652Mvs4i5hk94weAz6Xz; expires=Thu, 21-Nov-2013 20:36:23 GMT; path=/; domain=.google.ca; HttpOnly', 'expires': '-1', 'server': 'gws', 'cache-control': 'private, max-age=0', 'date': 'Wed, 22 May 2013 20:36:23 GMT', 'p3p': 'CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."', 'content-type': 'text/html; charset=ISO-8859-1', 'x-frame-options': 'SAMEORIGIN'}) is not JSON serializable
@woozyking
Copy link
Author

While this is not actually requests bug, it does break some use cases prior to the introduction of CaseInsensitiveDict usage.

@sigmavirus24
Copy link
Contributor

This is easily worked around by doing:

import requests
import json

r = requests.get(url)
headers_json = json.dumps(dict(r.headers))

Technically we could return any object that behaves like a dict without it being a dict, so I don't see this as much of a problem. What would be fantastic is if there were a __serialize__ method we could declare on objects so that modules like json could just reference that as the author of the object intends.

I'll defer to @Lukasa on this one though. I personally don't find this so offensive frankly but I'm not against changing it either.

@woozyking
Copy link
Author

Thank you @sigmavirus24. I'm aware of this workaround, I brought this up only because it broke existing code of mine (so possibly others' who haven't updated to 1.2.x).

I'm 👍 for a __serialize__. Magic methods are sometimes nice.

@sigmavirus24
Copy link
Contributor

Magic methods are so often nice. That's more of a pipe-dream than anything else. The stdlib json module is pretty much frozen except for bug fixes I think. I have to wonder if simplejson or itsdangerous would consider (or even already have) that kind of support.

@Lukasa
Copy link
Member

Lukasa commented May 22, 2013

I'm with @sigmavirus24 here. This is a pain, but the Case-Insensitive Dict is awesome.

As for magic methods, I think JSON will never add one. JSON should be round-trippable, e.g: json.loads(json.dumps(obj)) == obj. Allowing arbitrary serialisation breaks that functionality.

@woozyking, for what it's worth, if you find yourself doing this a lot, you can use a [custom JSON encoder with the default method defined](http://docs.python.org/2/library/json.html#json.JSONEncoder.default). Define the default` method such that it turns the Case-Insensitive Dict into a dict. Slightly less code repetition if you want it.

Sorry that we caused you this inconvenience, but I think things are going to stay as they are. Thanks so much for raising the issue though! 🍰

@Lukasa Lukasa closed this as completed May 22, 2013
@woozyking
Copy link
Author

@sigmavirus24 a quick test with the latest simplejson indicates that they don't have built-in resolution for this case.

@Lukasa fully understand.

@sigmavirus24
Copy link
Contributor

@Lukasa that's true. But it would still be convenient. :-P

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants