Python3 json.dumps gives TypeError: keys must be a string

I have a simple web server written in Python3 (using classes from http.server ) which I am transferring from 2 to 3.

I have the following code:

 # More code here... postvars = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1) something.json_run(json.dumps(postvars)) 

What throws away:

 TypeError: keys must be a string 

Checking the data, I decided that parse_qs apparently encodes the keys as bytes, which throws an error ( json apparently doesn't like bytes).

 import json json.dumps({b'Throws error' : [b"Keys must be a string"]}) json.dumps({'Also throws error': [b'TypeError, is not JSON serializable']}) json.dumps({'This works': ['No bytes!']}) 

What is the best solution here? With Python 2, the code works fine because parse_qs uses str instead of bytes . My initial thought is that I probably need to write a JSON serializer. Not that it was difficult for something so simple, but I would prefer not to do it if I can do it the other way (for example, translate the dictionary to use strings instead of bytes).

+4
source share
1 answer

Firstly, the cgi.parse_qs function cgi.parse_qs deprecated and is just an alias for urllib.parse.parse_qs , you can configure your import path.

Secondly, you pass the byte string to the parsing method. If you go to a regular string (unicode), the parse_qs method parse_qs returns regular strings:

 >>> from urllib.parse import parse_qs >>> parse_qs(b'a_byte_string=foobar') {b'a_byte_string': [b'foobar']} >>> parse_qs('a_unicode_string=foobar') {'a_unicode_string': ['foobar']} 

So you need to first decode the byte string with the file in order to execute a regular string.

+2
source

All Articles