douban/pymesos

Python 3 bytes, string JSON problems

Closed this issue · 4 comments

Hi,

I might have stumbeled on a small bug concerning serialization. It seems that when running python 3.5

the encode_data method does not always work as expected as it return bytes and json expects string objects. For example if the executor does not speciy a uuid the default assignment lead to JSON serialization errors.

Adding a encode_data(uuid.uuid4().bytes).decode(), solves this. Adding the decode does not seem to break the code for python 2 .

The same problem is also present in the examples folder.

This can be reproduced by:

Python 3.5.1 |Anaconda 4.0.0 (64-bit)| (default, Dec  7 2015, 11:16:01) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from binascii import b2a_base64, a2b_base64
>>> import json
>>> json.dumps(b2a_base64("a").decode())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: a bytes-like object is required, not 'str'
>>> json.dumps(b2a_base64(b"a").decode())
'"YQ==\\n"'
>>> json.dumps(b2a_base64(b"a"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/anaconda3/lib/python3.5/json/__init__.py", line 230, in dumps
    return _default_encoder.encode(obj)
  File "/opt/anaconda3/lib/python3.5/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/opt/anaconda3/lib/python3.5/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/opt/anaconda3/lib/python3.5/json/encoder.py", line 180, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: b'YQ==\n' is not JSON serializable
>> json.dumps(b2a_base64(b"a").decode())
'"YQ==\\n"'

I am not sure if this is a bug or I am just misunderstanding something. If this is indeed a bug, adding a decode call to the encode method seems to fix the issue

This is definitely a bug, thank you.

we expect binascii.b2a_base64 in python 3 should return str, but in fact it returns bytes
we will fix this ASAP

Ok cool, I guess adding a decode at the end should not impact much?

yes, but we prefer add decode('ascii') inside enode_data than outside.

Ya thats what i ended up doing as well. Cheers.