Python3 error: initial_value must be str or None

When porting code from python2 to 3 I get this error when reading from URL

TypeError: initial_value must be str or None, not bytes.

 import urllib import json import gzip from urllib.parse import urlencode from urllib.request import Request service_url = 'https://babelfy.io/v1/disambiguate' text = 'BabelNet is both a multilingual encyclopedic dictionary and a semantic network' lang = 'EN' Key = 'KEY' params = { 'text' : text, 'key' : Key, 'lang' :'EN' } url = service_url + '?' + urllib.urlencode(params) request = Request(url) request.add_header('Accept-encoding', 'gzip') response = urllib.request.urlopen(request) if response.info().get('Content-Encoding') == 'gzip': buf = StringIO(response.read()) f = gzip.GzipFile(fileobj=buf) data = json.loads(f.read()) 

An exception is thrown on this line.

 buf = StringIO(response.read()) 

If I use python2, it works fine.

+37
python urllib2 urllib
Jun 26 '15 at 4:33
source share
3 answers

response.read() returns an instance of bytes , and StringIO is a text-only memory stream. Use BytesIO .

From What's New in Python 3.0 - Text Vs. Data instead of Unicode Vs. 8 bit

The StringIO and cStringIO gone. Instead, import the io module and use io.StringIO or io.BytesIO for text and data, respectively.

+69
Jun 26 '15 at 7:28
source share

This looks like another python3 bytes vs. issue str . Your answer is of type bytes (which is different from python 3 from str ). You need to enter it into the string first using response.read().decode('utf-8') and then use StringIO . Or you can use BytesIO , as someone said, but if you expect it to be str , the preferred way is decode at the beginning of str .

+14
Jun 26 '15 at 7:31 on
source share

Try using six.StringIO instead of io.StringIO.

0
Jul 08 '19 at 17:05
source share



All Articles