I'm porting a Python 2 application to Python 3. Currently running Python2.7 but, updating code to pass pylint --py3k
tests, I have run into a problem with this:
def json_resource_file(baseurl, jsondata, resource_info):
"""
Return a file object that reads out a JSON version of the supplied entity values data.
"""
response_file = StringIO()
json.dump(jsondata, response_file, indent=2, separators=(',', ': '), sort_keys=True)
response_file.seek(0)
return response_file
It works fine with:
from StringIO import StringIO
but StringIO.StringIO
doesn't exist in Python3 (according to pylint), so using:
from io import StringIO
I get an error: "TypeError: unicode argument expected, got 'str'" (This is running under Python 2 - I'm still preparing the ground, so to speak, and am not planning to use Python 3 until I have done as much preparation and testing as I can under Python 2.)
By way of some experimentation, I tried using BytesIO
from io
, but that gives a different error "TypeError: 'unicode' does not have the buffer interface".
Clearly, the Python2 version of json.dump is writing str
values to the supplied file object. I think the Python3 version of json.dump also writes str
(i.e. Unicode) values.
So my question is: is there an easy way to dump JSON to a StringIO memory buffer that works with Python 2 and 3?
I realize I could use json.dumps
and coerce the result to whatever type StringIO
expects, but that all seems rather heavy-handed.
I'm also using the following future imports as part of my porting process:
from __future__ import (unicode_literals, absolute_import, division, print_function)
Currently, a solution I'm thinking of is to test the python version and import a different version of StringIO
accordingly, but that would violate the "Use feature detection instead of version detection" principle.
In most of my code, using from io import StringIO
appears to work fine for situations that I use StringIO
. It's the specific case of using a StringIO
with json.dump
that has caused me a few problems.
Use six's StringIO
from six.moves import StringIO