Update Python 3 compatibility
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@
|
||||
Utility functions for the Admin application
|
||||
-------------------------------------------
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
+1
-1
@@ -988,7 +988,7 @@ class AuthAPI(object):
|
||||
requires = table_user[passfield].requires
|
||||
if not isinstance(requires, (list, tuple)):
|
||||
requires = [requires]
|
||||
requires = list(filter(lambda t: isinstance(t, CRYPT), requires))
|
||||
requires = [t for t in requires if isinstance(t, CRYPT)]
|
||||
if requires:
|
||||
requires[0] = CRYPT(**requires[0].__dict__) # Copy the existing CRYPT attributes
|
||||
requires[0].min_length = 0 # But do not enforce minimum length for the old password
|
||||
|
||||
+1
-1
@@ -619,7 +619,7 @@ class Cache(object):
|
||||
if user_agent_ is True:
|
||||
cache_key.append("%(is_mobile)s_%(is_tablet)s" % current.request.user_agent())
|
||||
else:
|
||||
cache_key.append(str(user_agent_.items()))
|
||||
cache_key.append(str(list(user_agent_.items())))
|
||||
if vars_:
|
||||
cache_key.append(current.request.env.query_string)
|
||||
if lang_:
|
||||
|
||||
+4
-4
@@ -18,7 +18,7 @@ import fnmatch
|
||||
import os, sys
|
||||
import copy
|
||||
import random
|
||||
from gluon._compat import builtin, PY2, unicodeT, to_native, to_bytes, iteritems, basestring, reduce, xrange, long, reload
|
||||
from gluon._compat import builtin, PY2, unicodeT, to_native, to_bytes, iteritems, integer_types, basestring, reduce, xrange, long, reload
|
||||
from gluon.storage import Storage, List
|
||||
from gluon.template import parse_template
|
||||
from gluon.restricted import restricted, compile2
|
||||
@@ -177,7 +177,7 @@ def LOAD(c=None, f='index', args=None, vars=None,
|
||||
else:
|
||||
raise TypeError("Unsupported times argument type %s" % type(times))
|
||||
if timeout is not None:
|
||||
if not isinstance(timeout, (int, long)):
|
||||
if not isinstance(timeout, integer_types):
|
||||
raise ValueError("Timeout argument must be an integer or None")
|
||||
elif timeout <= 0:
|
||||
raise ValueError(
|
||||
@@ -261,7 +261,7 @@ class LoadFactory(object):
|
||||
if args is None:
|
||||
args = []
|
||||
vars = Storage(vars or {})
|
||||
import globals
|
||||
from . import globals
|
||||
target = target or 'c' + str(random.random())[2:]
|
||||
attr['_id'] = target
|
||||
request = current.request
|
||||
@@ -631,7 +631,7 @@ def run_controller_in(controller, function, environment):
|
||||
raise HTTP(404,
|
||||
rewrite.THREAD_LOCAL.routes.error_message % badc,
|
||||
web2py_error=badc)
|
||||
environment['__symbols__'] = environment.keys()
|
||||
environment['__symbols__'] = list(environment.keys())
|
||||
code = read_file(filename)
|
||||
code += TEST_CODE
|
||||
ccode = compile2(code, filename)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from .markdown2 import *
|
||||
from gluon.html import XML
|
||||
from gluon._compat import to_unicode
|
||||
|
||||
def WIKI(text, encoding="utf8", safe_mode='escape', html4tags=False, **attributes):
|
||||
if not text:
|
||||
@@ -9,7 +10,7 @@ def WIKI(text, encoding="utf8", safe_mode='escape', html4tags=False, **attribute
|
||||
del attributes['extras']
|
||||
else:
|
||||
extras=None
|
||||
text = text.decode(encoding,'replace')
|
||||
text = to_unicode(text, encoding, 'replace')
|
||||
|
||||
return XML(markdown(text,extras=extras,
|
||||
safe_mode=safe_mode, html4tags=html4tags)\
|
||||
|
||||
+2
-2
@@ -57,8 +57,8 @@ def autoDetectXMLEncoding(buffer):
|
||||
secret_decoder_ring = codecs.lookup(encoding)[1]
|
||||
(decoded, length) = secret_decoder_ring(buffer)
|
||||
first_line = decoded.split("\n")[0]
|
||||
if first_line and first_line.startswith(u"<?xml"):
|
||||
encoding_pos = first_line.find(u"encoding")
|
||||
if first_line and first_line.startswith("<?xml"):
|
||||
encoding_pos = first_line.find("encoding")
|
||||
if encoding_pos != -1:
|
||||
# look for double quote
|
||||
quote_pos = first_line.find('"', encoding_pos)
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
|
||||
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from gluon._compat import xrange
|
||||
from gluon.utils import local_html_escape
|
||||
import re
|
||||
@@ -325,7 +325,7 @@ color: #A0A0A0;
|
||||
fa = ' '.join([key[1:].lower() for (key, value) in items if key[:1]
|
||||
== '_' and value is None] + ['%s="%s"'
|
||||
% (key[1:].lower(), str(value).replace('"', "'"))
|
||||
for (key, value) in attributes.items() if key[:1]
|
||||
for (key, value) in items if key[:1]
|
||||
== '_' and value])
|
||||
if fa:
|
||||
fa = ' ' + fa
|
||||
|
||||
+2
-3
@@ -9,7 +9,6 @@
|
||||
Template helpers
|
||||
--------------------------------------------
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import cgi
|
||||
import os
|
||||
@@ -35,8 +34,8 @@ regex_crlf = re.compile('\r|\n')
|
||||
join = ''.join
|
||||
|
||||
# name2codepoint is incomplete respect to xhtml (and xml): 'apos' is missing.
|
||||
entitydefs = dict(map(lambda k_v: (k_v[0], unichr(k_v[1]).encode('utf-8')), iteritems(name2codepoint)))
|
||||
entitydefs.setdefault('apos', u"'".encode('utf-8'))
|
||||
entitydefs = dict([(k_v[0], to_bytes(unichr(k_v[1]))) for k_v in iteritems(name2codepoint)])
|
||||
entitydefs.setdefault('apos', to_bytes("'"))
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
||||
+1
-3
@@ -326,9 +326,7 @@ def write_plural_dict(filename, contents):
|
||||
|
||||
|
||||
def sort_function(x):
|
||||
if sys.version_info.major == 3: # python 3 compatibility
|
||||
unicode = str
|
||||
return unicode(x, 'utf-8').lower()
|
||||
return to_unicode(x, 'utf-8').lower()
|
||||
|
||||
|
||||
def write_dict(filename, contents):
|
||||
|
||||
+6
-7
@@ -9,10 +9,9 @@
|
||||
The gluon wsgi application
|
||||
---------------------------
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
if False:
|
||||
import import_all # DO NOT REMOVE PART OF FREEZE PROCESS
|
||||
from . import import_all # DO NOT REMOVE PART OF FREEZE PROCESS
|
||||
import gc
|
||||
|
||||
import os
|
||||
@@ -249,7 +248,7 @@ class LazyWSGI(object):
|
||||
def app(environ, start_response):
|
||||
data = f()
|
||||
start_response(self.response.status,
|
||||
self.response.headers.items())
|
||||
list(self.response.headers.items()))
|
||||
if isinstance(data, list):
|
||||
return data
|
||||
return [data]
|
||||
@@ -486,10 +485,10 @@ def wsgibase(environ, responder):
|
||||
if request.ajax:
|
||||
if response.flash:
|
||||
http_response.headers['web2py-component-flash'] = \
|
||||
urllib2.quote(xmlescape(response.flash).replace(b'\n', b''))
|
||||
urllib_quote(xmlescape(response.flash).replace(b'\n', b''))
|
||||
if response.js:
|
||||
http_response.headers['web2py-component-command'] = \
|
||||
urllib2.quote(response.js.replace('\n', ''))
|
||||
urllib_quote(response.js.replace('\n', ''))
|
||||
|
||||
# ##################################################
|
||||
# store cookies in headers
|
||||
@@ -717,9 +716,9 @@ class HttpServer(object):
|
||||
if isinstance(interfaces, list):
|
||||
for i in interfaces:
|
||||
if not isinstance(i, tuple):
|
||||
raise "Wrong format for rocket interfaces parameter - see http://packages.python.org/rocket/"
|
||||
raise AttributeError("Wrong format for rocket interfaces parameter - see http://packages.python.org/rocket/")
|
||||
else:
|
||||
raise "Wrong format for rocket interfaces parameter - see http://packages.python.org/rocket/"
|
||||
raise AttributeError("Wrong format for rocket interfaces parameter - see http://packages.python.org/rocket/")
|
||||
|
||||
if path:
|
||||
# if a path is specified change the global variables so that web2py
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
import Tkinter
|
||||
except:
|
||||
if sys.version_info[0] == 2:
|
||||
import Tkinter as tkinter
|
||||
else:
|
||||
import tkinter
|
||||
except ImportError:
|
||||
Tkinter = None
|
||||
|
||||
|
||||
@@ -12,15 +16,15 @@ class MessageBoxHandler(logging.Handler):
|
||||
logging.Handler.__init__(self)
|
||||
|
||||
def emit(self, record):
|
||||
if Tkinter:
|
||||
if tkinter:
|
||||
msg = self.format(record)
|
||||
root = Tkinter.Tk()
|
||||
root = tkinter.Tk()
|
||||
root.wm_title("web2py logger message")
|
||||
text = Tkinter.Text()
|
||||
text = tkinter.Text()
|
||||
text["height"] = 12
|
||||
text.insert(0.1, msg)
|
||||
text.pack()
|
||||
button = Tkinter.Button(root, text="OK", command=root.destroy)
|
||||
button = tkinter.Button(root, text="OK", command=root.destroy)
|
||||
button.pack()
|
||||
root.mainloop()
|
||||
|
||||
@@ -30,6 +34,6 @@ class NotifySendHandler(logging.Handler):
|
||||
logging.Handler.__init__(self)
|
||||
|
||||
def emit(self, record):
|
||||
if Tkinter:
|
||||
if tkinter:
|
||||
msg = self.format(record)
|
||||
os.system("notify-send '%s'" % msg)
|
||||
|
||||
+1
-5
@@ -20,13 +20,9 @@ import re
|
||||
import datetime
|
||||
import platform
|
||||
from functools import reduce
|
||||
try:
|
||||
import cPickle as pickle
|
||||
except:
|
||||
import pickle
|
||||
from gluon.settings import global_settings
|
||||
from gluon import fileutils
|
||||
from gluon._compat import to_bytes
|
||||
from gluon._compat import to_bytes, pickle
|
||||
from pydal.contrib import portalocker
|
||||
|
||||
logger = logging.getLogger("web2py.cron")
|
||||
|
||||
@@ -15,7 +15,6 @@ routes.py supports two styles of URL rewriting, depending on whether 'routers' i
|
||||
Refer to router.example.py and routes.example.py for additional documentation.
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
+8
-39
@@ -5,14 +5,14 @@
|
||||
# Modified by Massimo Di Pierro
|
||||
|
||||
# Import System Modules
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import errno
|
||||
import socket
|
||||
import logging
|
||||
import platform
|
||||
from gluon._compat import iteritems, to_bytes, StringIO
|
||||
from gluon._compat import urllib_unquote, to_native
|
||||
from gluon._compat import iteritems, to_bytes, to_unicode, StringIO
|
||||
from gluon._compat import urllib_unquote, to_native, PY2
|
||||
|
||||
# Define Constants
|
||||
VERSION = '1.2.6'
|
||||
@@ -32,7 +32,7 @@ DEFAULTS = dict(LISTEN_QUEUE_SIZE=DEFAULT_LISTEN_QUEUE_SIZE,
|
||||
MIN_THREADS=DEFAULT_MIN_THREADS,
|
||||
MAX_THREADS=DEFAULT_MAX_THREADS)
|
||||
|
||||
PY3K = sys.version_info[0] > 2
|
||||
PY3K = not PY2
|
||||
|
||||
|
||||
class NullHandler(logging.Handler):
|
||||
@@ -40,39 +40,8 @@ class NullHandler(logging.Handler):
|
||||
def emit(self, record):
|
||||
pass
|
||||
|
||||
if PY3K:
|
||||
def b(val):
|
||||
""" Convert string/unicode/bytes literals into bytes. This allows for
|
||||
the same code to run on Python 2.x and 3.x. """
|
||||
if isinstance(val, str):
|
||||
return val.encode()
|
||||
else:
|
||||
return val
|
||||
|
||||
def u(val, encoding="us-ascii"):
|
||||
""" Convert bytes into string/unicode. This allows for the
|
||||
same code to run on Python 2.x and 3.x. """
|
||||
if isinstance(val, bytes):
|
||||
return val.decode(encoding)
|
||||
else:
|
||||
return val
|
||||
|
||||
else:
|
||||
def b(val):
|
||||
""" Convert string/unicode/bytes literals into bytes. This allows for
|
||||
the same code to run on Python 2.x and 3.x. """
|
||||
if isinstance(val, unicode):
|
||||
return val.encode()
|
||||
else:
|
||||
return val
|
||||
|
||||
def u(val, encoding="us-ascii"):
|
||||
""" Convert bytes into string/unicode. This allows for the
|
||||
same code to run on Python 2.x and 3.x. """
|
||||
if isinstance(val, str):
|
||||
return val.decode(encoding)
|
||||
else:
|
||||
return val
|
||||
b = to_bytes
|
||||
u = to_unicode
|
||||
|
||||
# Import Package Modules
|
||||
# package imports removed in monolithic build
|
||||
@@ -613,9 +582,9 @@ import socket
|
||||
import logging
|
||||
import traceback
|
||||
from threading import Lock
|
||||
try:
|
||||
if PY3K:
|
||||
from queue import Queue
|
||||
except ImportError:
|
||||
else:
|
||||
from Queue import Queue
|
||||
|
||||
# Import Package Modules
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from __future__ import print_function
|
||||
# The following code is not part of Rocket but was added to
|
||||
# web2py for testing purposes.
|
||||
|
||||
|
||||
+9
-11
@@ -8,7 +8,6 @@
|
||||
Background processes made simple
|
||||
---------------------------------
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
@@ -29,7 +28,7 @@ from json import loads, dumps
|
||||
from gluon import DAL, Field, IS_NOT_EMPTY, IS_IN_SET, IS_NOT_IN_DB, IS_EMPTY_OR
|
||||
from gluon import IS_INT_IN_RANGE, IS_DATETIME, IS_IN_DB
|
||||
from gluon.utils import web2py_uuid
|
||||
from gluon._compat import Queue, long, iteritems, PY2
|
||||
from gluon._compat import Queue, long, iteritems, PY2, to_bytes, string_types, integer_types
|
||||
from gluon.storage import Storage
|
||||
|
||||
USAGE = """
|
||||
@@ -417,8 +416,8 @@ def _decode_list(lst):
|
||||
return lst
|
||||
newlist = []
|
||||
for i in lst:
|
||||
if isinstance(i, unicode):
|
||||
i = i.encode('utf-8')
|
||||
if isinstance(i, string_types):
|
||||
i = to_bytes(i)
|
||||
elif isinstance(i, list):
|
||||
i = _decode_list(i)
|
||||
newlist.append(i)
|
||||
@@ -430,10 +429,9 @@ def _decode_dict(dct):
|
||||
return dct
|
||||
newdict = {}
|
||||
for k, v in iteritems(dct):
|
||||
if isinstance(k, unicode):
|
||||
k = k.encode('utf-8')
|
||||
if isinstance(v, unicode):
|
||||
v = v.encode('utf-8')
|
||||
k = to_bytes(k)
|
||||
if isinstance(v, string_types):
|
||||
v = to_bytes(v)
|
||||
elif isinstance(v, list):
|
||||
v = _decode_list(v)
|
||||
newdict[k] = v
|
||||
@@ -1572,7 +1570,7 @@ class Scheduler(MetaScheduler):
|
||||
"""
|
||||
from pydal.objects import Query
|
||||
sr, st = self.db.scheduler_run, self.db.scheduler_task
|
||||
if isinstance(ref, (int, long)):
|
||||
if isinstance(ref, integer_types):
|
||||
q = st.id == ref
|
||||
elif isinstance(ref, str):
|
||||
q = st.uuid == ref
|
||||
@@ -1623,7 +1621,7 @@ class Scheduler(MetaScheduler):
|
||||
Experimental
|
||||
"""
|
||||
st, sw = self.db.scheduler_task, self.db.scheduler_worker
|
||||
if isinstance(ref, (int, long)):
|
||||
if isinstance(ref, integer_types):
|
||||
q = st.id == ref
|
||||
elif isinstance(ref, str):
|
||||
q = st.uuid == ref
|
||||
@@ -1723,7 +1721,7 @@ def main():
|
||||
sys.path.append(path)
|
||||
print('importing tasks...')
|
||||
tasks = __import__(filename, globals(), locals(), [], -1).tasks
|
||||
print('tasks found: ' + ', '.join(tasks.keys()))
|
||||
print('tasks found: ' + ', '.join(list(tasks.keys())))
|
||||
else:
|
||||
tasks = {}
|
||||
group_names = [x.strip() for x in options.group_names.split(',')]
|
||||
|
||||
@@ -10,7 +10,7 @@ from gluon.html import TAG, XmlComponent, xmlescape
|
||||
from gluon.languages import lazyT
|
||||
import gluon.contrib.rss2 as rss2
|
||||
import json as json_parser
|
||||
from gluon._compat import long, to_native, unicodeT
|
||||
from gluon._compat import long, to_native, unicodeT, integer_types
|
||||
|
||||
have_yaml = True
|
||||
try:
|
||||
@@ -79,7 +79,7 @@ def custom_json(o):
|
||||
datetime.datetime,
|
||||
datetime.time)):
|
||||
return o.isoformat()[:19].replace('T', ' ')
|
||||
elif isinstance(o, (int, long)):
|
||||
elif isinstance(o, integer_types):
|
||||
return int(o)
|
||||
elif isinstance(o, decimal.Decimal):
|
||||
return str(o)
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@
|
||||
Web2py environment in the shell
|
||||
--------------------------------
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
@@ -95,7 +96,7 @@ def exec_environment(
|
||||
if pyfile:
|
||||
pycfile = pyfile + 'c'
|
||||
if os.path.isfile(pycfile):
|
||||
exec (read_pyc(pycfile), env)
|
||||
exec(read_pyc(pycfile), env)
|
||||
else:
|
||||
execfile(pyfile, env)
|
||||
return Storage(env)
|
||||
|
||||
+8
-8
@@ -717,7 +717,7 @@ class AutocompleteWidget(object):
|
||||
compact=table_rows.compact)
|
||||
elif settings and settings.global_settings.web2py_runtime_gae:
|
||||
rows = self.db(field.__ge__(kword) &
|
||||
field.__lt__(kword + u'\ufffd')
|
||||
field.__lt__(kword + '\ufffd')
|
||||
).select(orderby=self.orderby,
|
||||
limitby=self.limitby,
|
||||
*(self.fields + self.help_fields))
|
||||
@@ -1966,7 +1966,7 @@ class SQLFORM(FORM):
|
||||
|
||||
AUTOTYPES = {
|
||||
type(''): ('string', None),
|
||||
type(u''): ('string',None),
|
||||
type(''): ('string',None),
|
||||
type(True): ('boolean', None),
|
||||
type(1): ('integer', IS_INT_IN_RANGE(-1e12, +1e12)),
|
||||
type(1.0): ('double', IS_FLOAT_IN_RANGE()),
|
||||
@@ -2462,8 +2462,8 @@ class SQLFORM(FORM):
|
||||
filter1 = lambda f: isinstance(f, Field) and (f.type!='blob' or showblobs)
|
||||
filter2 = lambda f: isinstance(f, Field) and f.readable and f.listable
|
||||
for table in tables:
|
||||
fields += filter(filter1, table)
|
||||
columns += filter(filter2, table)
|
||||
fields += list(filter(filter1, table))
|
||||
columns += list(filter(filter2, table))
|
||||
for k, f in iteritems(table):
|
||||
if not k.startswith('_'):
|
||||
if isinstance(f, Field.Virtual) and f.readable:
|
||||
@@ -2549,7 +2549,7 @@ class SQLFORM(FORM):
|
||||
table = db[request.args[-2]]
|
||||
record = table(request.args[-1]) or redirect(referrer)
|
||||
if represent_none is not None:
|
||||
for field in record.iterkeys():
|
||||
for field in record.keys():
|
||||
if record[field] is None:
|
||||
record[field] = represent_none
|
||||
sqlformargs = dict(upload=upload, ignore_rw=ignore_rw,
|
||||
@@ -2676,7 +2676,7 @@ class SQLFORM(FORM):
|
||||
# the query should be constructed using searchable
|
||||
# fields but not virtual fields
|
||||
is_searchable = lambda f: f.readable and not isinstance(f, Field.Virtual) and f.searchable
|
||||
sfields = reduce(lambda a, b: a + b, [filter(is_searchable, t) for t in tables])
|
||||
sfields = reduce(lambda a, b: a + b, [list(filter(is_searchable, t)) for t in tables])
|
||||
# use custom_query using searchable
|
||||
if callable(searchable):
|
||||
dbset = dbset(searchable(sfields, keywords))
|
||||
@@ -2937,7 +2937,7 @@ class SQLFORM(FORM):
|
||||
paginator.append(LI(self_link('<<', 0)))
|
||||
if page > NPAGES:
|
||||
paginator.append(LI(self_link('<', page - 1)))
|
||||
pages = range(max(0, page - NPAGES), min(page + NPAGES, npages))
|
||||
pages = list(range(max(0, page - NPAGES), min(page + NPAGES, npages)))
|
||||
for p in pages:
|
||||
if p == page:
|
||||
paginator.append(LI(A(p + 1, _onclick='return false'),
|
||||
@@ -3426,7 +3426,7 @@ class SQLTABLE(TABLE):
|
||||
if not sqlrows:
|
||||
return
|
||||
REGEX_TABLE_DOT_FIELD = sqlrows.db._adapter.REGEX_TABLE_DOT_FIELD
|
||||
fieldmap = dict(zip(sqlrows.colnames, sqlrows.fields))
|
||||
fieldmap = dict(list(zip(sqlrows.colnames, sqlrows.fields)))
|
||||
tablemap = dict(((f.tablename, f.table) if isinstance(f, Field) else (f._table._tablename, f._table) for f in fieldmap.values()))
|
||||
for table in tablemap.values():
|
||||
pref = table._tablename + '.'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"""
|
||||
Unit tests for gluon.sqlhtml
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
@@ -56,7 +56,7 @@ def _prepare_exec_for_file(filename):
|
||||
elif os.path.split(filename)[1] == '__init__.py':
|
||||
filename = os.path.dirname(filename)
|
||||
else:
|
||||
raise 'The file provided (%s) does is not a valid Python file.'
|
||||
raise IOError('The file provided (%s) is not a valid Python file.')
|
||||
filename = os.path.realpath(filename)
|
||||
dirpath = filename
|
||||
while True:
|
||||
|
||||
@@ -252,11 +252,11 @@ class testResponse(unittest.TestCase):
|
||||
|
||||
def test_include_meta(self):
|
||||
response = Response()
|
||||
response.meta[u'web2py'] = 'web2py'
|
||||
response.meta['web2py'] = 'web2py'
|
||||
response.include_meta()
|
||||
self.assertEqual(response.body.getvalue(), '\n<meta name="web2py" content="web2py" />\n')
|
||||
response = Response()
|
||||
response.meta[u'meta_dict'] = {u'tag_name':'tag_value'}
|
||||
response.meta['meta_dict'] = {'tag_name':'tag_value'}
|
||||
response.include_meta()
|
||||
self.assertEqual(response.body.getvalue(), '\n<meta tag_name="tag_value" />\n')
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Unit tests for rewrite.py routers option"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import tempfile
|
||||
|
||||
@@ -551,12 +551,12 @@ class TestsForSchedulerAPIs(BaseTestScheduler):
|
||||
def isnotqueued(result):
|
||||
self.assertEqual(result.id, None)
|
||||
self.assertEqual(result.uuid, None)
|
||||
self.assertEqual(len(result.errors.keys()) > 0, True)
|
||||
self.assertEqual(len(list(result.errors.keys())) > 0, True)
|
||||
|
||||
def isqueued(result):
|
||||
self.assertNotEqual(result.id, None)
|
||||
self.assertNotEqual(result.uuid, None)
|
||||
self.assertEqual(len(result.errors.keys()), 0)
|
||||
self.assertEqual(len(list(result.errors.keys())), 0)
|
||||
|
||||
s = Scheduler(self.db)
|
||||
fname = 'foo'
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"""
|
||||
Unit tests for running web2py
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
import unittest
|
||||
|
||||
+27
-27
@@ -15,8 +15,9 @@ from functools import reduce
|
||||
from gluon._compat import pickle, thread, urllib2, Cookie, StringIO, urlencode
|
||||
from gluon._compat import configparser, MIMEBase, MIMEMultipart, MIMEText, Header
|
||||
from gluon._compat import Encoders, Charset, long, urllib_quote, iteritems
|
||||
from gluon._compat import to_bytes, to_native, add_charset
|
||||
from gluon._compat import to_bytes, to_native, add_charset, string_types
|
||||
from gluon._compat import charset_QP, basestring, unicodeT, to_unicode
|
||||
from gluon._compat import urllib2, urlopen
|
||||
import datetime
|
||||
import logging
|
||||
import sys
|
||||
@@ -902,13 +903,13 @@ class Recaptcha2(DIV):
|
||||
'secret': self.private_key,
|
||||
'remoteip': remoteip,
|
||||
'response': recaptcha_response_field,
|
||||
})
|
||||
}).encode('utf-8')
|
||||
request = urllib2.Request(
|
||||
url=self.VERIFY_SERVER,
|
||||
data=to_bytes(params),
|
||||
headers={'Content-type': 'application/x-www-form-urlencoded',
|
||||
'User-agent': 'reCAPTCHA Python'})
|
||||
httpresp = urllib2.urlopen(request)
|
||||
httpresp = urlopen(request)
|
||||
content = httpresp.read()
|
||||
httpresp.close()
|
||||
try:
|
||||
@@ -1037,7 +1038,7 @@ class AuthJWT(object):
|
||||
Example:
|
||||
def mybefore_authorization(tokend):
|
||||
if not tokend['my_name_is'] == 'bond,james bond':
|
||||
raise HTTP(400, u'Invalid JWT my_name_is claim')
|
||||
raise HTTP(400, 'Invalid JWT my_name_is claim')
|
||||
- max_header_length: check max length to avoid load()ing unusually large tokens (could mean crafted, e.g. in a DDoS.)
|
||||
|
||||
Basic Usage:
|
||||
@@ -1161,7 +1162,7 @@ class AuthJWT(object):
|
||||
b64h, b64b = body.split(b'.', 1)
|
||||
if b64h != self.cached_b64h:
|
||||
# header not the same
|
||||
raise HTTP(400, u'Invalid JWT Header')
|
||||
raise HTTP(400, 'Invalid JWT Header')
|
||||
secret = self.secret_key
|
||||
tokend = serializers.loads_json(to_native(self.jwt_b64d(b64b)))
|
||||
if self.salt:
|
||||
@@ -1172,11 +1173,11 @@ class AuthJWT(object):
|
||||
secret = to_bytes(secret, 'ascii', 'ignore')
|
||||
if not self.verify_signature(body, sig, secret):
|
||||
# signature verification failed
|
||||
raise HTTP(400, u'Token signature is invalid')
|
||||
raise HTTP(400, 'Token signature is invalid')
|
||||
if self.verify_expiration:
|
||||
now = time.mktime(datetime.datetime.utcnow().timetuple())
|
||||
if tokend['exp'] + self.leeway < now:
|
||||
raise HTTP(400, u'Token is expired')
|
||||
raise HTTP(400, 'Token is expired')
|
||||
if callable(self.before_authorization):
|
||||
self.before_authorization(tokend)
|
||||
return tokend
|
||||
@@ -1209,11 +1210,11 @@ class AuthJWT(object):
|
||||
orig_exp = orig_payload['exp']
|
||||
if orig_exp + self.leeway < now:
|
||||
# token already expired, can't be used for refresh
|
||||
raise HTTP(400, u'Token already expired')
|
||||
raise HTTP(400, 'Token already expired')
|
||||
orig_iat = orig_payload.get('orig_iat') or orig_payload['iat']
|
||||
if orig_iat + self.refresh_expiration_delta < now:
|
||||
# refreshed too long ago
|
||||
raise HTTP(400, u'Token issued too long ago')
|
||||
raise HTTP(400, 'Token issued too long ago')
|
||||
expires = now + self.expiration
|
||||
orig_payload.update(
|
||||
orig_iat=orig_iat,
|
||||
@@ -1259,7 +1260,7 @@ class AuthJWT(object):
|
||||
pass
|
||||
if token:
|
||||
if not self.allow_refresh:
|
||||
raise HTTP(403, u'Refreshing token is not allowed')
|
||||
raise HTTP(403, 'Refreshing token is not allowed')
|
||||
tokend = self.load_token(token)
|
||||
# verification can fail here
|
||||
refreshed = self.refresh_token(tokend)
|
||||
@@ -1277,9 +1278,9 @@ class AuthJWT(object):
|
||||
ret = {'token': self.generate_token(payload)}
|
||||
elif ret is None:
|
||||
raise HTTP(401,
|
||||
u'Not Authorized - need to be logged in, to pass a token '
|
||||
u'for refresh or username and password for login',
|
||||
**{'WWW-Authenticate': u'JWT realm="%s"' % self.realm})
|
||||
'Not Authorized - need to be logged in, to pass a token '
|
||||
'for refresh or username and password for login',
|
||||
**{'WWW-Authenticate': 'JWT realm="%s"' % self.realm})
|
||||
response.headers['Content-Type'] = 'application/json'
|
||||
return serializers.json(ret)
|
||||
|
||||
@@ -1303,9 +1304,9 @@ class AuthJWT(object):
|
||||
if token_in_header:
|
||||
parts = token_in_header.split()
|
||||
if parts[0].lower() != self.header_prefix.lower():
|
||||
raise HTTP(400, u'Invalid JWT header')
|
||||
raise HTTP(400, 'Invalid JWT header')
|
||||
elif len(parts) == 1:
|
||||
raise HTTP(400, u'Invalid JWT header, missing token')
|
||||
raise HTTP(400, 'Invalid JWT header, missing token')
|
||||
elif len(parts) > 2:
|
||||
raise HTTP(400, 'Invalid JWT header, token contains spaces')
|
||||
token = parts[1]
|
||||
@@ -2243,11 +2244,11 @@ class Auth(AuthAPI):
|
||||
if basic_auth_realm:
|
||||
if callable(basic_auth_realm):
|
||||
basic_auth_realm = basic_auth_realm()
|
||||
elif isinstance(basic_auth_realm, (unicode, str)):
|
||||
basic_realm = unicode(basic_auth_realm) # Warning python 3.5 does not have method unicod
|
||||
elif isinstance(basic_auth_realm, string_types):
|
||||
basic_realm = to_unicode(basic_auth_realm)
|
||||
elif basic_auth_realm is True:
|
||||
basic_realm = u'' + current.request.application
|
||||
http_401 = HTTP(401, u'Not Authorized', **{'WWW-Authenticate': u'Basic realm="' + basic_realm + '"'})
|
||||
basic_realm = '' + current.request.application
|
||||
http_401 = HTTP(401, 'Not Authorized', **{'WWW-Authenticate': 'Basic realm="' + basic_realm + '"'})
|
||||
if not basic or not basic[:6].lower() == 'basic ':
|
||||
if basic_auth_realm:
|
||||
raise http_401
|
||||
@@ -3574,7 +3575,7 @@ class Auth(AuthAPI):
|
||||
requires = table_user[passfield].requires
|
||||
if not isinstance(requires, (list, tuple)):
|
||||
requires = [requires]
|
||||
requires = list(filter(lambda t: isinstance(t, CRYPT), requires))
|
||||
requires = [t for t in requires if isinstance(t, CRYPT)]
|
||||
if requires:
|
||||
requires[0] = CRYPT(**requires[0].__dict__) # Copy the existing CRYPT attributes
|
||||
requires[0].min_length = 0 # But do not enforce minimum length for the old password
|
||||
@@ -4614,7 +4615,6 @@ class Crud(object): # pragma: no cover
|
||||
results = None
|
||||
return form, results
|
||||
|
||||
|
||||
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPCookieProcessor()))
|
||||
|
||||
|
||||
@@ -4632,7 +4632,7 @@ def fetch(url, data=None, headers=None,
|
||||
from google.appengine.api import urlfetch
|
||||
except ImportError:
|
||||
req = urllib2.Request(url, data, headers)
|
||||
html = urllib2.urlopen(req).read()
|
||||
html = urlopen(req).read()
|
||||
else:
|
||||
method = ((data is None) and urlfetch.GET) or urlfetch.POST
|
||||
while url is not None:
|
||||
@@ -5000,7 +5000,7 @@ class Service(object):
|
||||
elif r and not isinstance(r, types.GeneratorType) and isinstance(r[0], (dict, Storage)):
|
||||
import csv
|
||||
writer = csv.writer(s)
|
||||
writer.writerow(r[0].keys())
|
||||
writer.writerow(list(r[0].keys()))
|
||||
for line in r:
|
||||
writer.writerow([none_exception(v)
|
||||
for v in line.values()])
|
||||
@@ -5217,7 +5217,7 @@ class Service(object):
|
||||
def serve_xmlrpc(self):
|
||||
request = current.request
|
||||
response = current.response
|
||||
services = self.xmlrpc_procedures.values()
|
||||
services = list(self.xmlrpc_procedures.values())
|
||||
return response.xmlrpc(request, services)
|
||||
|
||||
def serve_amfrpc(self, version=0):
|
||||
@@ -5572,7 +5572,7 @@ class PluginManager(object):
|
||||
return self.__dict__[key]
|
||||
|
||||
def keys(self):
|
||||
return self.__dict__.keys()
|
||||
return list(self.__dict__.keys())
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self.__dict__
|
||||
@@ -5818,7 +5818,7 @@ class Wiki(object):
|
||||
settings.templates = templates
|
||||
settings.controller = controller
|
||||
settings.function = function
|
||||
settings.groups = auth.user_groups.values() \
|
||||
settings.groups = list(auth.user_groups.values()) \
|
||||
if groups is None else groups
|
||||
|
||||
db = auth.db
|
||||
@@ -5914,7 +5914,7 @@ class Wiki(object):
|
||||
if (auth.user and
|
||||
check_credentials(current.request, gae_login=False) and
|
||||
'wiki_editor' not in auth.user_groups.values() and
|
||||
self.settings.groups == auth.user_groups.values()):
|
||||
self.settings.groups == list(auth.user_groups.values())):
|
||||
group = db.auth_group(role='wiki_editor')
|
||||
gid = group.id if group else db.auth_group.insert(
|
||||
role='wiki_editor')
|
||||
|
||||
+4
-5
@@ -16,7 +16,6 @@ import datetime
|
||||
import time
|
||||
import cgi
|
||||
import json
|
||||
import urllib
|
||||
import struct
|
||||
import decimal
|
||||
import unicodedata
|
||||
@@ -437,7 +436,7 @@ class IS_IN_SET(Validator):
|
||||
self.multiple = multiple
|
||||
if isinstance(theset, dict):
|
||||
self.theset = [str(item) for item in theset]
|
||||
self.labels = theset.values()
|
||||
self.labels = list(theset.values())
|
||||
elif theset and isinstance(theset, (tuple, list)) \
|
||||
and isinstance(theset[0], (tuple, list)) and len(theset[0]) == 2:
|
||||
self.theset = [str(item) for item, label in theset]
|
||||
@@ -575,7 +574,7 @@ class IS_IN_DB(Validator):
|
||||
else:
|
||||
fields = [table[k] for k in self.fieldnames]
|
||||
ignore = (FieldVirtual, FieldMethod)
|
||||
fields = filter(lambda f: not isinstance(f, ignore), fields)
|
||||
fields = [f for f in fields if not isinstance(f, ignore)]
|
||||
if self.dbset.db._dbname != 'gae':
|
||||
orderby = self.orderby or reduce(lambda a, b: a | b, fields)
|
||||
groupby = self.groupby
|
||||
@@ -649,7 +648,7 @@ class IS_IN_DB(Validator):
|
||||
return (values, None)
|
||||
else:
|
||||
def count(values, s=self.dbset, f=field):
|
||||
return s(f.belongs(map(int, values))).count()
|
||||
return s(f.belongs(list(map(int, values)))).count()
|
||||
|
||||
if self.dbset.db._adapter.dbengine == "google:datastore":
|
||||
range_ids = range(0, len(values), 30)
|
||||
@@ -3533,7 +3532,7 @@ class IS_IPV4(Validator):
|
||||
if isinstance(value, str):
|
||||
temp.append(value.split('.'))
|
||||
elif isinstance(value, (list, tuple)):
|
||||
if len(value) == len(list(filter(lambda item: isinstance(item, int), value))) == 4:
|
||||
if len(value) == len([item for item in value if isinstance(item, int)]) == 4:
|
||||
temp.append(value)
|
||||
else:
|
||||
for item in value:
|
||||
|
||||
+4
-2
@@ -9,7 +9,6 @@
|
||||
The widget is called from web2py
|
||||
----------------------------------
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import datetime
|
||||
import sys
|
||||
@@ -31,6 +30,9 @@ from gluon.settings import global_settings
|
||||
from gluon.shell import run, test
|
||||
from gluon.utils import is_valid_ip_address, is_loopback_ip_address, getipaddrinfo
|
||||
|
||||
if PY2:
|
||||
input = raw_input
|
||||
|
||||
|
||||
ProgramName = 'web2py Web Framework'
|
||||
ProgramAuthor = 'Created by Massimo Di Pierro, Copyright 2007-' + str(
|
||||
@@ -952,7 +954,7 @@ def console():
|
||||
|
||||
if options.gae:
|
||||
if not os.path.exists('app.yaml'):
|
||||
name = raw_input("Your GAE app name: ")
|
||||
name = input("Your GAE app name: ")
|
||||
content = open(os.path.join('examples', 'app.example.yaml'), 'rb').read()
|
||||
open('app.yaml', 'wb').write(content.replace("yourappname", name))
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user