git: b117f7f8f772 - main - databases/py-sqlobject: Fix build with setuptools 58.0.0+

From: Po-Chuan Hsieh <sunpoet_at_FreeBSD.org>
Date: Fri, 25 Mar 2022 13:49:45 UTC
The branch main has been updated by sunpoet:

URL: https://cgit.FreeBSD.org/ports/commit/?id=b117f7f8f7723515ea1f847cd66293719ce324bf

commit b117f7f8f7723515ea1f847cd66293719ce324bf
Author:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
AuthorDate: 2022-03-25 13:32:07 +0000
Commit:     Po-Chuan Hsieh <sunpoet@FreeBSD.org>
CommitDate: 2022-03-25 13:38:06 +0000

    databases/py-sqlobject: Fix build with setuptools 58.0.0+
    
    With hat:       python
---
 databases/py-sqlobject/Makefile         |    2 +-
 databases/py-sqlobject/files/patch-2to3 | 2505 +++++++++++++++++++++++++++++++
 2 files changed, 2506 insertions(+), 1 deletion(-)

diff --git a/databases/py-sqlobject/Makefile b/databases/py-sqlobject/Makefile
index 96770c5846c2..5f7f49091410 100644
--- a/databases/py-sqlobject/Makefile
+++ b/databases/py-sqlobject/Makefile
@@ -17,7 +17,7 @@ BUILD_DEPENDS=	${PYTHON_PKGNAMEPREFIX}formencode>=1.2.2:www/py-formencode@${PY_F
 RUN_DEPENDS:=	${BUILD_DEPENDS}
 
 NO_ARCH=	yes
-USES=		python:3.6+
+USES=		dos2unix python:3.6+
 USE_PYTHON=	autoplist distutils
 
 # currently MaxDB(SAP), ADODB are not supported
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')):
*** 1555 LINES SKIPPED ***