summaryrefslogtreecommitdiff
path: root/databases/py-sqlobject/files/patch-2to3
diff options
context:
space:
mode:
authorPo-Chuan Hsieh <sunpoet@FreeBSD.org>2022-03-25 21:32:07 +0800
committerPo-Chuan Hsieh <sunpoet@FreeBSD.org>2022-03-25 21:38:06 +0800
commitb117f7f8f7723515ea1f847cd66293719ce324bf (patch)
treeb5b1b84c349cbea1443e80ea11f5a2592ff62d30 /databases/py-sqlobject/files/patch-2to3
parentdatabases/py-motor: Fix build with setuptools 58.0.0+ (diff)
databases/py-sqlobject: Fix build with setuptools 58.0.0+
With hat: python
Diffstat (limited to 'databases/py-sqlobject/files/patch-2to3')
-rw-r--r--databases/py-sqlobject/files/patch-2to32505
1 files changed, 2505 insertions, 0 deletions
diff --git a/databases/py-sqlobject/files/patch-2to3 b/databases/py-sqlobject/files/patch-2to3
new file mode 100644
index 000000000000..66193d081e4a
--- /dev/null
+++ b/databases/py-sqlobject/files/patch-2to3
@@ -0,0 +1,2505 @@
+--- sqlobject/col.py.orig 2014-05-04 12:48:24 UTC
++++ sqlobject/col.py
+@@ -22,17 +22,17 @@ from array import array
+ from itertools import count
+ import re, time
+ try:
+- import cPickle as pickle
++ import pickle as pickle
+ except ImportError:
+ import pickle
+ import weakref
+ from formencode import compound, validators
+-from classregistry import findClass
++from .classregistry import findClass
+ # Sadly the name "constraints" conflicts with many of the function
+ # arguments in this module, so we rename it:
+-import constraints as constrs
+-import sqlbuilder
+-from styles import capword
++from . import constraints as constrs
++from . import sqlbuilder
++from .styles import capword
+
+ NoDefault = sqlbuilder.NoDefault
+
+@@ -218,7 +218,7 @@ class SOCol(object):
+ self.dbEncoding = dbEncoding
+
+ if extra_vars:
+- for name, value in extra_vars.items():
++ for name, value in list(extra_vars.items()):
+ setattr(self, name, value)
+
+ def _set_validator(self, value):
+@@ -286,7 +286,7 @@ class SOCol(object):
+
+ def _sqlType(self):
+ if self.customSQLType is None:
+- raise ValueError, ("Col %s (%s) cannot be used for automatic "
++ raise ValueError("Col %s (%s) cannot be used for automatic "
+ "schema creation (too abstract)" %
+ (self.name, self.__class__))
+ else:
+@@ -399,7 +399,7 @@ class Col(object):
+ super(Col, self).__init__()
+ self.__dict__['_name'] = name
+ self.__dict__['_kw'] = kw
+- self.__dict__['creationOrder'] = creationOrder.next()
++ self.__dict__['creationOrder'] = next(creationOrder)
+ self.__dict__['_extra_vars'] = {}
+
+ def _set_name(self, value):
+@@ -473,7 +473,7 @@ class SOStringLikeCol(SOCol):
+
+ def _check_case_sensitive(self, db):
+ if self.char_binary:
+- raise ValueError, "%s does not support binary character columns" % db
++ raise ValueError("%s does not support binary character columns" % db)
+
+ def _mysqlType(self):
+ type = self._sqlType()
+@@ -538,14 +538,14 @@ class StringValidator(SOValidator):
+ except AttributeError:
+ binaryType = type(None) # Just a simple workaround
+ dbEncoding = self.getDbEncoding(state, default='ascii')
+- if isinstance(value, unicode):
++ if isinstance(value, str):
+ return value.encode(dbEncoding)
+ if self.dataType and isinstance(value, self.dataType):
+ return value
+ if isinstance(value, (str, buffer, binaryType, sqlbuilder.SQLExpression)):
+ return value
+ if hasattr(value, '__unicode__'):
+- return unicode(value).encode(dbEncoding)
++ return str(value).encode(dbEncoding)
+ raise validators.Invalid("expected a str in the StringCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
+
+@@ -563,7 +563,7 @@ class StringCol(Col):
+
+ class NQuoted(sqlbuilder.SQLExpression):
+ def __init__(self, value):
+- assert isinstance(value, unicode)
++ assert isinstance(value, str)
+ self.value = value
+ def __hash__(self):
+ return hash(self.value)
+@@ -576,14 +576,14 @@ class UnicodeStringValidator(SOValidator):
+ def to_python(self, value, state):
+ if value is None:
+ return None
+- if isinstance(value, (unicode, sqlbuilder.SQLExpression)):
++ if isinstance(value, (str, sqlbuilder.SQLExpression)):
+ return value
+ if isinstance(value, str):
+- return unicode(value, self.getDbEncoding(state))
++ return str(value, self.getDbEncoding(state))
+ if isinstance(value, array): # MySQL
+- return unicode(value.tostring(), self.getDbEncoding(state))
++ return str(value.tostring(), self.getDbEncoding(state))
+ if hasattr(value, '__unicode__'):
+- return unicode(value)
++ return str(value)
+ raise validators.Invalid("expected a str or a unicode in the UnicodeCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
+
+@@ -592,7 +592,7 @@ class UnicodeStringValidator(SOValidator):
+ return None
+ if isinstance(value, (str, sqlbuilder.SQLExpression)):
+ return value
+- if isinstance(value, unicode):
++ if isinstance(value, str):
+ try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+@@ -602,7 +602,7 @@ class UnicodeStringValidator(SOValidator):
+ return NQuoted(value)
+ return value.encode(self.getDbEncoding(state))
+ if hasattr(value, '__unicode__'):
+- return unicode(value).encode(self.getDbEncoding(state))
++ return str(value).encode(self.getDbEncoding(state))
+ raise validators.Invalid("expected a str or a unicode in the UnicodeCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
+
+@@ -625,9 +625,9 @@ class IntValidator(SOValidator):
+ def to_python(self, value, state):
+ if value is None:
+ return None
+- if isinstance(value, (int, long, sqlbuilder.SQLExpression)):
++ if isinstance(value, (int, sqlbuilder.SQLExpression)):
+ return value
+- for converter, attr_name in (int, '__int__'), (long, '__long__'):
++ for converter, attr_name in (int, '__int__'), (int, '__long__'):
+ if hasattr(value, attr_name):
+ try:
+ return converter(value)
+@@ -708,7 +708,7 @@ class BoolValidator(SOValidator):
+ return None
+ if isinstance(value, (bool, sqlbuilder.SQLExpression)):
+ return value
+- if isinstance(value, (int, long)) or hasattr(value, '__nonzero__'):
++ if isinstance(value, int) or hasattr(value, '__nonzero__'):
+ return bool(value)
+ raise validators.Invalid("expected a bool or an int in the BoolCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
+@@ -753,9 +753,9 @@ class FloatValidator(SOValidator):
+ def to_python(self, value, state):
+ if value is None:
+ return None
+- if isinstance(value, (float, int, long, sqlbuilder.SQLExpression)):
++ if isinstance(value, (float, int, sqlbuilder.SQLExpression)):
+ return value
+- for converter, attr_name in (float, '__float__'), (int, '__int__'), (long, '__long__'):
++ for converter, attr_name in (float, '__float__'), (int, '__int__'), (int, '__long__'):
+ if hasattr(value, attr_name):
+ try:
+ return converter(value)
+@@ -964,7 +964,7 @@ class EnumValidator(SOValidator):
+
+ def to_python(self, value, state):
+ if value in self.enumValues:
+- if isinstance(value, unicode):
++ if isinstance(value, str):
+ dbEncoding = self.getDbEncoding(state)
+ value = value.encode(dbEncoding)
+ return value
+@@ -1000,7 +1000,7 @@ class SOEnumCol(SOCol):
+ return "ENUM(%s) NOT NULL" % ', '.join([sqlbuilder.sqlrepr(v, 'mysql') for v in self.enumValues])
+
+ def _postgresType(self):
+- length = max(map(self._getlength, self.enumValues))
++ length = max(list(map(self._getlength, self.enumValues)))
+ enumValues = ', '.join([sqlbuilder.sqlrepr(v, 'postgres') for v in self.enumValues])
+ checkConstraint = "CHECK (%s in (%s))" % (self.dbName, enumValues)
+ return "VARCHAR(%i) %s" % (length, checkConstraint)
+@@ -1014,7 +1014,7 @@ class SOEnumCol(SOCol):
+ return self._postgresType()
+
+ def _firebirdType(self):
+- length = max(map(self._getlength, self.enumValues))
++ length = max(list(map(self._getlength, self.enumValues)))
+ enumValues = ', '.join([sqlbuilder.sqlrepr(v, 'firebird') for v in self.enumValues])
+ checkConstraint = "CHECK (%s in (%s))" % (self.dbName, enumValues)
+ #NB. Return a tuple, not a string here
+@@ -1048,7 +1048,7 @@ class SetValidator(SOValidator):
+ (self.name, type(value), value), value, state)
+
+ def from_python(self, value, state):
+- if isinstance(value, basestring):
++ if isinstance(value, str):
+ value = (value,)
+ try:
+ return ",".join(value)
+@@ -1358,7 +1358,7 @@ class DecimalValidator(SOValidator):
+ def to_python(self, value, state):
+ if value is None:
+ return None
+- if isinstance(value, (int, long, Decimal, sqlbuilder.SQLExpression)):
++ if isinstance(value, (int, Decimal, sqlbuilder.SQLExpression)):
+ return value
+ if isinstance(value, float):
+ value = str(value)
+@@ -1380,7 +1380,7 @@ class DecimalValidator(SOValidator):
+ return None
+ if isinstance(value, float):
+ value = str(value)
+- if isinstance(value, basestring):
++ if isinstance(value, str):
+ try:
+ connection = state.connection or state.soObject._connection
+ except AttributeError:
+@@ -1393,7 +1393,7 @@ class DecimalValidator(SOValidator):
+ except:
+ raise validators.Invalid("can not parse Decimal value '%s' in the DecimalCol from '%s'" %
+ (value, getattr(state, 'soObject', '(unknown)')), value, state)
+- if isinstance(value, (int, long, Decimal, sqlbuilder.SQLExpression)):
++ if isinstance(value, (int, Decimal, sqlbuilder.SQLExpression)):
+ return value
+ raise validators.Invalid("expected a Decimal in the DecimalCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
+@@ -1447,7 +1447,7 @@ class DecimalStringValidator(DecimalValidator):
+ "Value must be less than %s" % int(self.max)
+ value = value.quantize(self.precision)
+ value = value.to_eng_string()
+- elif isinstance(value, (int, long)):
++ elif isinstance(value, int):
+ value = str(value)
+ return value
+
+@@ -1569,7 +1569,7 @@ class PickleValidator(BinaryValidator):
+ def to_python(self, value, state):
+ if value is None:
+ return None
+- if isinstance(value, unicode):
++ if isinstance(value, str):
+ dbEncoding = self.getDbEncoding(state, default='ascii')
+ value = value.encode(dbEncoding)
+ if isinstance(value, str):
+@@ -1610,7 +1610,7 @@ def pushKey(kw, name, value):
+ kw[name] = value
+
+ all = []
+-for key, value in globals().items():
++for key, value in list(globals().items()):
+ if isinstance(value, type) and (issubclass(value, (Col, SOCol))):
+ all.append(key)
+ __all__.extend(all)
+--- sqlobject/converters.py.orig 2014-05-04 12:48:24 UTC
++++ sqlobject/converters.py
+@@ -95,7 +95,7 @@ def StringLikeConverter(value, db):
+ return "'%s'" % value
+
+ registerConverter(str, StringLikeConverter)
+-registerConverter(unicode, StringLikeConverter)
++registerConverter(str, StringLikeConverter)
+ registerConverter(array, StringLikeConverter)
+ registerConverter(buffer, StringLikeConverter)
+
+@@ -107,7 +107,7 @@ registerConverter(int, IntConverter)
+ def LongConverter(value, db):
+ return str(value)
+
+-registerConverter(long, LongConverter)
++registerConverter(int, LongConverter)
+
+ if NumericType:
+ registerConverter(NumericType, IntConverter)
+@@ -203,8 +203,8 @@ def sqlrepr(obj, db=None):
+ except AttributeError:
+ converter = lookupConverter(obj)
+ if converter is None:
+- raise ValueError, "Unknown SQL builtin type: %s for %s" % \
+- (type(obj), repr(obj))
++ raise ValueError("Unknown SQL builtin type: %s for %s" % \
++ (type(obj), repr(obj)))
+ return converter(obj, db)
+ else:
+ return reprFunc(db)
+--- sqlobject/dbconnection.py.orig 2013-07-07 18:43:26 UTC
++++ sqlobject/dbconnection.py
+@@ -6,17 +6,17 @@ import os
+ import sys
+ import threading
+ import types
+-import urllib
++import urllib.request, urllib.parse, urllib.error
+ import warnings
+ import weakref
+
+-from cache import CacheSet
+-import classregistry
+-import col
+-from converters import sqlrepr
+-import main
+-import sqlbuilder
+-from util.threadinglocal import local as threading_local
++from .cache import CacheSet
++from . import classregistry
++from . import col
++from .converters import sqlrepr
++from . import main
++from . import sqlbuilder
++from .util.threadinglocal import local as threading_local
+
+ warnings.filterwarnings("ignore", "DB-API extension cursor.lastrowid used")
+
+@@ -34,7 +34,7 @@ class ConsoleWriter:
+ self.dbEncoding = getattr(connection, "dbEncoding", None) or "ascii"
+ def write(self, text):
+ logfile = getattr(sys, self.loglevel)
+- if isinstance(text, unicode):
++ if isinstance(text, str):
+ try:
+ text = text.encode(self.dbEncoding)
+ except UnicodeEncodeError:
+@@ -111,9 +111,9 @@ class DBConnection:
+ def uri(self):
+ auth = getattr(self, 'user', '') or ''
+ if auth:
+- auth = urllib.quote(auth)
++ auth = urllib.parse.quote(auth)
+ if self.password:
+- auth = auth + ':' + urllib.quote(self.password)
++ auth = auth + ':' + urllib.parse.quote(self.password)
+ auth = auth + '@'
+ else:
+ assert not getattr(self, 'password', None), (
+@@ -127,7 +127,7 @@ class DBConnection:
+ db = self.db
+ if db.startswith('/'):
+ db = db[1:]
+- return uri + urllib.quote(db)
++ return uri + urllib.parse.quote(db)
+
+ @classmethod
+ def connectionFromOldURI(cls, uri):
+@@ -167,9 +167,9 @@ class DBConnection:
+ try:
+ port = int(port)
+ except ValueError:
+- raise ValueError, "port must be integer, got '%s' instead" % port
++ raise ValueError("port must be integer, got '%s' instead" % port)
+ if not (1 <= port <= 65535):
+- raise ValueError, "port must be integer in the range 1-65535, got '%d' instead" % port
++ raise ValueError("port must be integer in the range 1-65535, got '%d' instead" % port)
+ host = _host
+ else:
+ port = None
+@@ -183,15 +183,15 @@ class DBConnection:
+ arglist = arglist.split('&')
+ for single in arglist:
+ argname, argvalue = single.split('=', 1)
+- argvalue = urllib.unquote(argvalue)
++ argvalue = urllib.parse.unquote(argvalue)
+ args[argname] = argvalue
+ return user, password, host, port, path, args
+
+ @staticmethod
+ def _parseURI(uri):
+- protocol, request = urllib.splittype(uri)
++ protocol, request = urllib.parse.splittype(uri)
+ user, password, port = None, None, None
+- host, path = urllib.splithost(request)
++ host, path = urllib.parse.splithost(request)
+
+ if host:
+ # Python < 2.7 have a problem - splituser() calls unquote() too early
+@@ -199,17 +199,17 @@ class DBConnection:
+ if '@' in host:
+ user, host = host.split('@', 1)
+ if user:
+- user, password = [x and urllib.unquote(x) or None for x in urllib.splitpasswd(user)]
+- host, port = urllib.splitport(host)
++ user, password = [x and urllib.parse.unquote(x) or None for x in urllib.parse.splitpasswd(user)]
++ host, port = urllib.parse.splitport(host)
+ if port: port = int(port)
+ elif host == '':
+ host = None
+
+ # hash-tag is splitted but ignored
+- path, tag = urllib.splittag(path)
+- path, query = urllib.splitquery(path)
++ path, tag = urllib.parse.splittag(path)
++ path, query = urllib.parse.splitquery(path)
+
+- path = urllib.unquote(path)
++ path = urllib.parse.unquote(path)
+ if (os.name == 'nt') and (len(path) > 2):
+ # Preserve backward compatibility with URIs like /C|/path;
+ # replace '|' by ':'
+@@ -282,7 +282,7 @@ class ConnWrapper(object):
+ "because it takes **kw: %r"
+ % meth)
+ takes_conn = 'connection' in args
+- meth.im_func.takes_connection = takes_conn
++ meth.__func__.takes_connection = takes_conn
+ if not takes_conn:
+ return meth
+ return ConnMethodWrapper(meth, self._connection)
+@@ -363,7 +363,7 @@ class DBAPI(DBConnection):
+ if self.debug:
+ self.printDebug(conn, 'auto/exception', 'ROLLBACK')
+ conn.rollback()
+- raise Exception, 'Object used outside of a transaction; implicit COMMIT or ROLLBACK not allowed'
++ raise Exception('Object used outside of a transaction; implicit COMMIT or ROLLBACK not allowed')
+ elif self.autoCommit:
+ if self.debug:
+ self.printDebug(conn, 'auto', 'COMMIT')
+@@ -593,7 +593,7 @@ class DBAPI(DBConnection):
+
+ def _SO_selectOneAlt(self, so, columnNames, condition):
+ if columnNames:
+- columns = [isinstance(x, basestring) and sqlbuilder.SQLConstant(x) or x for x in columnNames]
++ columns = [isinstance(x, str) and sqlbuilder.SQLConstant(x) or x for x in columnNames]
+ else:
+ columns = None
+ return self.queryOne(self.sqlrepr(sqlbuilder.Select(columns,
+@@ -643,7 +643,7 @@ class DBAPI(DBConnection):
+ data = {}
+ if 'id' in kw:
+ data[soClass.sqlmeta.idName] = kw.pop('id')
+- for key, col in soClass.sqlmeta.columns.items():
++ for key, col in list(soClass.sqlmeta.columns.items()):
+ if key in kw:
+ value = kw.pop(key)
+ if col.from_python:
+@@ -657,7 +657,7 @@ class DBAPI(DBConnection):
+ data[col.dbName] = obj
+ if kw:
+ # pick the first key from kw to use to raise the error,
+- raise TypeError, "got an unexpected keyword argument(s): %r" % kw.keys()
++ raise TypeError("got an unexpected keyword argument(s): %r" % list(kw.keys()))
+
+ if not data:
+ return None
+@@ -665,7 +665,7 @@ class DBAPI(DBConnection):
+ ['%s %s %s' %
+ (dbName, ops.get(value, "="), self.sqlrepr(value))
+ for dbName, value
+- in data.items()])
++ in list(data.items())])
+
+ def sqlrepr(self, v):
+ return sqlrepr(v, self.dbName)
+@@ -718,7 +718,7 @@ class Iteration(object):
+ def __iter__(self):
+ return self
+
+- def next(self):
++ def __next__(self):
+ result = self.cursor.fetchone()
+ if result is None:
+ self._cleanup()
+@@ -791,7 +791,7 @@ class Transaction(object):
+ if not cls in self._deletedCache:
+ self._deletedCache[cls] = []
+ self._deletedCache[cls].append(inst.id)
+- meth = new.instancemethod(self._dbConnection._SO_delete.im_func, self, self.__class__)
++ meth = new.instancemethod(self._dbConnection._SO_delete.__func__, self, self.__class__)
+ return meth(inst)
+
+ def commit(self, close=False):
+@@ -801,8 +801,8 @@ class Transaction(object):
+ if self._dbConnection.debug:
+ self._dbConnection.printDebug(self._connection, '', 'COMMIT')
+ self._connection.commit()
+- subCaches = [(sub[0], sub[1].allIDs()) for sub in self.cache.allSubCachesByClassNames().items()]
+- subCaches.extend([(x[0], x[1]) for x in self._deletedCache.items()])
++ subCaches = [(sub[0], sub[1].allIDs()) for sub in list(self.cache.allSubCachesByClassNames().items())]
++ subCaches.extend([(x[0], x[1]) for x in list(self._deletedCache.items())])
+ for cls, ids in subCaches:
+ for id in ids:
+ inst = self._dbConnection.cache.tryGetByName(id, cls)
+@@ -836,7 +836,7 @@ class Transaction(object):
+ self.assertActive()
+ attr = getattr(self._dbConnection, attr)
+ try:
+- func = attr.im_func
++ func = attr.__func__
+ except AttributeError:
+ if isinstance(attr, ConnWrapper):
+ return ConnWrapper(attr._soClass, self)
+@@ -996,9 +996,9 @@ class ConnectionURIOpener(object):
+ def connectionForURI(self, uri, oldUri=False, **args):
+ if args:
+ if '?' not in uri:
+- uri += '?' + urllib.urlencode(args)
++ uri += '?' + urllib.parse.urlencode(args)
+ else:
+- uri += '&' + urllib.urlencode(args)
++ uri += '&' + urllib.parse.urlencode(args)
+ if uri in self.cachedURIs:
+ return self.cachedURIs[uri]
+ if uri.find(':') != -1:
+@@ -1020,7 +1020,7 @@ class ConnectionURIOpener(object):
+ def dbConnectionForScheme(self, scheme):
+ assert scheme in self.schemeBuilders, (
+ "No SQLObject driver exists for %s (only %s)"
+- % (scheme, ', '.join(self.schemeBuilders.keys())))
++ % (scheme, ', '.join(list(self.schemeBuilders.keys()))))
+ return self.schemeBuilders[scheme]()
+
+ TheURIOpener = ConnectionURIOpener()
+@@ -1031,11 +1031,11 @@ connectionForURI = TheURIOpener.connectionForURI
+ dbConnectionForScheme = TheURIOpener.dbConnectionForScheme
+
+ # Register DB URI schemas
+-import firebird
+-import maxdb
+-import mssql
+-import mysql
+-import postgres
+-import rdbhost
+-import sqlite
+-import sybase
++from . import firebird
++from . import maxdb
++from . import mssql
++from . import mysql
++from . import postgres
++from . import rdbhost
++from . import sqlite
++from . import sybase
+--- sqlobject/events.py.orig 2010-11-13 17:42:40 UTC
++++ sqlobject/events.py
+@@ -206,25 +206,25 @@ def summarize_events_by_sender(sender=None, output=Non
+ if sender is None:
+ send_list = [
+ (deref(dispatcher.senders.get(sid)), listeners)
+- for sid, listeners in dispatcher.connections.items()
++ for sid, listeners in list(dispatcher.connections.items())
+ if deref(dispatcher.senders.get(sid))]
+ for sender, listeners in sorted_items(send_list):
+ real_sender = deref(sender)
+ if not real_sender:
+ continue
+ header = 'Sender: %r' % real_sender
+- print >> output, (' '*indent) + header
+- print >> output, (' '*indent) + '='*len(header)
++ print((' '*indent) + header, file=output)
++ print((' '*indent) + '='*len(header), file=output)
+ summarize_events_by_sender(real_sender, output=output, indent=indent+2)
+ else:
+ for signal, receivers in sorted_items(dispatcher.connections.get(id(sender), [])):
+ receivers = [deref(r) for r in receivers if deref(r)]
+ header = 'Signal: %s (%i receivers)' % (sort_name(signal),
+ len(receivers))
+- print >> output, (' '*indent) + header
+- print >> output, (' '*indent) + '-'*len(header)
++ print((' '*indent) + header, file=output)
++ print((' '*indent) + '-'*len(header), file=output)
+ for receiver in sorted(receivers, key=sort_name):
+- print >> output, (' '*indent) + ' ' + nice_repr(receiver)
++ print((' '*indent) + ' ' + nice_repr(receiver), file=output)
+
+ def deref(value):
+ if isinstance(value, dispatcher.WEAKREF_TYPES):
+@@ -234,14 +234,14 @@ def deref(value):
+
+ def sorted_items(a_dict):
+ if isinstance(a_dict, dict):
+- a_dict = a_dict.items()
++ a_dict = list(a_dict.items())
+ return sorted(a_dict, key=lambda t: sort_name(t[0]))
+
+ def sort_name(value):
+ if isinstance(value, type):
+ return value.__name__
+ elif isinstance(value, types.FunctionType):
+- return value.func_name
++ return value.__name__
+ else:
+ return str(value)
+
+@@ -262,26 +262,26 @@ def debug_events():
+
+ def _debug_send(signal=dispatcher.Any, sender=dispatcher.Anonymous,
+ *arguments, **named):
+- print "send %s from %s: %s" % (
+- nice_repr(signal), nice_repr(sender), fmt_args(*arguments, **named))
++ print("send %s from %s: %s" % (
++ nice_repr(signal), nice_repr(sender), fmt_args(*arguments, **named)))
+ return _real_dispatcher_send(signal, sender, *arguments, **named)
+
+ def _debug_sendExact(signal=dispatcher.Any, sender=dispatcher.Anonymous,
+ *arguments, **named):
+- print "sendExact %s from %s: %s" % (
+- nice_repr(signal), nice_repr(sender), fmt_args(*arguments, **name))
++ print("sendExact %s from %s: %s" % (
++ nice_repr(signal), nice_repr(sender), fmt_args(*arguments, **name)))
+ return _real_dispatcher_sendExact(signal, sender, *arguments, **named)
+
+ def _debug_connect(receiver, signal=dispatcher.Any, sender=dispatcher.Any,
+ weak=True):
+- print "connect %s to %s signal %s" % (
+- nice_repr(receiver), nice_repr(signal), nice_repr(sender))
++ print("connect %s to %s signal %s" % (
++ nice_repr(receiver), nice_repr(signal), nice_repr(sender)))
+ return _real_dispatcher_connect(receiver, signal, sender, weak)
+
+ def _debug_disconnect(receiver, signal=dispatcher.Any, sender=dispatcher.Any,
+ weak=True):
+- print "disconnecting %s from %s signal %s" % (
+- nice_repr(receiver), nice_repr(signal), nice_repr(sender))
++ print("disconnecting %s from %s signal %s" % (
++ nice_repr(receiver), nice_repr(signal), nice_repr(sender)))
+ return disconnect(receiver, signal, sender, weak)
+
+ def fmt_args(*arguments, **name):
+@@ -294,23 +294,23 @@ def nice_repr(v):
+ """
+ Like repr(), but nicer for debugging here.
+ """
+- if isinstance(v, (types.ClassType, type)):
++ if isinstance(v, type):
+ return v.__module__ + '.' + v.__name__
+ elif isinstance(v, types.FunctionType):
+- if '__name__' in v.func_globals:
+- if getattr(sys.modules[v.func_globals['__name__']],
+- v.func_name, None) is v:
+- return '%s.%s' % (v.func_globals['__name__'], v.func_name)
++ if '__name__' in v.__globals__:
++ if getattr(sys.modules[v.__globals__['__name__']],
++ v.__name__, None) is v:
++ return '%s.%s' % (v.__globals__['__name__'], v.__name__)
+ return repr(v)
+ elif isinstance(v, types.MethodType):
+ return '%s.%s of %s' % (
+- nice_repr(v.im_class), v.im_func.func_name,
+- nice_repr(v.im_self))
++ nice_repr(v.__self__.__class__), v.__func__.__name__,
++ nice_repr(v.__self__))
+ else:
+ return repr(v)
+
+
+ __all__ = ['listen', 'send']
+-for name, value in globals().items():
++for name, value in list(globals().items()):
+ if isinstance(value, type) and issubclass(value, Signal):
+ __all__.append(name)
+--- sqlobject/include/pydispatch/dispatcher.py.orig 2011-05-15 15:48:27 UTC
++++ sqlobject/include/pydispatch/dispatcher.py
+@@ -25,20 +25,14 @@ Internal attributes:
+ deletion, (considerably speeds up the cleanup process
+ vs. the original code.)
+ """
+-from __future__ import generators
++
+ import types, weakref
+-import saferef, robustapply, errors
++from . import saferef, robustapply, errors
+
+ __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
+ __cvsid__ = "$Id: dispatcher.py,v 1.9 2005/09/17 04:55:57 mcfletch Exp $"
+ __version__ = "$Revision: 1.9 $"[11:-2]
+
+-try:
+- True
+-except NameError:
+- True = 1==1
+- False = 1==0
+-
+ class _Parameter:
+ """Used to represent default parameter values."""
+ def __repr__(self):
+@@ -379,8 +373,8 @@ def _removeReceiver(receiver):
+ backKey = id(receiver)
+ for senderkey in sendersBack.get(backKey,()):
+ try:
+- signals = connections[senderkey].keys()
+- except KeyError,err:
++ signals = list(connections[senderkey].keys())
++ except KeyError as err:
+ pass
+ else:
+ for signal in signals:
+@@ -391,7 +385,7 @@ def _removeReceiver(receiver):
+ else:
+ try:
+ receivers.remove( receiver )
+- except Exception, err:
++ except Exception as err:
+ pass
+ _cleanupConnections(senderkey, signal)
+ try:
+@@ -440,7 +434,7 @@ def _removeBackrefs( senderkey):
+ except KeyError:
+ signals = None
+ else:
+- items = signals.items()
++ items = list(signals.items())
+ def allReceivers( ):
+ for signal,set in items:
+ for item in set:
+@@ -468,7 +462,7 @@ def _removeOldBackRefs(senderkey, signal, receiver, re
+ found = 0
+ signals = connections.get(signal)
+ if signals is not None:
+- for sig,recs in connections.get(signal,{}).iteritems():
++ for sig,recs in connections.get(signal,{}).items():
+ if sig != signal:
+ for rec in recs:
+ if rec is oldReceiver:
+--- sqlobject/include/pydispatch/robust.py.orig 2006-02-09 16:14:04 UTC
++++ sqlobject/include/pydispatch/robust.py
+@@ -1,6 +1,6 @@
+ """Module implementing error-catching version of send (sendRobust)"""
+-from dispatcher import Any, Anonymous, liveReceivers, getAllReceivers
+-from robustapply import robustApply
++from .dispatcher import Any, Anonymous, liveReceivers, getAllReceivers
++from .robustapply import robustApply
+
+ def sendRobust(
+ signal=Any,
+@@ -50,7 +50,7 @@ def sendRobust(
+ *arguments,
+ **named
+ )
+- except Exception, err:
++ except Exception as err:
+ responses.append((receiver, err))
+ else:
+ responses.append((receiver, response))
+--- sqlobject/include/pydispatch/saferef.py.orig 2006-02-09 16:14:04 UTC
++++ sqlobject/include/pydispatch/saferef.py
+@@ -13,7 +13,7 @@ def safeRef(target, onDelete = None):
+ weakref or a BoundMethodWeakref) as argument.
+ """
+ if hasattr(target, 'im_self'):
+- if target.im_self is not None:
++ if target.__self__ is not None:
+ # Turn a bound method into a BoundMethodWeakref instance.
+ # Keep track of these instances for lookup by disconnect().
+ assert hasattr(target, 'im_func'), """safeRef target %r has im_self, but no im_func, don't know how to create reference"""%( target,)
+@@ -109,26 +109,26 @@ class BoundMethodWeakref(object):
+ try:
+ if callable( function ):
+ function( self )
+- except Exception, e:
++ except Exception as e:
+ try:
+ traceback.print_exc()
+- except AttributeError, err:
+- print '''Exception during saferef %s cleanup function %s: %s'''%(
++ except AttributeError as err:
++ print('''Exception during saferef %s cleanup function %s: %s'''%(
+ self, function, e
+- )
++ ))
+ self.deletionMethods = [onDelete]
+ self.key = self.calculateKey( target )
+- self.weakSelf = weakref.ref(target.im_self, remove)
+- self.weakFunc = weakref.ref(target.im_func, remove)
+- self.selfName = str(target.im_self)
+- self.funcName = str(target.im_func.__name__)
++ self.weakSelf = weakref.ref(target.__self__, remove)
++ self.weakFunc = weakref.ref(target.__func__, remove)
++ self.selfName = str(target.__self__)
++ self.funcName = str(target.__func__.__name__)
+ def calculateKey( cls, target ):
+ """Calculate the reference key for this reference
+
+ Currently this is a two-tuple of the id()'s of the
+ target object and the target function respectively.
+ """
+- return (id(target.im_self),id(target.im_func))
++ return (id(target.__self__),id(target.__func__))
+ calculateKey = classmethod( calculateKey )
+ def __str__(self):
+ """Give a friendly representation of the object"""
+@@ -138,7 +138,7 @@ class BoundMethodWeakref(object):
+ self.funcName,
+ )
+ __repr__ = __str__
+- def __nonzero__( self ):
++ def __bool__( self ):
+ """Whether we are still a valid reference"""
+ return self() is not None
+ def __cmp__( self, other ):
+--- sqlobject/index.py.orig 2011-05-15 15:48:27 UTC
++++ sqlobject/index.py
+@@ -1,6 +1,6 @@
+ from itertools import count
+ from types import *
+-from converters import sqlrepr
++from .converters import sqlrepr
+
+ creationOrder = count()
+
+@@ -20,15 +20,15 @@ class SODatabaseIndex(object):
+
+ def get(self, *args, **kw):
+ if not self.unique:
+- raise AttributeError, (
++ raise AttributeError(
+ "'%s' object has no attribute 'get' (index is not unique)" % self.name)
+ connection = kw.pop('connection', None)
+ if args and kw:
+- raise TypeError, "You cannot mix named and unnamed arguments"
++ raise TypeError("You cannot mix named and unnamed arguments")
+ columns = [d['column'] for d in self.descriptions
+ if 'column' in d]
+ if kw and len(kw) != len(columns) or args and len(args) != len(columns):
+- raise TypeError, ("get() takes exactly %d argument and an optional "
++ raise TypeError("get() takes exactly %d argument and an optional "
+ "named argument 'connection' (%d given)" % (
+ len(columns), len(args)+len(kw)))
+ if args:
+@@ -65,13 +65,13 @@ class SODatabaseIndex(object):
+ columnName = columnName.name
+ colDict = self.soClass.sqlmeta.columns
+ if columnName not in colDict:
+- for possible in colDict.values():
++ for possible in list(colDict.values()):
+ if possible.origName == columnName:
+ column = possible
+ break
+ else:
+ # None found
+- raise ValueError, "The column by the name %r was not found in the class %r" % (columnName, self.soClass)
++ raise ValueError("The column by the name %r was not found in the class %r" % (columnName, self.soClass))
+ else:
+ column = colDict[columnName]
+ desc['column'] = column
+@@ -153,7 +153,7 @@ class DatabaseIndex(object):
+ def __init__(self, *columns, **kw):
+ kw['columns'] = columns
+ self.kw = kw
+- self.creationOrder = creationOrder.next()
++ self.creationOrder = next(creationOrder)
+
+ def setName(self, value):
+ assert self.kw.get('name') is None, "You cannot change a name after it has already been set (from %s to %s)" % (self.kw['name'], value)
+--- sqlobject/inheritance/__init__.py.orig 2011-05-15 15:48:27 UTC
++++ sqlobject/inheritance/__init__.py
+@@ -5,7 +5,8 @@ from sqlobject import sqlbuilder
+ from sqlobject.col import StringCol, ForeignKey
+ from sqlobject.main import sqlmeta, SQLObject, SelectResults, \
+ makeProperties, unmakeProperties, getterName, setterName
+-import iteration
++from . import iteration
++from functools import reduce
+
+ def tablesUsedSet(obj, db):
+ if hasattr(obj, "tablesUsedSet"):
+@@ -35,7 +36,7 @@ class InheritableSelectResults(SelectResults):
+ if inheritedTables:
+ for tableName in inheritedTables:
+ tablesSet.add(str(tableName))
+- if orderBy and not isinstance(orderBy, basestring):
++ if orderBy and not isinstance(orderBy, str):
+ tablesSet.update(tablesUsedSet(orderBy, dbName))
+ #DSM: if this class has a parent, we need to link it
+ #DSM: and be sure the parent is in the table list.
+@@ -69,7 +70,7 @@ class InheritableSelectResults(SelectResults):
+ #DSM: Table registry contains only the last children
+ #DSM: or standalone classes
+ parentClause = []
+- for (currentClass, minParentClass) in tableRegistry.items():
++ for (currentClass, minParentClass) in list(tableRegistry.items()):
+ while (currentClass != minParentClass) \
+ and currentClass.sqlmeta.parentClass:
+ parentClass = currentClass.sqlmeta.parentClass
+@@ -86,7 +87,7 @@ class InheritableSelectResults(SelectResults):
+ return super(InheritableSelectResults, self).accumulateMany(*attributes)
+ tables = []
+ for func_name, attribute in attributes:
+- if not isinstance(attribute, basestring):
++ if not isinstance(attribute, str):
+ tables.append(attribute.tableName)
+ clone = self.__class__(self.sourceClass, self.clause,
+ self.clauseTables, inheritedTables=tables, **self.ops)
+@@ -130,7 +131,7 @@ class InheritableSQLMeta(sqlmeta):
+ q = getattr(soClass.q, columnDef.name, None)
+ else:
+ q = None
+- for c in sqlmeta.childClasses.values():
++ for c in list(sqlmeta.childClasses.values()):
+ c.sqlmeta.addColumn(columnDef, connection=connection, childUpdate=True)
+ if q: setattr(c.q, columnDef.name, q)
+
+@@ -153,7 +154,7 @@ class InheritableSQLMeta(sqlmeta):
+
+ #DSM: Update each child class if needed
+ #DSM: and delete properties for this column
+- for c in sqlmeta.childClasses.values():
++ for c in list(sqlmeta.childClasses.values()):
+ c.sqlmeta.delColumn(column, changeSchema=changeSchema,
+ connection=connection, childUpdate=True)
+
+@@ -184,7 +185,7 @@ class InheritableSQLMeta(sqlmeta):
+
+ #DSM: Update each child class if needed and existing (only for new
+ #DSM: dynamic join as no child classes exists at object creation)
+- for c in sqlmeta.childClasses.values():
++ for c in list(sqlmeta.childClasses.values()):
+ c.sqlmeta.addJoin(joinDef, childUpdate=True)
+
+ @classmethod
+@@ -199,7 +200,7 @@ class InheritableSQLMeta(sqlmeta):
+
+ #DSM: Update each child class if needed
+ #DSM: and delete properties for this join
+- for c in sqlmeta.childClasses.values():
++ for c in list(sqlmeta.childClasses.values()):
+ c.sqlmeta.delJoin(joinDef, childUpdate=True)
+
+ @classmethod
+@@ -236,7 +237,7 @@ class InheritableSQLObject(SQLObject):
+ # if we are a child class, add sqlbuilder fields from parents
+ currentClass = cls.sqlmeta.parentClass
+ while currentClass:
+- for column in currentClass.sqlmeta.columnDefinitions.values():
++ for column in list(currentClass.sqlmeta.columnDefinitions.values()):
+ if column.name == 'childName':
+ continue
+ if isinstance(column, ForeignKey):
+@@ -319,7 +320,7 @@ class InheritableSQLObject(SQLObject):
+ # verify names of added columns
+ if sqlmeta.parentClass:
+ # FIXME: this does not check for grandparent column overrides
+- parentCols = sqlmeta.parentClass.sqlmeta.columns.keys()
++ parentCols = list(sqlmeta.parentClass.sqlmeta.columns.keys())
+ for column in sqlmeta.columnList:
+ if column.name == 'childName':
+ raise AttributeError(
+@@ -357,7 +358,7 @@ class InheritableSQLObject(SQLObject):
+ parentClass = self.sqlmeta.parentClass
+ new_kw = {}
+ parent_kw = {}
+- for (name, value) in kw.items():
++ for (name, value) in list(kw.items()):
+ if (name != 'childName') and hasattr(parentClass, name):
+ parent_kw[name] = value
+ else:
+@@ -370,7 +371,7 @@ class InheritableSQLObject(SQLObject):
+ for col in self.sqlmeta.columnList:
+ if (col._default == sqlbuilder.NoDefault) and \
+ (col.name not in kw) and (col.foreignName not in kw):
+- raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, col.name)
++ raise TypeError("%s() did not get expected keyword argument %s" % (self.__class__.__name__, col.name))
+
+ parent_kw['childName'] = self.sqlmeta.childName
+ self._parent = parentClass(kw=parent_kw,
+@@ -426,7 +427,7 @@ class InheritableSQLObject(SQLObject):
+ addClause = parentClass.q.childName == cls.sqlmeta.childName
+ # if the clause was one of TRUE varians, replace it
+ if (clause is None) or (clause is sqlbuilder.SQLTrueClause) \
+- or (isinstance(clause, basestring) and (clause == 'all')):
++ or (isinstance(clause, str) and (clause == 'all')):
+ clause = addClause
+ else:
+ # patch WHERE condition:
+@@ -471,11 +472,11 @@ class InheritableSQLObject(SQLObject):
+ currentClass = cls
+ while currentClass:
+ foreignColumns.update(dict([(column.foreignName, name)
+- for (name, column) in currentClass.sqlmeta.columns.items()
++ for (name, column) in list(currentClass.sqlmeta.columns.items())
+ if column.foreignKey
+ ]))
+ currentClass = currentClass.sqlmeta.parentClass
+- for name, value in kw.items():
++ for name, value in list(kw.items()):
+ if name in foreignColumns:
+ name = foreignColumns[name] # translate "key" to "keyID"
+ if isinstance(value, SQLObject):
+@@ -485,7 +486,7 @@ class InheritableSQLObject(SQLObject):
+ try:
+ clause.append(getattr(currentClass.q, name) == value)
+ break
+- except AttributeError, err:
++ except AttributeError as err:
+ pass
+ currentClass = currentClass.sqlmeta.parentClass
+ else:
+--- sqlobject/main.py.orig 2013-10-14 16:07:00 UTC
++++ sqlobject/main.py
+@@ -28,23 +28,23 @@ USA.
+
+ import threading
+ import weakref
+-import sqlbuilder
+-import dbconnection
+-import col
+-import styles
++from . import sqlbuilder
++from . import dbconnection
++from . import col
++from . import styles
+ import types
+ import warnings
+-import joins
+-import index
+-import classregistry
+-import declarative
+-import events
+-from sresults import SelectResults
+-from util.threadinglocal import local
++from . import joins
++from . import index
++from . import classregistry
++from . import declarative
++from . import events
++from .sresults import SelectResults
++from .util.threadinglocal import local
+
+ import sys
+ if sys.version_info[:3] < (2, 5, 0):
+- raise ImportError, "SQLObject requires Python 2.5.0 or later"
++ raise ImportError("SQLObject requires Python 2.5.0 or later")
+
+ """
+ This thread-local storage is needed for RowCreatedSignals. It gathers
+@@ -81,7 +81,7 @@ def makeProperties(obj):
+ d = obj.__dict__
+
+ props = {}
+- for var, value in d.items():
++ for var, value in list(d.items()):
+ if var.startswith('_set_'):
+ props.setdefault(var[5:], {})['set'] = value
+ elif var.startswith('_get_'):
+@@ -90,7 +90,7 @@ def makeProperties(obj):
+ props.setdefault(var[5:], {})['del'] = value
+ elif var.startswith('_doc_'):
+ props.setdefault(var[5:], {})['doc'] = value
+- for var, setters in props.items():
++ for var, setters in list(props.items()):
+ if len(setters) == 1 and 'doc' in setters:
+ continue
+ if var in d:
+@@ -115,7 +115,7 @@ def unmakeProperties(obj):
+ delFunc = delattr
+ d = obj.__dict__
+
+- for var, value in d.items():
++ for var, value in list(d.items()):
+ if isinstance(value, property):
+ for prop in [value.fget, value.fset, value.fdel]:
+ if prop and not prop.__name__ in d:
+@@ -148,7 +148,7 @@ def _collectAttributes(cls, new_attrs, look_for_class)
+
+ """
+ result = []
+- for attr, value in new_attrs.items():
++ for attr, value in list(new_attrs.items()):
+ if isinstance(value, look_for_class):
+ value.name = attr
+ delattr(cls, attr)
+@@ -162,7 +162,7 @@ class CreateNewSQLObject:
+ """
+ pass
+
+-class sqlmeta(object):
++class sqlmeta(object, metaclass=declarative.DeclarativeMeta):
+
+ """
+ This object is the object we use to keep track of all sorts of
+@@ -236,8 +236,6 @@ class sqlmeta(object):
+ # Default encoding for UnicodeCol's
+ dbEncoding = None
+
+- __metaclass__ = declarative.DeclarativeMeta
+-
+ def __classinit__(cls, new_attrs):
+ for attr in cls._unshared_attributes:
+ if attr not in new_attrs:
+@@ -321,7 +319,7 @@ class sqlmeta(object):
+ parent_columns = []
+ for base in soClass.__bases__:
+ if hasattr(base, "sqlmeta"):
+- parent_columns.extend(base.sqlmeta.columns.keys())
++ parent_columns.extend(list(base.sqlmeta.columns.keys()))
+ if hasattr(soClass, name):
+ assert (name in parent_columns) or (name == "childName"), (
+ "The class %s.%s already has a variable or method %r, you cannot "
+@@ -440,7 +438,7 @@ class sqlmeta(object):
+ conn = connection or soClass._connection
+ for columnDef in conn.columnsFromSchema(sqlmeta.table, soClass):
+ if columnDef.name not in sqlmeta.columnDefinitions:
+- if isinstance(columnDef.name, unicode):
++ if isinstance(columnDef.name, str):
+ columnDef.name = columnDef.name.encode('ascii')
+ sqlmeta.addColumn(columnDef)
+
+@@ -456,7 +454,7 @@ class sqlmeta(object):
+ else:
+ raise ValueError('Unknown column ' + column)
+ if isinstance(column, col.Col):
+- for c in sqlmeta.columns.values():
++ for c in list(sqlmeta.columns.values()):
+ if column is c.columnDef:
+ column = c
+ break
+@@ -704,10 +702,8 @@ _postponed_local = local()
+ # here, though -- just automatic method generation (like
+ # methods and properties for each column) is done in
+ # MetaSQLObject.
+-class SQLObject(object):
++class SQLObject(object, metaclass=declarative.DeclarativeMeta):
+
+- __metaclass__ = declarative.DeclarativeMeta
+-
+ _connection = sqlhub
+
+ sqlmeta = sqlmeta
+@@ -770,12 +766,12 @@ class SQLObject(object):
+ # _columns where the attribute has been set to None in this
+ # class. If so, then we need to remove that column from
+ # _columns.
+- for key in sqlmeta.columnDefinitions.keys():
++ for key in list(sqlmeta.columnDefinitions.keys()):
+ if (key in new_attrs
+ and new_attrs[key] is None):
+ del sqlmeta.columnDefinitions[key]
+
+- for column in sqlmeta.columnDefinitions.values():
++ for column in list(sqlmeta.columnDefinitions.values()):
+ sqlmeta.addColumn(column)
+
+ for column in implicitColumns:
+@@ -850,7 +846,7 @@ class SQLObject(object):
+ "(while fixing up sqlmeta %r inheritance)"
+ % cls.sqlmeta)
+ values = dict(cls.sqlmeta.__dict__)
+- for key in values.keys():
++ for key in list(values.keys()):
+ if key.startswith('__') and key.endswith('__'):
+ # Magic values shouldn't be passed through:
+ del values[key]
+@@ -931,7 +927,7 @@ class SQLObject(object):
+ dbNames = [col.dbName for col in self.sqlmeta.columnList]
+ selectResults = self._connection._SO_selectOne(self, dbNames)
+ if not selectResults:
+- raise SQLObjectNotFound, "The object %s by the ID %s does not exist" % (self.__class__.__name__, self.id)
++ raise SQLObjectNotFound("The object %s by the ID %s does not exist" % (self.__class__.__name__, self.id))
+ self._SO_selectInit(selectResults)
+ self._SO_createValues = {}
+ self.sqlmeta.dirty = False
+@@ -958,7 +954,7 @@ class SQLObject(object):
+ dbNames = [col.dbName for col in self.sqlmeta.columnList]
+ selectResults = self._connection._SO_selectOne(self, dbNames)
+ if not selectResults:
+- raise SQLObjectNotFound, "The object %s by the ID %s has been deleted" % (self.__class__.__name__, self.id)
++ raise SQLObjectNotFound("The object %s by the ID %s has been deleted" % (self.__class__.__name__, self.id))
+ self._SO_selectInit(selectResults)
+ result = getattr(self, attrName)
+ return result
+@@ -973,7 +969,7 @@ class SQLObject(object):
+ dbNames = [col.dbName for col in self.sqlmeta.columnList]
+ selectResults = self._connection._SO_selectOne(self, dbNames)
+ if not selectResults:
+- raise SQLObjectNotFound, "The object %s by the ID %s has been deleted" % (self.__class__.__name__, self.id)
++ raise SQLObjectNotFound("The object %s by the ID %s has been deleted" % (self.__class__.__name__, self.id))
+ self._SO_selectInit(selectResults)
+ self.sqlmeta.expired = False
+ finally:
+@@ -986,7 +982,7 @@ class SQLObject(object):
+ try:
+ if self.sqlmeta.columns:
+ values = [(self.sqlmeta.columns[v[0]].dbName, v[1])
+- for v in self._SO_createValues.items()]
++ for v in list(self._SO_createValues.items())]
+ self._connection._SO_update(self, values)
+ self.sqlmeta.dirty = False
+ self._SO_createValues = {}
+@@ -1067,13 +1063,13 @@ class SQLObject(object):
+ is_column = lambda _c: _c in self.sqlmeta._plainSetters
+ f_is_column = lambda item: is_column(item[0])
+ f_not_column = lambda item: not is_column(item[0])
+- items = kw.items()
+- extra = dict(filter(f_not_column, items))
+- kw = dict(filter(f_is_column, items))
++ items = list(kw.items())
++ extra = dict(list(filter(f_not_column, items)))
++ kw = dict(list(filter(f_is_column, items)))
+
+ # _creating is special, see _SO_setValue
+ if self.sqlmeta._creating or self.sqlmeta.lazyUpdate:
+- for name, value in kw.items():
++ for name, value in list(kw.items()):
+ from_python = getattr(self, '_SO_from_python_%s' % name, None)
+ if from_python:
+ kw[name] = dbValue = from_python(value, self._SO_validatorState)
+@@ -1086,16 +1082,16 @@ class SQLObject(object):
+
+ self._SO_createValues.update(kw)
+
+- for name, value in extra.items():
++ for name, value in list(extra.items()):
+ try:
+ getattr(self.__class__, name)
+ except AttributeError:
+ if name not in self.sqlmeta.columns:
+- raise TypeError, "%s.set() got an unexpected keyword argument %s" % (self.__class__.__name__, name)
++ raise TypeError("%s.set() got an unexpected keyword argument %s" % (self.__class__.__name__, name))
+ try:
+ setattr(self, name, value)
+- except AttributeError, e:
+- raise AttributeError, '%s (with attribute %r)' % (e, name)
++ except AttributeError as e:
++ raise AttributeError('%s (with attribute %r)' % (e, name))
+
+ self.sqlmeta.dirty = True
+ return
+@@ -1112,7 +1108,7 @@ class SQLObject(object):
+ # read the user's mind. We'll combine everything
+ # else into a single UPDATE, if necessary.
+ toUpdate = {}
+- for name, value in kw.items():
++ for name, value in list(kw.items()):
+ from_python = getattr(self, '_SO_from_python_%s' % name, None)
+ if from_python:
+ dbValue = from_python(value, self._SO_validatorState)
+@@ -1124,20 +1120,20 @@ class SQLObject(object):
+ if self.sqlmeta.cacheValues:
+ setattr(self, instanceName(name), value)
+ toUpdate[name] = dbValue
+- for name, value in extra.items():
++ for name, value in list(extra.items()):
+ try:
+ getattr(self.__class__, name)
+ except AttributeError:
+ if name not in self.sqlmeta.columns:
+- raise TypeError, "%s.set() got an unexpected keyword argument %s" % (self.__class__.__name__, name)
++ raise TypeError("%s.set() got an unexpected keyword argument %s" % (self.__class__.__name__, name))
+ try:
+ setattr(self, name, value)
+- except AttributeError, e:
+- raise AttributeError, '%s (with attribute %r)' % (e, name)
++ except AttributeError as e:
++ raise AttributeError('%s (with attribute %r)' % (e, name))
+
+ if toUpdate:
+ args = [(self.sqlmeta.columns[name].dbName, value)
+- for name, value in toUpdate.items()]
++ for name, value in list(toUpdate.items())]
+ self._connection._SO_update(self, args)
+ finally:
+ self._SO_writeLock.release()
+@@ -1257,7 +1253,7 @@ class SQLObject(object):
+ # If we specified an SQL DEFAULT, then we should use that
+ if default is NoDefault:
+ if column.defaultSQL is None:
+- raise TypeError, "%s() did not get expected keyword argument '%s'" % (self.__class__.__name__, column.name)
++ raise TypeError("%s() did not get expected keyword argument '%s'" % (self.__class__.__name__, column.name))
+ else:
+ # There is defaultSQL for the column - do not put
+ # the column to kw so that the backend creates the value
+@@ -1277,7 +1273,7 @@ class SQLObject(object):
+ # Here's where an INSERT is finalized.
+ # These are all the column values that were supposed
+ # to be set, but were delayed until now:
+- setters = self._SO_createValues.items()
++ setters = list(self._SO_createValues.items())
+ # Here's their database names:
+ names = [self.sqlmeta.columns[v[0]].dbName for v in setters]
+ values = [v[1] for v in setters]
+@@ -1316,7 +1312,7 @@ class SQLObject(object):
+ name = (name,)
+ value = (value,)
+ if len(name) != len(value):
+- raise ValueError, "'column' and 'value' tuples must be of the same size"
++ raise ValueError("'column' and 'value' tuples must be of the same size")
+ new_value = []
+ for n, v in zip(name, value):
+ from_python = getattr(cls, '_SO_from_python_' + n)
+@@ -1335,13 +1331,13 @@ class SQLObject(object):
+ result, obj = cls._findAlternateID(name, dbName, value, connection)
+ if not result:
+ if idxName is None:
+- raise SQLObjectNotFound, "The %s by alternateID %s = %s does not exist" % (cls.__name__, name, repr(value))
++ raise SQLObjectNotFound("The %s by alternateID %s = %s does not exist" % (cls.__name__, name, repr(value)))
+ else:
+ names = []
+- for i in xrange(len(name)):
++ for i in range(len(name)):
+ names.append("%s = %s" % (name[i], repr(value[i])))
+ names = ', '.join(names)
+- raise SQLObjectNotFound, "The %s by unique index %s(%s) does not exist" % (cls.__name__, idxName, names)
++ raise SQLObjectNotFound("The %s by unique index %s(%s) does not exist" % (cls.__name__, idxName, names))
+ if obj:
+ return obj
+ if connection:
+@@ -1564,7 +1560,7 @@ class SQLObject(object):
+ if results.count():
+ # Restrictions only apply if there are
+ # matching records on the related table
+- raise SQLObjectIntegrityError, (
++ raise SQLObjectIntegrityError(
+ "Tried to delete %s::%s but "
+ "table %s has a restriction against it" %
+ (klass.__name__, self.id, k.__name__))
+@@ -1638,7 +1634,7 @@ class SQLObject(object):
+
+ @classmethod
+ def setConnection(cls, value):
+- if isinstance(value, basestring):
++ if isinstance(value, str):
+ value = dbconnection.connectionForURI(value)
+ cls._connection = value
+
+@@ -1720,7 +1716,7 @@ def getID(obj, refColumn=None):
+ return getattr(obj, refColumn or 'id')
+ elif isinstance(obj, int):
+ return obj
+- elif isinstance(obj, long):
++ elif isinstance(obj, int):
+ return int(obj)
+ elif isinstance(obj, str):
+ try:
+@@ -1733,7 +1729,7 @@ def getID(obj, refColumn=None):
+ def getObject(obj, klass):
+ if isinstance(obj, int):
+ return klass(obj)
+- elif isinstance(obj, long):
++ elif isinstance(obj, int):
+ return klass(int(obj))
+ elif isinstance(obj, str):
+ return klass(int(obj))
+--- sqlobject/manager/command.py.orig 2011-05-15 15:48:27 UTC
++++ sqlobject/manager/command.py
+@@ -69,10 +69,10 @@ def db_differences(soClass, conn):
+ del existing[col.dbName]
+ else:
+ missing[col.dbName] = col
+- for col in existing.values():
++ for col in list(existing.values()):
+ diffs.append('Database has extra column: %s'
+ % col.dbName)
+- for col in missing.values():
++ for col in list(missing.values()):
+ diffs.append('Database missing column: %s' % col.dbName)
+ return diffs
+
+@@ -96,7 +96,7 @@ class CommandRunner(object):
+ self.invalid('No COMMAND given (try "%s help")'
+ % os.path.basename(invoked_as))
+ real_command = self.command_aliases.get(command, command)
+- if real_command not in self.commands.keys():
++ if real_command not in list(self.commands.keys()):
+ self.invalid('COMMAND %s unknown' % command)
+ runner = self.commands[real_command](
+ invoked_as, command, args, self)
+@@ -109,7 +109,7 @@ class CommandRunner(object):
+ self.command_aliases[alias] = name
+
+ def invalid(self, msg, code=2):
+- print msg
++ print(msg)
+ sys.exit(code)
+
+ the_runner = CommandRunner()
+@@ -170,10 +170,8 @@ def standard_parser(connection=True, simulate=True,
+ default=[])
+ return parser
+
+-class Command(object):
++class Command(object, metaclass=DeclarativeMeta):
+
+- __metaclass__ = DeclarativeMeta
+-
+ min_args = 0
+ min_args_error = 'You must provide at least %(min_args)s arguments'
+ max_args = 0
+@@ -225,7 +223,7 @@ class Command(object):
+ # Check for circular references
+ if cls in dependency_stack:
+ dependency_stack.append(cls)
+- raise SQLObjectCircularReferenceError, (
++ raise SQLObjectCircularReferenceError(
+ "Found a circular reference: %s " %
+ (' --> '.join([x.__name__
+ for x in dependency_stack])))
+@@ -248,14 +246,14 @@ class Command(object):
+ sorter.append((level, cls))
+ sorter.sort()
+ ordered_classes = [cls for level, cls in sorter]
+- except SQLObjectCircularReferenceError, msg:
++ except SQLObjectCircularReferenceError as msg:
+ # Failsafe: return the classes as-is if a circular reference
+ # prevented the dependency levels to be calculated.
+- print ("Warning: a circular reference was detected in the "
++ print(("Warning: a circular reference was detected in the "
+ "model. Unable to sort the classes by dependency: they "
+ "will be treated in alphabetic order. This may or may "
+ "not work depending on your database backend. "
+- "The error was:\n%s" % msg)
++ "The error was:\n%s" % msg))
+ return classes
+ return ordered_classes
+
+@@ -347,21 +345,21 @@ class Command(object):
+ % '\n * '.join([soClass.__name__
+ for soClass in missing]))
+ if require_some and not all:
+- print 'No classes found!'
++ print('No classes found!')
+ if self.options.modules:
+- print 'Looked in modules: %s' % ', '.join(self.options.modules)
++ print('Looked in modules: %s' % ', '.join(self.options.modules))
+ else:
+- print 'No modules specified'
++ print('No modules specified')
+ if self.options.packages:
+- print 'Looked in packages: %s' % ', '.join(self.options.packages)
++ print('Looked in packages: %s' % ', '.join(self.options.packages))
+ else:
+- print 'No packages specified'
++ print('No packages specified')
+ if self.options.class_matchers:
+- print 'Matching class pattern: %s' % self.options.class_matches
++ print('Matching class pattern: %s' % self.options.class_matches)
+ if self.options.eggs:
+- print 'Looked in eggs: %s' % ', '.join(self.options.eggs)
++ print('Looked in eggs: %s' % ', '.join(self.options.eggs))
+ else:
+- print 'No eggs specified'
++ print('No eggs specified')
+ sys.exit(1)
+ return self.orderClassesByDependencyLevel(all)
+
+@@ -411,7 +409,7 @@ class Command(object):
+ if '#' in conf_fn:
+ conf_fn, conf_section = conf_fn.split('#', 1)
+
+- from ConfigParser import ConfigParser
++ from configparser import ConfigParser
+ p = ConfigParser()
+ # Case-sensitive:
+ p.optionxform = str
+@@ -454,21 +452,20 @@ class Command(object):
+ def find_classes_in_file(arg, dir_name, filenames):
+ if dir_name.startswith('.svn'):
+ return
+- filenames = filter(lambda fname: fname.endswith('.py') and fname != '__init__.py',
+- filenames)
++ filenames = [fname for fname in filenames if fname.endswith('.py') and fname != '__init__.py']
+ for fname in filenames:
+ module_name = os.path.join(dir_name, fname)
+ module_name = module_name[module_name.find(package_name):]
+ module_name = module_name.replace(os.path.sep,'.')[:-3]
+ try:
+ module = moduleloader.load_module(module_name)
+- except ImportError, err:
++ except ImportError as err:
+ if self.options.verbose:
+- print 'Could not import module "%s". Error was : "%s"' % (module_name, err)
++ print('Could not import module "%s". Error was : "%s"' % (module_name, err))
+ continue
+- except Exception, exc:
++ except Exception as exc:
+ if self.options.verbose:
+- print 'Unknown exception while processing module "%s" : "%s"' % (module_name, exc)
++ print('Unknown exception while processing module "%s" : "%s"' % (module_name, exc))
+ continue
+ classes = self.classes_from_module(module)
+ all.extend(classes)
+@@ -484,7 +481,7 @@ class Command(object):
+ if not mod:
+ continue
+ if self.options.verbose:
+- print 'Looking in module %s' % mod
++ print('Looking in module %s' % mod)
+ modules.extend(self.classes_from_module(
+ moduleloader.load_module(mod)))
+ return modules
+@@ -503,7 +500,7 @@ class Command(object):
+ dist = pkg_resources.get_distribution(egg_spec)
+ if not dist.has_metadata('sqlobject.txt'):
+ if warn_no_sqlobject:
+- print 'No sqlobject.txt in %s egg info' % egg_spec
++ print('No sqlobject.txt in %s egg info' % egg_spec)
+ return None, {}
+ result = {}
+ for line in dist.get_metadata_lines('sqlobject.txt'):
+@@ -513,7 +510,7 @@ class Command(object):
+ name, value = line.split('=', 1)
+ name = name.strip().lower()
+ if name in result:
+- print 'Warning: %s appears more than once in sqlobject.txt' % name
++ print('Warning: %s appears more than once in sqlobject.txt' % name)
+ result[name.strip().lower()] = value.strip()
+ return dist, result
+
+@@ -532,12 +529,12 @@ class Command(object):
+ else:
+ prompt += ' [y/N]? '
+ while 1:
+- response = raw_input(prompt).strip()
++ response = input(prompt).strip()
+ if not response.strip():
+ return default
+ if response and response[0].lower() in ('y', 'n'):
+ return response[0].lower() == 'y'
+- print 'Y or N please'
++ print('Y or N please')
+
+ def shorten_filename(self, fn):
+ """
+@@ -558,7 +555,7 @@ class Command(object):
+ f = open(fn, 'w')
+ f.write(pretext)
+ f.close()
+- print '$EDITOR %s' % fn
++ print('$EDITOR %s' % fn)
+ os.system('$EDITOR %s' % fn)
+ f = open(fn, 'r')
+ content = f.read()
+@@ -582,16 +579,16 @@ class CommandSQL(Command):
+ allConstraints = []
+ for cls in classes:
+ if self.options.verbose >= 1:
+- print '-- %s from %s' % (
+- cls.__name__, cls.__module__)
++ print('-- %s from %s' % (
++ cls.__name__, cls.__module__))
+ createSql, constraints = cls.createTableSQL()
+- print createSql.strip() + ';\n'
++ print(createSql.strip() + ';\n')
+ allConstraints.append(constraints)
+ for constraints in allConstraints:
+ if constraints:
+ for constraint in constraints:
+ if constraint:
+- print constraint.strip() + ';\n'
++ print(constraint.strip() + ';\n')
+
+
+ class CommandList(Command):
+@@ -603,12 +600,12 @@ class CommandList(Command):
+
+ def command(self):
+ if self.options.verbose >= 1:
+- print 'Classes found:'
++ print('Classes found:')
+ classes = self.classes(require_connection=False)
+ for soClass in classes:
+- print '%s.%s' % (soClass.__module__, soClass.__name__)
++ print('%s.%s' % (soClass.__module__, soClass.__name__))
+ if self.options.verbose >= 1:
+- print ' Table: %s' % soClass.sqlmeta.table
++ print(' Table: %s' % soClass.sqlmeta.table)
+
+ class CommandCreate(Command):
+
+@@ -633,26 +630,26 @@ class CommandCreate(Command):
+ if not self.options.simulate:
+ try:
+ soClass._connection.createEmptyDatabase()
+- except soClass._connection.module.ProgrammingError, e:
++ except soClass._connection.module.ProgrammingError as e:
+ if str(e).find('already exists') != -1:
+- print 'Database already exists'
++ print('Database already exists')
+ else:
+ raise
+ else:
+- print '(simulating; cannot create database)'
++ print('(simulating; cannot create database)')
+ dbs_created.append(soClass._connection)
+- if soClass._connection not in constraints.keys():
++ if soClass._connection not in list(constraints.keys()):
+ constraints[soClass._connection] = []
+ exists = soClass._connection.tableExists(soClass.sqlmeta.table)
+ if v >= 1:
+ if exists:
+ existing += 1
+- print '%s already exists.' % soClass.__name__
++ print('%s already exists.' % soClass.__name__)
+ else:
+- print 'Creating %s' % soClass.__name__
++ print('Creating %s' % soClass.__name__)
+ if v >= 2:
+ sql, extra = soClass.createTableSQL()
+- print sql
++ print(sql)
+ if (not self.options.simulate
+ and not exists):
+ if self.options.interactive:
+@@ -662,22 +659,22 @@ class CommandCreate(Command):
+ if tableConstraints:
+ constraints[soClass._connection].append(tableConstraints)
+ else:
+- print 'Cancelled'
++ print('Cancelled')
+ else:
+ created += 1
+ tableConstraints = soClass.createTable(applyConstraints=False)
+ if tableConstraints:
+ constraints[soClass._connection].append(tableConstraints)
+- for connection in constraints.keys():
++ for connection in list(constraints.keys()):
+ if v >= 2:
+- print 'Creating constraints'
++ print('Creating constraints')
+ for constraintList in constraints[connection]:
+ for constraint in constraintList:
+ if constraint:
+ connection.query(constraint)
+ if v >= 1:
+- print '%i tables created (%i already exist)' % (
+- created, existing)
++ print('%i tables created (%i already exist)' % (
++ created, existing))
+
+
+ class CommandDrop(Command):
+@@ -695,10 +692,10 @@ class CommandDrop(Command):
+ exists = soClass._connection.tableExists(soClass.sqlmeta.table)
+ if v >= 1:
+ if exists:
+- print 'Dropping %s' % soClass.__name__
++ print('Dropping %s' % soClass.__name__)
+ else:
+ not_existing += 1
+- print '%s does not exist.' % soClass.__name__
++ print('%s does not exist.' % soClass.__name__)
+ if (not self.options.simulate
+ and exists):
+ if self.options.interactive:
+@@ -706,13 +703,13 @@ class CommandDrop(Command):
+ dropped += 1
+ soClass.dropTable()
+ else:
+- print 'Cancelled'
++ print('Cancelled')
+ else:
+ dropped += 1
+ soClass.dropTable()
+ if v >= 1:
+- print '%i tables dropped (%i didn\'t exist)' % (
+- dropped, not_existing)
++ print('%i tables dropped (%i didn\'t exist)' % (
++ dropped, not_existing))
+
+ class CommandStatus(Command):
+
+@@ -730,7 +727,7 @@ class CommandStatus(Command):
+ if self.printed:
+ return
+ self.printed = True
+- print 'Checking %s...' % soClass.__name__
++ print('Checking %s...' % soClass.__name__)
+
+ def command(self):
+ good = 0
+@@ -744,7 +741,7 @@ class CommandStatus(Command):
+ self.print_class(soClass)
+ if not conn.tableExists(soClass.sqlmeta.table):
+ self.print_class(soClass)
+- print ' Does not exist in database'
++ print(' Does not exist in database')
+ missing_tables += 1
+ continue
+ try:
+@@ -752,13 +749,13 @@ class CommandStatus(Command):
+ soClass)
+ except AttributeError:
+ if not columnsFromSchema_warning:
+- print 'Database does not support reading columns'
++ print('Database does not support reading columns')
+ columnsFromSchema_warning = True
+ good += 1
+ continue
+- except AssertionError, e:
+- print 'Cannot read db table %s: %s' % (
+- soClass.sqlmeta.table, e)
++ except AssertionError as e:
++ print('Cannot read db table %s: %s' % (
++ soClass.sqlmeta.table, e))
+ continue
+ existing = {}
+ for col in columns:
+@@ -772,19 +769,19 @@ class CommandStatus(Command):
+ missing[col.dbName] = col
+ if existing:
+ self.print_class(soClass)
+- for col in existing.values():
+- print ' Database has extra column: %s' % col.dbName
++ for col in list(existing.values()):
++ print(' Database has extra column: %s' % col.dbName)
+ if missing:
+ self.print_class(soClass)
+- for col in missing.values():
+- print ' Database missing column: %s' % col.dbName
++ for col in list(missing.values()):
++ print(' Database missing column: %s' % col.dbName)
+ if existing or missing:
+ bad += 1
+ else:
+ good += 1
+ if self.options.verbose:
+- print '%i in sync; %i out of sync; %i not in database' % (
+- good, bad, missing_tables)
++ print('%i in sync; %i out of sync; %i not in database' % (
++ good, bad, missing_tables))
+
+ class CommandHelp(Command):
+
+@@ -799,20 +796,20 @@ class CommandHelp(Command):
+ if self.args:
+ the_runner.run([self.invoked_as, self.args[0], '-h'])
+ else:
+- print 'Available commands:'
+- print ' (use "%s help COMMAND" or "%s COMMAND -h" ' % (
+- self.prog_name, self.prog_name)
+- print ' for more information)'
+- items = the_runner.commands.items()
++ print('Available commands:')
++ print(' (use "%s help COMMAND" or "%s COMMAND -h" ' % (
++ self.prog_name, self.prog_name))
++ print(' for more information)')
++ items = list(the_runner.commands.items())
+ items.sort()
+ max_len = max([len(cn) for cn, c in items])
+ for command_name, command in items:
+- print '%s:%s %s' % (command_name,
++ print('%s:%s %s' % (command_name,
+ ' '*(max_len-len(command_name)),
+- command.summary)
++ command.summary))
+ if command.aliases:
+- print '%s (Aliases: %s)' % (
+- ' '*max_len, ', '.join(command.aliases))
++ print('%s (Aliases: %s)' % (
++ ' '*max_len, ', '.join(command.aliases)))
+
+ class CommandExecute(Command):
+
+@@ -834,7 +831,7 @@ class CommandExecute(Command):
+ args = self.args
+ if self.options.use_stdin:
+ if self.options.verbose:
+- print "Reading additional SQL from stdin (Ctrl-D or Ctrl-Z to finish)..."
++ print("Reading additional SQL from stdin (Ctrl-D or Ctrl-Z to finish)...")
+ args.append(sys.stdin.read())
+ self.conn = self.connection().getConnection()
+ self.cursor = self.conn.cursor()
+@@ -843,22 +840,22 @@ class CommandExecute(Command):
+
+ def execute_sql(self, sql):
+ if self.options.verbose:
+- print sql
++ print(sql)
+ try:
+ self.cursor.execute(sql)
+- except Exception, e:
++ except Exception as e:
+ if not self.options.verbose:
+- print sql
+- print "****Error:"
+- print ' ', e
++ print(sql)
++ print("****Error:")
++ print(' ', e)
+ return
+ desc = self.cursor.description
+ rows = self.cursor.fetchall()
+ if self.options.verbose:
+ if not self.cursor.rowcount:
+- print "No rows accessed"
++ print("No rows accessed")
+ else:
+- print "%i rows accessed" % self.cursor.rowcount
++ print("%i rows accessed" % self.cursor.rowcount)
+ if desc:
+ for name, type_code, display_size, internal_size, precision, scale, null_ok in desc:
+ sys.stdout.write("%s\t" % name)
+@@ -867,7 +864,7 @@ class CommandExecute(Command):
+ for col in row:
+ sys.stdout.write("%r\t" % col)
+ sys.stdout.write("\n")
+- print
++ print()
+
+ class CommandRecord(Command):
+
+@@ -928,12 +925,12 @@ class CommandRecord(Command):
+ sim = self.options.simulate
+ classes = self.classes()
+ if not classes:
+- print "No classes found!"
++ print("No classes found!")
+ return
+
+ output_dir = self.find_output_dir()
+ version = os.path.basename(output_dir)
+- print "Creating version %s" % version
++ print("Creating version %s" % version)
+ conns = []
+ files = {}
+ for cls in self.classes():
+@@ -963,14 +960,14 @@ class CommandRecord(Command):
+ last_version_dir = self.find_last_version()
+ if last_version_dir and not self.options.force_create:
+ if v > 1:
+- print "Checking %s to see if it is current" % last_version_dir
++ print("Checking %s to see if it is current" % last_version_dir)
+ files_copy = files.copy()
+ for fn in os.listdir(last_version_dir):
+ if not fn.endswith('.sql'):
+ continue
+ if not fn in files_copy:
+ if v > 1:
+- print "Missing file %s" % fn
++ print("Missing file %s" % fn)
+ break
+ f = open(os.path.join(last_version_dir, fn), 'r')
+ content = f.read()
+@@ -978,32 +975,32 @@ class CommandRecord(Command):
+ if (self.strip_comments(files_copy[fn])
+ != self.strip_comments(content)):
+ if v > 1:
+- print "Content does not match: %s" % fn
++ print("Content does not match: %s" % fn)
+ break
+ del files_copy[fn]
+ else:
+ # No differences so far
+ if not files_copy:
+ # Used up all files
+- print ("Current status matches version %s"
+- % os.path.basename(last_version_dir))
++ print(("Current status matches version %s"
++ % os.path.basename(last_version_dir)))
+ return
+ if v > 1:
+- print "Extra files: %s" % ', '.join(files_copy.keys())
++ print("Extra files: %s" % ', '.join(list(files_copy.keys())))
+ if v:
+- print ("Current state does not match %s"
+- % os.path.basename(last_version_dir))
++ print(("Current state does not match %s"
++ % os.path.basename(last_version_dir)))
+ if v > 1 and not last_version_dir:
+- print "No last version to check"
++ print("No last version to check")
+ if not sim:
+ os.mkdir(output_dir)
+ if v:
+- print 'Making directory %s' % self.shorten_filename(output_dir)
+- files = files.items()
++ print('Making directory %s' % self.shorten_filename(output_dir))
++ files = list(files.items())
+ files.sort()
+ for fn, content in files:
+ if v:
+- print ' Writing %s' % self.shorten_filename(fn)
++ print(' Writing %s' % self.shorten_filename(fn))
+ if not sim:
+ f = open(os.path.join(output_dir, fn), 'w')
+ f.write(content)
+@@ -1021,8 +1018,8 @@ class CommandRecord(Command):
+ diff = ' %s: %s' % (cls.sqlmeta.table, diff)
+ all_diffs.append(diff)
+ if all_diffs:
+- print 'Database does not match schema:'
+- print '\n'.join(all_diffs)
++ print('Database does not match schema:')
++ print('\n'.join(all_diffs))
+ for conn in conns:
+ self.update_db(version, conn)
+ else:
+@@ -1044,17 +1041,17 @@ class CommandRecord(Command):
+ f = open(fn, 'w')
+ f.write(text)
+ f.close()
+- print 'Wrote to %s' % fn
++ print('Wrote to %s' % fn)
+
+ def update_db(self, version, conn):
+ v = self.options.verbose
+ if not conn.tableExists(SQLObjectVersionTable.sqlmeta.table):
+ if v:
+- print ('Creating table %s'
+- % SQLObjectVersionTable.sqlmeta.table)
++ print(('Creating table %s'
++ % SQLObjectVersionTable.sqlmeta.table))
+ sql = SQLObjectVersionTable.createTableSQL(connection=conn)
+ if v > 1:
+- print sql
++ print(sql)
+ if not self.options.simulate:
+ SQLObjectVersionTable.createTable(connection=conn)
+ if not self.options.simulate:
+@@ -1073,7 +1070,7 @@ class CommandRecord(Command):
+ if base is None:
+ base = CONFIG.get('sqlobject_history_dir', '.')
+ if not os.path.exists(base):
+- print 'Creating history directory %s' % self.shorten_filename(base)
++ print('Creating history directory %s' % self.shorten_filename(base))
+ if not self.options.simulate:
+ os.makedirs(base)
+ return base
+@@ -1084,8 +1081,8 @@ class CommandRecord(Command):
+ dir = os.path.join(self.base_dir(), today + '-' +
+ self.options.version_name)
+ if os.path.exists(dir):
+- print ("Error, directory already exists: %s"
+- % dir)
++ print(("Error, directory already exists: %s"
++ % dir))
+ sys.exit(1)
+ return dir
+ extra = ''
+@@ -1114,18 +1111,18 @@ class CommandRecord(Command):
+ sim = self.options.simulate
+ version = self.options.force_db_version
+ if not self.version_regex.search(version):
+- print "Versions must be in the format YYYY-MM-DD..."
+- print "You version %s does not fit this" % version
++ print("Versions must be in the format YYYY-MM-DD...")
++ print("You version %s does not fit this" % version)
+ return
+ version_dir = os.path.join(self.base_dir(), version)
+ if not os.path.exists(version_dir):
+ if v:
+- print 'Creating %s' % self.shorten_filename(version_dir)
++ print('Creating %s' % self.shorten_filename(version_dir))
+ if not sim:
+ os.mkdir(version_dir)
+ elif v:
+- print ('Directory %s exists'
+- % self.shorten_filename(version_dir))
++ print(('Directory %s exists'
++ % self.shorten_filename(version_dir)))
+ if self.options.db_record:
+ self.update_db(version, self.connection())
+
+@@ -1162,51 +1159,51 @@ class CommandUpgrade(CommandRecord):
+ else:
+ fname = self.find_last_version()
+ if fname is None:
+- print "No version exists, use 'record' command to create one"
++ print("No version exists, use 'record' command to create one")
+ return
+ version_to = os.path.basename(fname)
+ current = self.current_version()
+ if v:
+- print 'Current version: %s' % current
++ print('Current version: %s' % current)
+ version_list = self.make_plan(current, version_to)
+ if not version_list:
+- print 'Database up to date'
++ print('Database up to date')
+ return
+ if v:
+- print 'Plan:'
++ print('Plan:')
+ for next_version, upgrader in version_list:
+- print ' Use %s to upgrade to %s' % (
+- self.shorten_filename(upgrader), next_version)
++ print(' Use %s to upgrade to %s' % (
++ self.shorten_filename(upgrader), next_version))
+ conn = self.connection()
+ for next_version, upgrader in version_list:
+ f = open(upgrader)
+ sql = f.read()
+ f.close()
+ if v:
+- print "Running:"
+- print sql
+- print '-'*60
++ print("Running:")
++ print(sql)
++ print('-'*60)
+ if not sim:
+ try:
+ conn.query(sql)
+ except:
+- print "Error in script: %s" % upgrader
++ print("Error in script: %s" % upgrader)
+ raise
+ self.update_db(next_version, conn)
+- print 'Done.'
++ print('Done.')
+
+
+ def current_version(self):
+ conn = self.connection()
+ if not conn.tableExists(SQLObjectVersionTable.sqlmeta.table):
+- print 'No sqlobject_version table!'
++ print('No sqlobject_version table!')
+ sys.exit(1)
+ versions = list(SQLObjectVersionTable.select(connection=conn))
+ if not versions:
+- print 'No rows in sqlobject_version!'
++ print('No rows in sqlobject_version!')
+ sys.exit(1)
+ if len(versions) > 1:
+- print 'Ambiguous sqlobject_version_table'
++ print('Ambiguous sqlobject_version_table')
+ sys.exit(1)
+ return versions[0].version
+
+@@ -1216,9 +1213,9 @@ class CommandUpgrade(CommandRecord):
+ dbname = self.connection().dbName
+ next_version, upgrader = self.best_upgrade(current, dest, dbname)
+ if not upgrader:
+- print 'No way to upgrade from %s to %s' % (current, dest)
+- print ('(you need a %s/upgrade_%s_%s.sql script)'
+- % (current, dbname, dest))
++ print('No way to upgrade from %s to %s' % (current, dest))
++ print(('(you need a %s/upgrade_%s_%s.sql script)'
++ % (current, dbname, dest)))
+ sys.exit(1)
+ plan = [(next_version, upgrader)]
+ if next_version == dest:
+@@ -1229,42 +1226,42 @@ class CommandUpgrade(CommandRecord):
+ def best_upgrade(self, current, dest, target_dbname):
+ current_dir = os.path.join(self.base_dir(), current)
+ if self.options.verbose > 1:
+- print ('Looking in %s for upgraders'
+- % self.shorten_filename(current_dir))
++ print(('Looking in %s for upgraders'
++ % self.shorten_filename(current_dir)))
+ upgraders = []
+ for fn in os.listdir(current_dir):
+ match = self.upgrade_regex.search(fn)
+ if not match:
+ if self.options.verbose > 1:
+- print 'Not an upgrade script: %s' % fn
++ print('Not an upgrade script: %s' % fn)
+ continue
+ dbname = match.group(1)
+ version = match.group(2)
+ if dbname != target_dbname:
+ if self.options.verbose > 1:
+- print 'Not for this database: %s (want %s)' % (
+- dbname, target_dbname)
++ print('Not for this database: %s (want %s)' % (
++ dbname, target_dbname))
+ continue
+ if version > dest:
+ if self.options.verbose > 1:
+- print 'Version too new: %s (only want %s)' % (
+- version, dest)
++ print('Version too new: %s (only want %s)' % (
++ version, dest))
+ upgraders.append((version, os.path.join(current_dir, fn)))
+ if not upgraders:
+ if self.options.verbose > 1:
+- print 'No upgraders found in %s' % current_dir
++ print('No upgraders found in %s' % current_dir)
+ return None, None
+ upgraders.sort()
+ return upgraders[-1]
+
+ def update_sys_path(paths, verbose):
+- if isinstance(paths, basestring):
++ if isinstance(paths, str):
+ paths = [paths]
+ for path in paths:
+ path = os.path.abspath(path)
+ if path not in sys.path:
+ if verbose > 1:
+- print 'Adding %s to path' % path
++ print('Adding %s to path' % path)
+ sys.path.insert(0, path)
+
+ if __name__ == '__main__':
+--- sqlobject/maxdb/maxdbconnection.py.orig 2022-03-15 19:15:16 UTC
++++ sqlobject/maxdb/maxdbconnection.py
+@@ -246,7 +246,7 @@ class MaxdbConnection(DBAPI):
+ pkmap[col_name]=True
+
+ if len(pkmap) == 0:
+- raise PrimaryKeyNotFounded, tableName
++ raise PrimaryKeyNotFounded(tableName)
+
+ for (field, nullAllowed, default, data_type, data_len,
+ data_scale) in colData:
+--- sqlobject/mysql/mysqlconnection.py.orig 2011-05-08 15:49:57 UTC
++++ sqlobject/mysql/mysqlconnection.py
+@@ -69,7 +69,7 @@ class MySQLConnection(DBAPI):
+ db=self.db, user=self.user, passwd=self.password, **self.kw)
+ if self.module.version_info[:3] >= (1, 2, 2):
+ conn.ping(True) # Attempt to reconnect. This setting is persistent.
+- except self.module.OperationalError, e:
++ except self.module.OperationalError as e:
+ conninfo = "; used connection string: host=%(host)s, port=%(port)s, db=%(db)s, user=%(user)s" % self.__dict__
+ raise OperationalError(ErrorMessage(e, conninfo))
+
+@@ -90,9 +90,9 @@ class MySQLConnection(DBAPI):
+ conn.autocommit(auto)
+
+ def _executeRetry(self, conn, cursor, query):
+- if self.need_unicode and not isinstance(query, unicode):
++ if self.need_unicode and not isinstance(query, str):
+ try:
+- query = unicode(query, self.dbEncoding)
++ query = str(query, self.dbEncoding)
+ except UnicodeError:
+ pass
+
+@@ -111,7 +111,7 @@ class MySQLConnection(DBAPI):
+ for count in range(3):
+ try:
+ return cursor.execute(query)
+- except self.module.OperationalError, e:
++ except self.module.OperationalError as e:
+ if e.args[0] in (self.module.constants.CR.SERVER_GONE_ERROR, self.module.constants.CR.SERVER_LOST):
+ if count == 2:
+ raise OperationalError(ErrorMessage(e))
+@@ -119,27 +119,27 @@ class MySQLConnection(DBAPI):
+ self.printDebug(conn, str(e), 'ERROR')
+ else:
+ raise OperationalError(ErrorMessage(e))
+- except self.module.IntegrityError, e:
++ except self.module.IntegrityError as e:
+ msg = ErrorMessage(e)
+ if e.args[0] == self.module.constants.ER.DUP_ENTRY:
+ raise DuplicateEntryError(msg)
+ else:
+ raise IntegrityError(msg)
+- except self.module.InternalError, e:
++ except self.module.InternalError as e:
+ raise InternalError(ErrorMessage(e))
+- except self.module.ProgrammingError, e:
++ except self.module.ProgrammingError as e:
+ raise ProgrammingError(ErrorMessage(e))
+- except self.module.DataError, e:
++ except self.module.DataError as e:
+ raise DataError(ErrorMessage(e))
+- except self.module.NotSupportedError, e:
++ except self.module.NotSupportedError as e:
+ raise NotSupportedError(ErrorMessage(e))
+- except self.module.DatabaseError, e:
++ except self.module.DatabaseError as e:
+ raise DatabaseError(ErrorMessage(e))
+- except self.module.InterfaceError, e:
++ except self.module.InterfaceError as e:
+ raise InterfaceError(ErrorMessage(e))
+- except self.module.Warning, e:
++ except self.module.Warning as e:
+ raise Warning(ErrorMessage(e))
+- except self.module.Error, e:
++ except self.module.Error as e:
+ raise Error(ErrorMessage(e))
+
+ def _queryInsertID(self, conn, soInstance, id, names, values):
+@@ -194,7 +194,7 @@ class MySQLConnection(DBAPI):
+ # which is not always True (for an embedded application, e.g.)
+ self.query('DESCRIBE %s' % (tableName))
+ return True
+- except ProgrammingError, e:
++ except ProgrammingError as e:
+ if e[0].code == 1146: # ER_NO_SUCH_TABLE
+ return False
+ raise
+--- sqlobject/postgres/pgconnection.py.orig 2013-09-30 14:25:11 UTC
++++ sqlobject/postgres/pgconnection.py
+@@ -142,7 +142,7 @@ class PostgresConnection(DBAPI):
+ conn = self.module.connect(self.dsn)
+ else:
+ conn = self.module.connect(**self.dsn_dict)
+- except self.module.OperationalError, e:
++ except self.module.OperationalError as e:
+ raise OperationalError(ErrorMessage(e, "used connection string %r" % self.dsn))
+
+ # For printDebug in _executeRetry
+@@ -162,29 +162,29 @@ class PostgresConnection(DBAPI):
+ self.printDebug(conn, query, 'QueryR')
+ try:
+ return cursor.execute(query)
+- except self.module.OperationalError, e:
++ except self.module.OperationalError as e:
+ raise OperationalError(ErrorMessage(e))
+- except self.module.IntegrityError, e:
++ except self.module.IntegrityError as e:
+ msg = ErrorMessage(e)
+ if e.pgcode == '23505':
+ raise DuplicateEntryError(msg)
+ else:
+ raise IntegrityError(msg)
+- except self.module.InternalError, e:
++ except self.module.InternalError as e:
+ raise InternalError(ErrorMessage(e))
+- except self.module.ProgrammingError, e:
++ except self.module.ProgrammingError as e:
+ raise ProgrammingError(ErrorMessage(e))
+- except self.module.DataError, e:
++ except self.module.DataError as e:
+ raise DataError(ErrorMessage(e))
+- except self.module.NotSupportedError, e:
++ except self.module.NotSupportedError as e:
+ raise NotSupportedError(ErrorMessage(e))
+- except self.module.DatabaseError, e:
++ except self.module.DatabaseError as e:
+ raise DatabaseError(ErrorMessage(e))
+- except self.module.InterfaceError, e:
++ except self.module.InterfaceError as e:
+ raise InterfaceError(ErrorMessage(e))
+- except self.module.Warning, e:
++ except self.module.Warning as e:
+ raise Warning(ErrorMessage(e))
+- except self.module.Error, e:
++ except self.module.Error as e:
+ raise Error(ErrorMessage(e))
+
+ def _queryInsertID(self, conn, soInstance, id, names, values):
+--- sqlobject/sqlbuilder.py.orig 2013-10-05 12:02:45 UTC
++++ sqlobject/sqlbuilder.py
+@@ -67,8 +67,8 @@ import threading
+ import types
+ import weakref
+
+-import classregistry
+-from converters import registerConverter, sqlrepr, quote_str, unquote_str
++from . import classregistry
++from .converters import registerConverter, sqlrepr, quote_str, unquote_str
+
+
+ class VersionError(Exception):
+@@ -86,7 +86,7 @@ class SQLObjectState(object):
+ safeSQLRE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_\.]*$')
+ def sqlIdentifier(obj):
+ # some db drivers return unicode column names
+- return isinstance(obj, basestring) and bool(safeSQLRE.search(obj.strip()))
++ return isinstance(obj, str) and bool(safeSQLRE.search(obj.strip()))
+
+
+ def execute(expr, executor):
+@@ -97,7 +97,7 @@ def execute(expr, executor):
+
+
+ def _str_or_sqlrepr(expr, db):
+- if isinstance(expr, basestring):
++ if isinstance(expr, str):
+ return expr
+ return sqlrepr(expr, db)
+
+@@ -181,9 +181,9 @@ class SQLExpression:
+ return repr(self)
+
+ def __cmp__(self, other):
+- raise VersionError, "Python 2.1+ required"
++ raise VersionError("Python 2.1+ required")
+ def __rcmp__(self, other):
+- raise VersionError, "Python 2.1+ required"
++ raise VersionError("Python 2.1+ required")
+
+ def startswith(self, s):
+ return STARTSWITH(self, s)
+@@ -287,7 +287,7 @@ class SQLCall(SQLExpression):
+ def components(self):
+ return [self.expr] + list(self.args)
+ def execute(self, executor):
+- raise ValueError, "I don't yet know how to locally execute functions"
++ raise ValueError("I don't yet know how to locally execute functions")
+
+ registerConverter(SQLCall, SQLExprConverter)
+
+@@ -316,7 +316,7 @@ class SQLConstant(SQLExpression):
+ def __sqlrepr__(self, db):
+ return self.const
+ def execute(self, executor):
+- raise ValueError, "I don't yet know how to execute SQL constants"
++ raise ValueError("I don't yet know how to execute SQL constants")
+
+ registerConverter(SQLConstant, SQLExprConverter)
+
+@@ -391,7 +391,7 @@ class Table(SQLExpression):
+ def __sqlrepr__(self, db):
+ return _str_or_sqlrepr(self.tableName, db)
+ def execute(self, executor):
+- raise ValueError, "Tables don't have values"
++ raise ValueError("Tables don't have values")
+
+ class SQLObjectTable(Table):
+ FieldClass = SQLObjectField
+@@ -411,7 +411,7 @@ class SQLObjectTable(Table):
+ elif attr in self.soClass.sqlmeta.columns:
+ column = self.soClass.sqlmeta.columns[attr]
+ return self._getattrFromColumn(column, attr)
+- elif attr+'ID' in [k for (k, v) in self.soClass.sqlmeta.columns.items() if v.foreignKey]:
++ elif attr+'ID' in [k for (k, v) in list(self.soClass.sqlmeta.columns.items()) if v.foreignKey]:
+ attr += 'ID'
+ column = self.soClass.sqlmeta.columns[attr]
+ return self._getattrFromColumn(column, attr)
+@@ -427,7 +427,7 @@ class SQLObjectTable(Table):
+ class SQLObjectTableWithJoins(SQLObjectTable):
+
+ def __getattr__(self, attr):
+- if attr+'ID' in [k for (k, v) in self.soClass.sqlmeta.columns.items() if v.foreignKey]:
++ if attr+'ID' in [k for (k, v) in list(self.soClass.sqlmeta.columns.items()) if v.foreignKey]:
+ column = self.soClass.sqlmeta.columns[attr+'ID']
+ return self._getattrFromForeignKey(column, attr)
+ elif attr in [x.joinMethodName for x in self.soClass.sqlmeta.joins]:
+@@ -616,7 +616,7 @@ class Select(SQLExpression):
+ # None doesn't filter anything, it's just a no-op:
+ return self
+ clause = self.ops['clause']
+- if isinstance(clause, basestring):
++ if isinstance(clause, str):
+ clause = SQLConstant('(%s)' % clause)
+ return self.newClause(AND(clause, filter_clause))
+
+@@ -697,7 +697,7 @@ class Select(SQLExpression):
+ if self.ops['limit'] is not NoDefault:
+ end = start + self.ops['limit']
+ if start or end:
+- from dbconnection import dbConnectionForScheme
++ from .dbconnection import dbConnectionForScheme
+ select = dbConnectionForScheme(db)._queryAddLimitOffset(select, start, end)
+ if self.ops['forUpdate']:
+ select += " FOR UPDATE"
+@@ -711,7 +711,7 @@ class Insert(SQLExpression):
+ self.table = table
+ if valueList:
+ if values:
+- raise TypeError, "You may only give valueList *or* values"
++ raise TypeError("You may only give valueList *or* values")
+ self.valueList = valueList
+ else:
+ self.valueList = [values]
+@@ -722,7 +722,7 @@ class Insert(SQLExpression):
+ allowNonDict = True
+ template = self.template
+ if (template is NoDefault) and isinstance(self.valueList[0], dict):
+- template = self.valueList[0].keys()
++ template = list(self.valueList[0].keys())
+ allowNonDict = False
+ if template is not NoDefault:
+ insert += " (%s)" % ", ".join(template)
+@@ -732,10 +732,10 @@ class Insert(SQLExpression):
+ for value in self.valueList:
+ if isinstance(value, dict):
+ if template is NoDefault:
+- raise TypeError, "You can't mix non-dictionaries with dictionaries in an INSERT if you don't provide a template (%s)" % repr(value)
++ raise TypeError("You can't mix non-dictionaries with dictionaries in an INSERT if you don't provide a template (%s)" % repr(value))
+ value = dictToList(template, value)
+ elif not allowNonDict:
+- raise TypeError, "You can't mix non-dictionaries with dictionaries in an INSERT if you don't provide a template (%s)" % repr(value)
++ raise TypeError("You can't mix non-dictionaries with dictionaries in an INSERT if you don't provide a template (%s)" % repr(value))
+ listToJoin_app("(%s)" % ", ".join([sqlrepr(v, db) for v in value]))
+ insert = "%s%s" % (insert, ", ".join(listToJoin))
+ return insert
+@@ -746,8 +746,8 @@ def dictToList(template, dict):
+ list = []
+ for key in template:
+ list.append(dict[key])
+- if len(dict.keys()) > len(template):
+- raise TypeError, "Extra entries in dictionary that aren't asked for in template (template=%s, dict=%s)" % (repr(template), repr(dict))
++ if len(list(dict.keys())) > len(template):
++ raise TypeError("Extra entries in dictionary that aren't asked for in template (template=%s, dict=%s)" % (repr(template), repr(dict)))
+ return list
+
+ class Update(SQLExpression):
+@@ -768,7 +768,7 @@ class Update(SQLExpression):
+ update += ","
+ update += " %s=%s" % (self.template[i], sqlrepr(self.values[i], db))
+ else:
+- for key, value in self.values.items():
++ for key, value in list(self.values.items()):
+ if first:
+ first = False
+ else:
+@@ -788,7 +788,7 @@ class Delete(SQLExpression):
+ def __init__(self, table, where=NoDefault):
+ self.table = table
+ if where is NoDefault:
+- raise TypeError, "You must give a where clause or pass in None to indicate no where clause"
++ raise TypeError("You must give a where clause or pass in None to indicate no where clause")
+ self.whereClause = where
+ def __sqlrepr__(self, db):
+ whereClause = self.whereClause
+@@ -846,7 +846,7 @@ def _IN(item, list):
+ return SQLOp("IN", item, list)
+
+ def IN(item, list):
+- from sresults import SelectResults # Import here to avoid circular import
++ from .sresults import SelectResults # Import here to avoid circular import
+ if isinstance(list, SelectResults):
+ query = list.queryForSelect()
+ query.ops['items'] = [list.sourceClass.q.id]
+@@ -880,7 +880,7 @@ def ISNOTNULL(expr):
+ class ColumnAS(SQLOp):
+ ''' Just like SQLOp('AS', expr, name) except without the parentheses '''
+ def __init__(self, expr, name):
+- if isinstance(name, basestring):
++ if isinstance(name, str):
+ name = SQLConstant(name)
+ SQLOp.__init__(self, 'AS', expr, name)
+ def __sqlrepr__(self, db):
+@@ -919,11 +919,11 @@ class _LikeQuoted:
+ return "CONCAT(%s)" % ", ".join(values)
+ else:
+ return " || ".join(values)
+- elif isinstance(s, basestring):
++ elif isinstance(s, str):
+ s = _quote_like_special(unquote_str(sqlrepr(s, db)), db)
+ return quote_str("%s%s%s" % (self.prefix, s, self.postfix), db)
+ else:
+- raise TypeError, "expected str, unicode or SQLExpression, got %s" % type(s)
++ raise TypeError("expected str, unicode or SQLExpression, got %s" % type(s))
+
+ def _quote_like_special(s, db):
+ if db in ('postgres', 'rdbhost'):
+@@ -1021,9 +1021,9 @@ class SQLJoinConditional(SQLJoin):
+ (Table1.q.col1, Table2.q.col2)
+ """
+ if not on_condition and not using_columns:
+- raise TypeError, "You must give ON condition or USING columns"
++ raise TypeError("You must give ON condition or USING columns")
+ if on_condition and using_columns:
+- raise TypeError, "You must give ON condition or USING columns but not both"
++ raise TypeError("You must give ON condition or USING columns but not both")
+ SQLJoin.__init__(self, table1, table2, op)
+ self.on_condition = on_condition
+ self.using_columns = using_columns
+@@ -1254,7 +1254,7 @@ class ImportProxy(SQLExpression):
+ self.soClass = None
+ classregistry.registry(registry).addClassCallback(clsName, lambda foreign, me: setattr(me, 'soClass', foreign), self)
+
+- def __nonzero__(self):
++ def __bool__(self):
+ return True
+
+ def __getattr__(self, attr):
+--- sqlobject/sqlite/sqliteconnection.py.orig 2014-04-12 20:42:31 UTC
++++ sqlobject/sqlite/sqliteconnection.py
+@@ -1,7 +1,7 @@
+ import base64
+ import os
+-import thread
+-import urllib
++import _thread
++import urllib.request, urllib.parse, urllib.error
+ from sqlobject.dbconnection import DBAPI, Boolean
+ from sqlobject import col, sqlbuilder
+ from sqlobject.dberrors import *
+@@ -121,7 +121,7 @@ class SQLiteConnection(DBAPI):
+ path = "//" + path
+ else:
+ path = "///" + path
+- path = urllib.quote(path)
++ path = urllib.parse.quote(path)
+ return 'sqlite:%s' % path
+
+ def getConnection(self):
+@@ -133,7 +133,7 @@ class SQLiteConnection(DBAPI):
+ self._connectionNumbers[id(conn)] = self._connectionCount
+ self._connectionCount += 1
+ return conn
+- threadid = thread.get_ident()
++ threadid = _thread.get_ident()
+ if (self._pool is not None
+ and threadid in self._threadPool):
+ conn = self._threadPool[threadid]
+@@ -206,30 +206,30 @@ class SQLiteConnection(DBAPI):
+ self.printDebug(conn, query, 'QueryR')
+ try:
+ return cursor.execute(query)
+- except self.module.OperationalError, e:
++ except self.module.OperationalError as e:
+ raise OperationalError(ErrorMessage(e))
+- except self.module.IntegrityError, e:
++ except self.module.IntegrityError as e:
+ msg = ErrorMessage(e)
+ if msg.startswith('column') and msg.endswith('not unique') \
+ or msg.startswith('UNIQUE constraint failed:'):
+ raise DuplicateEntryError(msg)
+ else:
+ raise IntegrityError(msg)
+- except self.module.InternalError, e:
++ except self.module.InternalError as e:
+ raise InternalError(ErrorMessage(e))
+- except self.module.ProgrammingError, e:
++ except self.module.ProgrammingError as e:
+ raise ProgrammingError(ErrorMessage(e))
+- except self.module.DataError, e:
++ except self.module.DataError as e:
+ raise DataError(ErrorMessage(e))
+- except self.module.NotSupportedError, e:
++ except self.module.NotSupportedError as e:
+ raise NotSupportedError(ErrorMessage(e))
+- except self.module.DatabaseError, e:
++ except self.module.DatabaseError as e:
+ raise DatabaseError(ErrorMessage(e))
+- except self.module.InterfaceError, e:
++ except self.module.InterfaceError as e:
+ raise InterfaceError(ErrorMessage(e))
+- except self.module.Warning, e:
++ except self.module.Warning as e:
+ raise Warning(ErrorMessage(e))
+- except self.module.Error, e:
++ except self.module.Error as e:
+ raise Error(ErrorMessage(e))
+
+ def _queryInsertID(self, conn, soInstance, id, names, values):
+--- sqlobject/util/moduleloader.py.orig 2011-05-15 15:48:27 UTC
++++ sqlobject/util/moduleloader.py
+@@ -15,7 +15,7 @@ def load_module_from_name(filename, module_name):
+ if not os.path.exists(init_filename):
+ try:
+ f = open(init_filename, 'w')
+- except (OSError, IOError), e:
++ except (OSError, IOError) as e:
+ raise IOError(
+ 'Cannot write __init__.py file into directory %s (%s)\n'
+ % (os.path.dirname(filename), e))