diff --git a/applications/admin/controllers/appadmin.py b/applications/admin/controllers/appadmin.py index 2f780749..3060945c 100644 --- a/applications/admin/controllers/appadmin.py +++ b/applications/admin/controllers/appadmin.py @@ -10,6 +10,7 @@ import datetime import copy import gluon.contenttype import gluon.fileutils +from gluon._compat import iteritems try: import pygraphviz as pgv @@ -267,7 +268,7 @@ def select(): else: rows = db(query, ignore_common_filters=True).select( *fields, limitby=(start, stop)) - except Exception, e: + except Exception as e: import traceback tb = traceback.format_exc() (rows, nrows) = ([], 0) @@ -286,7 +287,7 @@ def select(): import_csv(db[request.vars.table], request.vars.csvfile.file) response.flash = T('data uploaded') - except Exception, e: + except Exception as e: response.flash = DIV(T('unable to parse csv file'), PRE(str(e))) # end handle upload csv @@ -454,7 +455,7 @@ def ccache(): except (KeyError, ZeroDivisionError): ram['ratio'] = 0 - for key, value in cache.ram.storage.iteritems(): + for key, value in iteritems(cache.ram.storage): if hp: ram['bytes'] += hp.iso(value[1]).size ram['objects'] += hp.iso(value[1]).count diff --git a/applications/admin/controllers/default.py b/applications/admin/controllers/default.py index fea3c3f7..b28c7626 100644 --- a/applications/admin/controllers/default.py +++ b/applications/admin/controllers/default.py @@ -15,6 +15,7 @@ from gluon.utils import web2py_uuid from gluon.tools import Config from gluon.compileapp import find_exposed_functions from glob import glob +from gluon._compat import iteritems, PY2 import shutil import platform @@ -81,7 +82,10 @@ def safe_open(a, b): def close(self): pass return tmp() - return open(a, b) + if PY2 or 'b' in b: + return open(a, b) + else: + return open(a, b, encoding="utf8") def safe_read(a, b='r'): @@ -314,7 +318,7 @@ def site(): if FILTER_APPS: apps = [f for f in apps if f in FILTER_APPS] - apps = sorted(apps, lambda a, b: cmp(a.upper(), b.upper())) + apps = sorted(apps, key=lambda a: a.upper()) myplatform = platform.python_version() return dict(app=None, apps=apps, myversion=myversion, myplatform=myplatform, form_create=form_create, form_update=form_update) @@ -1152,7 +1156,7 @@ def design(): # Get all languages langpath = os.path.join(apath(app, r=request), 'languages') languages = dict([(lang, info) for lang, info - in read_possible_languages(langpath).iteritems() + in iteritems(read_possible_languages(langpath)) if info[2] != 0]) # info[2] is langfile_mtime: # get only existed files @@ -1288,7 +1292,7 @@ def plugin(): # Get all languages languages = sorted([lang + '.py' for lang, info in - T.get_possible_languages_info().iteritems() + iteritems(T.get_possible_languages_info()) if info[2] != 0]) # info[2] is langfile_mtime: # get only existed files diff --git a/applications/admin/views/default/ticket.html b/applications/admin/views/default/ticket.html index 2b9a73b1..eb26c849 100644 --- a/applications/admin/views/default/ticket.html +++ b/applications/admin/views/default/ticket.html @@ -122,7 +122,7 @@ {{=XML(snapshot.get('response','no response available in snapshot'))}} -{{except Exception, e:}} +{{except Exception as e:}} {{import traceback;tb=traceback.format_exc().replace("\n","\\n") }} diff --git a/applications/admin/views/default/ticket.load b/applications/admin/views/default/ticket.load index 381eee1d..9a42bba3 100644 --- a/applications/admin/views/default/ticket.load +++ b/applications/admin/views/default/ticket.load @@ -117,7 +117,7 @@
session
{{=BEAUTIFY(snapshot['session'])}}
response
{{=BEAUTIFY(snapshot['response'])}}
-{{except Exception, e:}} +{{except Exception as e:}} {{import traceback;tb=traceback.format_exc().replace("\n","\\n") }} diff --git a/applications/admin/views/layout.html b/applications/admin/views/layout.html index 748f8f6e..5203dfc6 100644 --- a/applications/admin/views/layout.html +++ b/applications/admin/views/layout.html @@ -61,7 +61,7 @@ {{if hasattr(T,'get_possible_languages_info'):}} - {{=T('Admin language')}} diff --git a/applications/examples/controllers/appadmin.py b/applications/examples/controllers/appadmin.py index 2f780749..3060945c 100644 --- a/applications/examples/controllers/appadmin.py +++ b/applications/examples/controllers/appadmin.py @@ -10,6 +10,7 @@ import datetime import copy import gluon.contenttype import gluon.fileutils +from gluon._compat import iteritems try: import pygraphviz as pgv @@ -267,7 +268,7 @@ def select(): else: rows = db(query, ignore_common_filters=True).select( *fields, limitby=(start, stop)) - except Exception, e: + except Exception as e: import traceback tb = traceback.format_exc() (rows, nrows) = ([], 0) @@ -286,7 +287,7 @@ def select(): import_csv(db[request.vars.table], request.vars.csvfile.file) response.flash = T('data uploaded') - except Exception, e: + except Exception as e: response.flash = DIV(T('unable to parse csv file'), PRE(str(e))) # end handle upload csv @@ -454,7 +455,7 @@ def ccache(): except (KeyError, ZeroDivisionError): ram['ratio'] = 0 - for key, value in cache.ram.storage.iteritems(): + for key, value in iteritems(cache.ram.storage): if hp: ram['bytes'] += hp.iso(value[1]).size ram['objects'] += hp.iso(value[1]).count diff --git a/applications/examples/controllers/soap_examples.py b/applications/examples/controllers/soap_examples.py index 7840105e..2d091e80 100644 --- a/applications/examples/controllers/soap_examples.py +++ b/applications/examples/controllers/soap_examples.py @@ -44,7 +44,7 @@ def test_soap_sub(): try: ret = client.SubIntegers(a=3, b=2) result = ret['SubResult'] - except SoapFault, sf: + except SoapFault as sf: result = sf response.view = "soap_examples/generic.html" return dict(xml_request=client.xml_request, diff --git a/applications/examples/models/markmin.py b/applications/examples/models/markmin.py index 3376bac6..0370df95 100644 --- a/applications/examples/models/markmin.py +++ b/applications/examples/models/markmin.py @@ -28,7 +28,7 @@ def get_content(b=None, try: openedfile = openfile() - except Exception, IOError: + except (Exception, IOError): l = 'en' openedfile = openfile() diff --git a/applications/welcome/controllers/appadmin.py b/applications/welcome/controllers/appadmin.py index ddb02548..3060945c 100644 --- a/applications/welcome/controllers/appadmin.py +++ b/applications/welcome/controllers/appadmin.py @@ -10,6 +10,7 @@ import datetime import copy import gluon.contenttype import gluon.fileutils +from gluon._compat import iteritems try: import pygraphviz as pgv @@ -454,7 +455,7 @@ def ccache(): except (KeyError, ZeroDivisionError): ram['ratio'] = 0 - for key, value in cache.ram.storage.iteritems(): + for key, value in iteritems(cache.ram.storage): if hp: ram['bytes'] += hp.iso(value[1]).size ram['objects'] += hp.iso(value[1]).count diff --git a/gluon/compileapp.py b/gluon/compileapp.py index b6bbda79..1a55c3bc 100644 --- a/gluon/compileapp.py +++ b/gluon/compileapp.py @@ -18,7 +18,7 @@ import fnmatch import os import copy import random -from gluon._compat import builtin, PY2, unicodeT, to_native, basestring +from gluon._compat import builtin, PY2, unicodeT, to_native, to_bytes, iteritems, basestring from gluon.storage import Storage, List from gluon.template import parse_template from gluon.restricted import restricted, compile2 @@ -395,6 +395,11 @@ _base_environment_['SQLField'] = Field # for backward compatibility _base_environment_['SQLFORM'] = SQLFORM _base_environment_['SQLTABLE'] = SQLTABLE _base_environment_['LOAD'] = LOAD +# For an easier PY3 migration +_base_environment_['PY2'] = PY2 +_base_environment_['to_native'] = to_native +_base_environment_['to_bytes'] = to_bytes +_base_environment_['iteritems'] = iteritems def build_environment(request, response, session, store_current=True): """ diff --git a/gluon/http.py b/gluon/http.py index a0273866..e34fb8f0 100644 --- a/gluon/http.py +++ b/gluon/http.py @@ -110,7 +110,7 @@ class HTTP(Exception): if status[:1] == '4': if not body: body = status - if isinstance(body, str): + if isinstance(body, (str, bytes, bytearray)): headers['Content-Length'] = len(body) rheaders = [] for k, v in iteritems(headers): @@ -121,7 +121,7 @@ class HTTP(Exception): responder(status, rheaders) if env.get('request_method', '') == 'HEAD': return [''] - elif isinstance(body, str): + elif isinstance(body, (str, bytes, bytearray)): return [body] elif hasattr(body, '__iter__'): return body