View Single Post
Old 01-09-2020, 10:21 AM   #11
DaltonST
Deviser
DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.DaltonST ought to be getting tired of karma fortunes by now.
 
DaltonST's Avatar
 
Posts: 2,265
Karma: 2090983
Join Date: Aug 2013
Location: Texas
Device: none
Simultaneously Supporting Calibre 4.6 & 4.99: Cheat Sheet

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

Last edited by DaltonST; 01-09-2020 at 12:32 PM. Reason: Tips
DaltonST is offline   Reply With Quote