Merge pull request #2088 from vinyldarkscratch/python-3

Introduce better Python 3 compatibility across all files
This commit is contained in:
mdipierro
2019-02-10 20:09:27 -08:00
committed by GitHub
36 changed files with 141 additions and 182 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
Utility functions for the Admin application
-------------------------------------------
"""
from __future__ import print_function
import os
import sys
import traceback
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+7 -7
View File
@@ -108,8 +108,8 @@ def saml2_handler(session, request, config_filename = None, entityid = None):
config_filename = config_filename or os.path.join(request.folder,'private','sp_conf')
client = Saml2Client(config_file = config_filename)
if not entityid:
idps = client.metadata.with_descriptor("idpsso")
entityid = idps.keys()[0]
idps = client.metadata.with_descriptor("idpsso")
entityid = idps.keys()[0]
bindings = [BINDING_HTTP_REDIRECT, BINDING_HTTP_POST]
binding, destination = client.pick_binding(
"single_sign_on_service", bindings, "idpsso", entity_id=entityid)
@@ -120,7 +120,7 @@ def saml2_handler(session, request, config_filename = None, entityid = None):
if not request.vars.SAMLResponse:
req_id, req = client.create_authn_request(destination, binding=binding)
relay_state = web2py_uuid().replace('-','')
session.saml_outstanding_queries = {req_id: request.url}
session.saml_outstanding_queries = {req_id: request.url}
session.saml_req_id = req_id
http_args = client.apply_binding(binding, str(req), destination,
relay_state=relay_state)
@@ -150,14 +150,14 @@ class Saml2Auth(object):
self.config_file = config_file
self.maps = maps
# URL for redirecting users to when they sign out
# URL for redirecting users to when they sign out
self.saml_logout_url = logout_url
# URL to let users change their password in the IDP system
self.saml_change_password_url = change_password_url
# URL to specify an IDP if using federation metadata or an MDQ
self.entityid = entityid
# URL to specify an IDP if using federation metadata or an MDQ
self.entityid = entityid
def login_url(self, next="/"):
d = saml2_handler(current.session, current.request, entityid=self.entityid)
+2 -1
View File
@@ -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)\
+8 -8
View File
@@ -82,14 +82,14 @@ def test():
def check(data, salt, iterations, keylen, expected):
rv = pbkdf2_hex(data, salt, iterations, keylen)
if rv != expected:
print 'Test failed:'
print ' Expected: %s' % expected
print ' Got: %s' % rv
print ' Parameters:'
print ' data=%s' % data
print ' salt=%s' % salt
print ' iterations=%d' % iterations
print
print('Test failed:')
print(' Expected: %s' % expected)
print(' Got: %s' % rv)
print(' Parameters:')
print(' data=%s' % data)
print(' salt=%s' % salt)
print(' iterations=%d' % iterations)
print()
failed.append(1)
# From RFC 6070
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+11 -7
View File
@@ -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
View File
@@ -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")
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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(',')]
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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 + '.'
+1 -1
View File
@@ -4,7 +4,7 @@
"""
Unit tests for gluon.sqlhtml
"""
from __future__ import print_function
import os
import sys
import unittest
+1 -1
View File
@@ -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:
+2 -2
View File
@@ -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')
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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'
+1 -1
View File
@@ -3,7 +3,7 @@
"""
Unit tests for running web2py
"""
from __future__ import print_function
import sys
import os
import unittest
+27 -27
View File
@@ -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
@@ -3576,7 +3577,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
@@ -4616,7 +4617,6 @@ class Crud(object): # pragma: no cover
results = None
return form, results
urllib2.install_opener(urllib2.build_opener(urllib2.HTTPCookieProcessor()))
@@ -4634,7 +4634,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:
@@ -5002,7 +5002,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()])
@@ -5219,7 +5219,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):
@@ -5574,7 +5574,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__
@@ -5820,7 +5820,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
@@ -5916,7 +5916,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
View File
@@ -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
View File
@@ -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:
+2 -2
View File
@@ -1,6 +1,6 @@
echo "This script will:
1) Install modules needed to run web2py on Fedora and CentOS/RHEL
2) Install Python 2.6 to /opt and recompile wsgi if not provided
2) Install Python 3.7 to /opt and recompile wsgi if not provided
2) Install web2py in /opt/web-apps/
3) Configure SELinux and iptables
5) Create a self signed ssl certificate
@@ -56,7 +56,7 @@ echo
yum update
# Install required packages
yum install httpd mod_ssl mod_wsgi wget python unzip
yum install httpd mod_ssl mod_wsgi wget python3 unzip
###
### Phase 2 - Install web2py
+2 -2
View File
@@ -38,8 +38,8 @@ apt-get -y install libapache2-mod-wsgi
apt-get -y install python-psycopg2
apt-get -y install postfix
apt-get -y install wget
apt-get -y install python-matplotlib
apt-get -y install python-reportlab
apt-get -y install python3-matplotlib
apt-get -y install python3-reportlab
apt-get -y install mercurial
/etc/init.d/postgresql restart
+2 -2
View File
@@ -1,6 +1,6 @@
echo "This script will:
1) Install modules needed to run web2py on Fedora and CentOS/RHEL
2) Install Python 2.6 to /opt and recompile wsgi if not provided
2) Install Python 3.7 to /opt and recompile wsgi if not provided
2) Install web2py in /opt/web-apps/
3) Configure SELinux and iptables
5) Create a self signed ssl certificate
@@ -54,7 +54,7 @@ echo
yum update
# Install required packages
yum install httpd mod_ssl mod_wsgi wget python
yum install httpd mod_ssl mod_wsgi wget python3
# Verify we have at least Python 2.5
typeset -i version_major
+2 -2
View File
@@ -1,7 +1,7 @@
#!/bin/bash
echo "This script will:
1) Install modules needed to run web2py on Fedora and CentOS/RHEL
2) Install Python 2.6 to /opt and recompile wsgi if not provided
2) Install Python 3.7 to /opt and recompile wsgi if not provided
2) Install web2py in /opt/web-apps/
3) Configure SELinux and iptables
5) Create a self signed ssl certificate
@@ -55,7 +55,7 @@ echo
yum update
# Install required packages
yum install httpd mod_ssl mod_wsgi wget python
yum install httpd mod_ssl mod_wsgi wget python3
# Verify we have at least Python 2.5
typeset -i version_major
+6 -7
View File
@@ -31,18 +31,17 @@ apt-get -y install zip unzip
apt-get -y install tar
apt-get -y install openssh-server
apt-get -y install build-essential
apt-get -y install python
#apt-get -y install python2.5
apt-get -y install ipython
apt-get -y install python-dev
apt-get -y install python3
apt-get -y install ipython3
apt-get -y install python3-dev
apt-get -y install postgresql
apt-get -y install apache2
apt-get -y install libapache2-mod-wsgi
apt-get -y install python2.5-psycopg2
apt-get -y install python3-psycopg2
apt-get -y install postfix
apt-get -y install wget
apt-get -y install python-matplotlib
apt-get -y install python-reportlab
apt-get -y install python3-matplotlib
apt-get -y install python3-reportlab
apt-get -y install mercurial
/etc/init.d/postgresql restart
+6 -10
View File
@@ -14,15 +14,14 @@ parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)
from gluon.cfs import getcfs
from gluon.utf8 import Utf8
from gluon._compat import copyreg, PY2, maketrans, iterkeys, unicodeT, to_unicode, to_bytes, iteritems, to_native, pjoin
from gluon.languages import findT
from gluon.languages import findT, sort_function
# This script can be run with no arguments (which sets the application folder to the current working directory, and default language to English), one argument (which sets the default language), or two arguments (application folder path and default language).
# When run, it will update the default language, as well as strip all of the strings found in the non-default languages but not in the default language, and add the strings found in the default language to the non-default languages it is not, making sure translators don't do additional work that will never be used.
def read_dict_aux(filename):
lang_text = open(filename, 'r').read().replace(b'\r\n', b'\n')
lang_text = open(filename, 'r').read().replace('\r\n', '\n')
try:
return safe_eval(to_native(lang_text)) or {}
except Exception:
@@ -41,14 +40,11 @@ def safe_eval(text):
return eval(text, {}, {})
return None
def sort_function(x, y):
return cmp(unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower())
def write_file(file, contents):
file.write('# -*- coding: utf-8 -*-\n{\n')
for key in sorted(contents, sort_function):
file.write('%s: %s,\n' % (repr(Utf8(key)),
repr(Utf8(contents[key]))))
for key in sorted(contents, key = sort_function):
file.write('%s: %s,\n' % (repr(to_unicode(key)),
repr(to_unicode(contents[key]))))
file.write('}\n')
file.close()
@@ -67,7 +63,7 @@ def update_languages(cwd, default_lang):
if phrase in default:
new_dict[phrase] = i18n[phrase]
write_file(open(os.path.join(cwd, "languages", lang), 'w'), new_dict)
print lang
print(lang)
if __name__ == "__main__":
cwd = os.getcwd()