I've ported 14 of my 15 GUI plugins such that they are simultaneously compatible with Calibre 4.6 and 4.99.3. During that tedious, lengthy and sometimes painful journey, I kept a list of frequent solutions to problems I encountered. I hope this helps folks.
Code:
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
from polyglot.builtins import as_bytes, as_unicode, codepoint_to_chr, is_py3, iteritems, map, only_unicode_recursive, range, unicode_type
from polyglot.io import PolyglotStringIO
if is_py3:
from queue import Queue
else:
from Queue import Queue
for k,v in iteritems(my_dict):
from calibre.utils.serialize import json_dumps, json_loads
if is_py3:
from html.parser import HTMLParser as myhtmlparser
else:
import HTMLParser
myhtmlparser = HTMLParser.HTMLParser
if is_py3:
from urllib.request import urlopen
from urllib.parse import urlencode
else:
from urllib import urlencode
from urllib2 import urlopen
if is_py3:
my_list = as_unicode(my_list)
else:
my_list = as_bytes(my_list)
my_list = ast.literal_eval(my_list)
if not isinstance(text,unicode_type): #unicode is a Py2 type; use Polyglot's unicode_type instead.
You will see a lot of these errors:
TypeError: a bytes-like object is required, not 'str'
TypeError: can only concatenate str (not "bytes") to str
Py3 redefined what a bytestring is internally:
The bytestring 'A' is this in Python 2: A
the bytestring 'A' is this in Python 3: (a 3 digit integer)
Python2 was very forgiving and helpful in converting bytestrings to and from unicode when, for example, concatenating them. It just did it silently, and was unknowingly taken for granted.
Python3 is not at all forgiving and not at all helpful in converting anything to anything. Hence, errors such as: 'TypeError: can only concatenate str (not "bytes") to str' will happen if you try to concatenate text with, for example, a bytes version of an integer. Ditto for doing a str.replace(x,y); both x and y must be strings, not bytestrings, since a str in Py3 is an instance of 'str', not 'bytes'.
DaltonST