From 4b614b9b35cd2baddb7ca67c04bee5d70ec6a172 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 27 Apr 2013 19:53:57 -0400 Subject: - the raw 2to3 run - went through examples/ and cleaned out excess list() calls --- lib/sqlalchemy/__init__.py | 2 +- lib/sqlalchemy/connectors/mxodbc.py | 2 +- lib/sqlalchemy/connectors/pyodbc.py | 26 ++-- lib/sqlalchemy/dialects/firebird/base.py | 4 +- lib/sqlalchemy/dialects/informix/base.py | 9 +- lib/sqlalchemy/dialects/mssql/adodbapi.py | 2 +- lib/sqlalchemy/dialects/mssql/base.py | 20 +-- .../dialects/mssql/information_schema.py | 8 +- lib/sqlalchemy/dialects/mssql/pyodbc.py | 2 +- lib/sqlalchemy/dialects/mysql/base.py | 44 +++--- lib/sqlalchemy/dialects/mysql/cymysql.py | 17 +-- lib/sqlalchemy/dialects/mysql/oursql.py | 17 +-- lib/sqlalchemy/dialects/mysql/zxjdbc.py | 2 +- lib/sqlalchemy/dialects/oracle/base.py | 30 ++-- lib/sqlalchemy/dialects/oracle/cx_oracle.py | 97 ++++++------- lib/sqlalchemy/dialects/oracle/zxjdbc.py | 4 +- lib/sqlalchemy/dialects/postgresql/base.py | 61 ++++---- lib/sqlalchemy/dialects/postgresql/hstore.py | 4 +- lib/sqlalchemy/dialects/postgresql/psycopg2.py | 30 ++-- lib/sqlalchemy/dialects/sqlite/base.py | 4 +- lib/sqlalchemy/dialects/sqlite/pysqlite.py | 7 +- lib/sqlalchemy/dialects/sybase/__init__.py | 2 +- lib/sqlalchemy/dialects/sybase/base.py | 36 ++--- lib/sqlalchemy/engine/base.py | 22 +-- lib/sqlalchemy/engine/ddl.py | 8 +- lib/sqlalchemy/engine/default.py | 60 ++++---- lib/sqlalchemy/engine/reflection.py | 18 +-- lib/sqlalchemy/engine/result.py | 38 ++--- lib/sqlalchemy/engine/strategies.py | 25 ++-- lib/sqlalchemy/engine/url.py | 18 +-- lib/sqlalchemy/event.py | 10 +- lib/sqlalchemy/exc.py | 2 +- lib/sqlalchemy/ext/associationproxy.py | 32 ++--- lib/sqlalchemy/ext/declarative/api.py | 2 +- lib/sqlalchemy/ext/declarative/base.py | 8 +- lib/sqlalchemy/ext/declarative/clsregistry.py | 6 +- lib/sqlalchemy/ext/mutable.py | 4 +- lib/sqlalchemy/ext/orderinglist.py | 24 ++-- lib/sqlalchemy/ext/serializer.py | 26 ++-- lib/sqlalchemy/orm/__init__.py | 2 +- lib/sqlalchemy/orm/attributes.py | 2 +- lib/sqlalchemy/orm/collections.py | 79 ++++++----- lib/sqlalchemy/orm/descriptor_props.py | 2 +- lib/sqlalchemy/orm/evaluator.py | 12 +- lib/sqlalchemy/orm/identity.py | 50 +++---- lib/sqlalchemy/orm/instrumentation.py | 30 ++-- lib/sqlalchemy/orm/interfaces.py | 4 +- lib/sqlalchemy/orm/loading.py | 12 +- lib/sqlalchemy/orm/mapper.py | 28 ++-- lib/sqlalchemy/orm/persistence.py | 22 +-- lib/sqlalchemy/orm/properties.py | 4 +- lib/sqlalchemy/orm/query.py | 43 +++--- lib/sqlalchemy/orm/session.py | 20 +-- lib/sqlalchemy/orm/state.py | 2 +- lib/sqlalchemy/orm/strategies.py | 8 +- lib/sqlalchemy/orm/unitofwork.py | 8 +- lib/sqlalchemy/orm/util.py | 24 ++-- lib/sqlalchemy/pool.py | 12 +- lib/sqlalchemy/processors.py | 6 +- lib/sqlalchemy/schema.py | 97 ++++++------- lib/sqlalchemy/sql/__init__.py | 2 +- lib/sqlalchemy/sql/compiler.py | 63 ++++----- lib/sqlalchemy/sql/expression.py | 84 +++++------ lib/sqlalchemy/sql/functions.py | 3 +- lib/sqlalchemy/sql/operators.py | 10 +- lib/sqlalchemy/sql/util.py | 16 +-- lib/sqlalchemy/sql/visitors.py | 4 +- lib/sqlalchemy/testing/__init__.py | 2 +- lib/sqlalchemy/testing/assertions.py | 31 +++-- lib/sqlalchemy/testing/assertsql.py | 10 +- lib/sqlalchemy/testing/engines.py | 43 +++--- lib/sqlalchemy/testing/entities.py | 4 +- lib/sqlalchemy/testing/exclusions.py | 10 +- lib/sqlalchemy/testing/fixtures.py | 16 +-- lib/sqlalchemy/testing/plugin/noseplugin.py | 10 +- lib/sqlalchemy/testing/profiling.py | 10 +- lib/sqlalchemy/testing/schema.py | 4 +- lib/sqlalchemy/testing/suite/test_ddl.py | 2 +- lib/sqlalchemy/testing/suite/test_reflection.py | 4 +- lib/sqlalchemy/testing/suite/test_types.py | 18 +-- lib/sqlalchemy/testing/util.py | 18 +-- lib/sqlalchemy/testing/warnings.py | 4 +- lib/sqlalchemy/types.py | 155 +++++++++++---------- lib/sqlalchemy/util/_collections.py | 40 +++--- lib/sqlalchemy/util/compat.py | 15 +- lib/sqlalchemy/util/deprecations.py | 2 +- lib/sqlalchemy/util/langhelpers.py | 139 +++++++++--------- 87 files changed, 980 insertions(+), 939 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/__init__.py b/lib/sqlalchemy/__init__.py index 6e924ea9d..d92b81eac 100644 --- a/lib/sqlalchemy/__init__.py +++ b/lib/sqlalchemy/__init__.py @@ -117,7 +117,7 @@ from .inspection import inspect from .engine import create_engine, engine_from_config -__all__ = sorted(name for name, obj in locals().items() +__all__ = sorted(name for name, obj in list(locals().items()) if not (name.startswith('_') or _inspect.ismodule(obj))) __version__ = '0.8.1' diff --git a/lib/sqlalchemy/connectors/mxodbc.py b/lib/sqlalchemy/connectors/mxodbc.py index db297c9ab..ebdcd2758 100644 --- a/lib/sqlalchemy/connectors/mxodbc.py +++ b/lib/sqlalchemy/connectors/mxodbc.py @@ -82,7 +82,7 @@ class MxODBCConnector(Connector): category=errorclass, stacklevel=2) else: - raise errorclass, errorvalue + raise errorclass(errorvalue) return error_handler def create_connect_args(self, url): diff --git a/lib/sqlalchemy/connectors/pyodbc.py b/lib/sqlalchemy/connectors/pyodbc.py index f1a979286..504414b0f 100644 --- a/lib/sqlalchemy/connectors/pyodbc.py +++ b/lib/sqlalchemy/connectors/pyodbc.py @@ -9,7 +9,7 @@ from ..util import asbool import sys import re -import urllib +import urllib.request, urllib.parse, urllib.error class PyODBCConnector(Connector): @@ -59,7 +59,7 @@ class PyODBCConnector(Connector): connect_args[param] = asbool(keys.pop(param)) if 'odbc_connect' in keys: - connectors = [urllib.unquote_plus(keys.pop('odbc_connect'))] + connectors = [urllib.parse.unquote_plus(keys.pop('odbc_connect'))] else: dsn_connection = 'dsn' in keys or \ ('host' in keys and 'database' not in keys) @@ -91,7 +91,7 @@ class PyODBCConnector(Connector): connectors.append("AutoTranslate=%s" % keys.pop("odbc_autotranslate")) - connectors.extend(['%s=%s' % (k, v) for k, v in keys.iteritems()]) + connectors.extend(['%s=%s' % (k, v) for k, v in keys.items()]) return [[";".join(connectors)], connect_args] def is_disconnect(self, e, connection, cursor): @@ -123,16 +123,16 @@ class PyODBCConnector(Connector): # the "Py2K only" part here is theoretical. # have not tried pyodbc + python3.1 yet. - # Py2K - self.supports_unicode_statements = ( - not self.freetds and not self.easysoft) - if self._user_supports_unicode_binds is not None: - self.supports_unicode_binds = self._user_supports_unicode_binds - else: - self.supports_unicode_binds = ( - not self.freetds or self.freetds_driver_version >= '0.91' - ) and not self.easysoft - # end Py2K +# start Py2K +# self.supports_unicode_statements = ( +# not self.freetds and not self.easysoft) +# if self._user_supports_unicode_binds is not None: +# self.supports_unicode_binds = self._user_supports_unicode_binds +# else: +# self.supports_unicode_binds = ( +# not self.freetds or self.freetds_driver_version >= '0.91' +# ) and not self.easysoft +# end Py2K # run other initialization which asks for user name, etc. super(PyODBCConnector, self).initialize(connection) diff --git a/lib/sqlalchemy/dialects/firebird/base.py b/lib/sqlalchemy/dialects/firebird/base.py index 95196f44c..bb60a591e 100644 --- a/lib/sqlalchemy/dialects/firebird/base.py +++ b/lib/sqlalchemy/dialects/firebird/base.py @@ -685,7 +685,7 @@ class FBDialect(default.DefaultDialect): self.normalize_name(row['fname'])) fk['referred_columns'].append( self.normalize_name(row['targetfname'])) - return fks.values() + return list(fks.values()) @reflection.cache def get_indexes(self, connection, table_name, schema=None, **kw): @@ -716,7 +716,7 @@ class FBDialect(default.DefaultDialect): indexrec['column_names'].append( self.normalize_name(row['field_name'])) - return indexes.values() + return list(indexes.values()) def do_execute(self, cursor, statement, parameters, context=None): # kinterbase does not accept a None, but wants an empty list diff --git a/lib/sqlalchemy/dialects/informix/base.py b/lib/sqlalchemy/dialects/informix/base.py index 77361a5d0..691400e05 100644 --- a/lib/sqlalchemy/dialects/informix/base.py +++ b/lib/sqlalchemy/dialects/informix/base.py @@ -24,6 +24,7 @@ from sqlalchemy import sql, schema, exc, pool, util from sqlalchemy.sql import compiler, text from sqlalchemy.engine import default, reflection from sqlalchemy import types as sqltypes +from functools import reduce RESERVED_WORDS = set( ["abs", "absolute", "access", "access_method", "acos", "active", "add", @@ -298,7 +299,7 @@ class InfoDDLCompiler(compiler.DDLCompiler): def get_column_default_string(self, column): if (isinstance(column.server_default, schema.DefaultClause) and - isinstance(column.server_default.arg, basestring)): + isinstance(column.server_default.arg, str)): if isinstance(column.type, (sqltypes.Integer, sqltypes.Numeric)): return self.sql_compiler.process(text(column.server_default.arg)) @@ -322,10 +323,10 @@ class InfoDDLCompiler(compiler.DDLCompiler): remote_table = list(constraint._elements.values())[0].column.table text = "FOREIGN KEY (%s) REFERENCES %s (%s)" % ( ', '.join(preparer.quote(f.parent.name, f.parent.quote) - for f in constraint._elements.values()), + for f in list(constraint._elements.values())), preparer.format_table(remote_table), ', '.join(preparer.quote(f.column.name, f.column.quote) - for f in constraint._elements.values()) + for f in list(constraint._elements.values())) ) text += self.define_constraint_cascades(constraint) text += self.define_constraint_deferrability(constraint) @@ -506,7 +507,7 @@ class InformixDialect(default.DefaultDialect): if remote_column not in remote_cols: remote_cols.append(remote_column) - return fkeys.values() + return list(fkeys.values()) @reflection.cache def get_pk_constraint(self, connection, table_name, schema=None, **kw): diff --git a/lib/sqlalchemy/dialects/mssql/adodbapi.py b/lib/sqlalchemy/dialects/mssql/adodbapi.py index 167b4e807..080382d55 100644 --- a/lib/sqlalchemy/dialects/mssql/adodbapi.py +++ b/lib/sqlalchemy/dialects/mssql/adodbapi.py @@ -44,7 +44,7 @@ class MSDialect_adodbapi(MSDialect): @classmethod def import_dbapi(cls): - import adodbapi as module + from . import adodbapi as module return module colspecs = util.update_copy( diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 70ffcb8cd..827cf0186 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -295,7 +295,7 @@ class _MSDate(sqltypes.Date): def process(value): if isinstance(value, datetime.datetime): return value.date() - elif isinstance(value, basestring): + elif isinstance(value, str): return datetime.date(*[ int(x or 0) for x in self._reg.match(value).groups() @@ -328,7 +328,7 @@ class TIME(sqltypes.TIME): def process(value): if isinstance(value, datetime.datetime): return value.time() - elif isinstance(value, basestring): + elif isinstance(value, str): return datetime.time(*[ int(x or 0) for x in self._reg.match(value).groups()]) @@ -1002,7 +1002,7 @@ class MSDDLCompiler(compiler.DDLCompiler): # handle other included columns if index.kwargs.get("mssql_include"): inclusions = [index.table.c[col] - if isinstance(col, basestring) else col + if isinstance(col, str) else col for col in index.kwargs["mssql_include"]] text += " INCLUDE (%s)" \ @@ -1103,7 +1103,7 @@ class MSDialect(default.DefaultDialect): query_timeout=None, use_scope_identity=True, max_identifier_length=None, - schema_name=u"dbo", **opts): + schema_name="dbo", **opts): self.query_timeout = int(query_timeout or 0) self.schema_name = schema_name @@ -1123,7 +1123,7 @@ class MSDialect(default.DefaultDialect): def initialize(self, connection): super(MSDialect, self).initialize(connection) - if self.server_version_info[0] not in range(8, 17): + if self.server_version_info[0] not in list(range(8, 17)): # FreeTDS with version 4.2 seems to report here # a number like "95.10.255". Don't know what # that is. So emit warning. @@ -1150,7 +1150,7 @@ class MSDialect(default.DefaultDialect): try: default_schema_name = connection.scalar(query, name=user_name) if default_schema_name is not None: - return unicode(default_schema_name) + return str(default_schema_name) except: pass return self.schema_name @@ -1188,7 +1188,7 @@ class MSDialect(default.DefaultDialect): s = sql.select([tables.c.table_name], sql.and_( tables.c.table_schema == owner, - tables.c.table_type == u'BASE TABLE' + tables.c.table_type == 'BASE TABLE' ), order_by=[tables.c.table_name] ) @@ -1202,7 +1202,7 @@ class MSDialect(default.DefaultDialect): s = sql.select([tables.c.table_name], sql.and_( tables.c.table_schema == owner, - tables.c.table_type == u'VIEW' + tables.c.table_type == 'VIEW' ), order_by=[tables.c.table_name] ) @@ -1267,7 +1267,7 @@ class MSDialect(default.DefaultDialect): if row['index_id'] in indexes: indexes[row['index_id']]['column_names'].append(row['name']) - return indexes.values() + return list(indexes.values()) @reflection.cache @_db_plus_owner @@ -1474,4 +1474,4 @@ class MSDialect(default.DefaultDialect): local_cols.append(scol) remote_cols.append(rcol) - return fkeys.values() + return list(fkeys.values()) diff --git a/lib/sqlalchemy/dialects/mssql/information_schema.py b/lib/sqlalchemy/dialects/mssql/information_schema.py index 80e59d323..61403271f 100644 --- a/lib/sqlalchemy/dialects/mssql/information_schema.py +++ b/lib/sqlalchemy/dialects/mssql/information_schema.py @@ -17,10 +17,10 @@ class CoerceUnicode(TypeDecorator): impl = Unicode def process_bind_param(self, value, dialect): - # Py2K - if isinstance(value, str): - value = value.decode(dialect.encoding) - # end Py2K +# start Py2K +# if isinstance(value, str): +# value = value.decode(dialect.encoding) +# end Py2K return value def bind_expression(self, bindvalue): diff --git a/lib/sqlalchemy/dialects/mssql/pyodbc.py b/lib/sqlalchemy/dialects/mssql/pyodbc.py index beb6066f5..5a359d179 100644 --- a/lib/sqlalchemy/dialects/mssql/pyodbc.py +++ b/lib/sqlalchemy/dialects/mssql/pyodbc.py @@ -219,7 +219,7 @@ class MSExecutionContext_pyodbc(MSExecutionContext): # without closing it (FreeTDS particularly) row = self.cursor.fetchall()[0] break - except self.dialect.dbapi.Error, e: + except self.dialect.dbapi.Error as e: # no way around this - nextset() consumes the previous set # so we need to just keep flipping self.cursor.nextset() diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 38c86b116..c0497b14f 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -652,7 +652,7 @@ class BIT(sqltypes.TypeEngine): def process(value): if value is not None: - v = 0L + v = 0 for i in map(ord, value): v = v << 8 | i return v @@ -1171,7 +1171,7 @@ class SET(_StringType): super_convert = super(SET, self).bind_processor(dialect) def process(value): - if value is None or isinstance(value, (int, long, basestring)): + if value is None or isinstance(value, (int, str)): pass else: if None in value: @@ -1352,7 +1352,7 @@ class MySQLCompiler(compiler.SQLCompiler): of a SELECT. """ - if isinstance(select._distinct, basestring): + if isinstance(select._distinct, str): return select._distinct.upper() + " " elif select._distinct: return "DISTINCT " @@ -1441,7 +1441,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler): MySQLDDLCompiler, self).create_table_constraints(table) engine_key = '%s_engine' % self.dialect.name - is_innodb = table.kwargs.has_key(engine_key) and \ + is_innodb = engine_key in table.kwargs and \ table.kwargs[engine_key].lower() == 'innodb' auto_inc_column = table._autoincrement_column @@ -1494,7 +1494,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler): k[len(self.dialect.name) + 1:].upper(), v ) - for k, v in table.kwargs.items() + for k, v in list(table.kwargs.items()) if k.startswith('%s_' % self.dialect.name) ) @@ -2045,7 +2045,7 @@ class MySQLDialect(default.DefaultDialect): have = rs.fetchone() is not None rs.close() return have - except exc.DBAPIError, e: + except exc.DBAPIError as e: if self._extract_error_code(e.orig) == 1146: return False raise @@ -2328,7 +2328,7 @@ class MySQLDialect(default.DefaultDialect): rp = None try: rp = connection.execute(st) - except exc.DBAPIError, e: + except exc.DBAPIError as e: if self._extract_error_code(e.orig) == 1146: raise exc.NoSuchTableError(full_name) else: @@ -2352,7 +2352,7 @@ class MySQLDialect(default.DefaultDialect): try: try: rp = connection.execute(st) - except exc.DBAPIError, e: + except exc.DBAPIError as e: if self._extract_error_code(e.orig) == 1146: raise exc.NoSuchTableError(full_name) else: @@ -2485,7 +2485,7 @@ class MySQLTableDefinitionParser(object): for nope in ('auto_increment', 'data directory', 'index directory'): options.pop(nope, None) - for opt, val in options.items(): + for opt, val in list(options.items()): state.table_options['%s_%s' % (self.dialect.name, opt)] = val def _parse_column(self, line, state): @@ -2626,11 +2626,11 @@ class MySQLTableDefinitionParser(object): _final = self.preparer.final_quote - quotes = dict(zip(('iq', 'fq', 'esc_fq'), + quotes = dict(list(zip(('iq', 'fq', 'esc_fq'), [re.escape(s) for s in (self.preparer.initial_quote, _final, - self.preparer._escape_identifier(_final))])) + self.preparer._escape_identifier(_final))]))) self._pr_name = _pr_compile( r'^CREATE (?:\w+ +)?TABLE +' @@ -2802,11 +2802,12 @@ class _DecodingRowProxy(object): item = self.rowproxy[index] if isinstance(item, _array): item = item.tostring() - # Py2K - if self.charset and isinstance(item, str): - # end Py2K - # Py3K - #if self.charset and isinstance(item, bytes): +# start Py2K +# if self.charset and isinstance(item, str): +# end Py2K +# start Py3K + if self.charset and isinstance(item, bytes): +# end Py3K return item.decode(self.charset) else: return item @@ -2815,11 +2816,12 @@ class _DecodingRowProxy(object): item = getattr(self.rowproxy, attr) if isinstance(item, _array): item = item.tostring() - # Py2K - if self.charset and isinstance(item, str): - # end Py2K - # Py3K - #if self.charset and isinstance(item, bytes): +# start Py2K +# if self.charset and isinstance(item, str): +# end Py2K +# start Py3K + if self.charset and isinstance(item, bytes): +# end Py3K return item.decode(self.charset) else: return item diff --git a/lib/sqlalchemy/dialects/mysql/cymysql.py b/lib/sqlalchemy/dialects/mysql/cymysql.py index 0806f63b4..6fcbc2307 100644 --- a/lib/sqlalchemy/dialects/mysql/cymysql.py +++ b/lib/sqlalchemy/dialects/mysql/cymysql.py @@ -25,15 +25,16 @@ class _cymysqlBIT(BIT): def process(value): if value is not None: - # Py2K - v = 0L - for i in map(ord, value): +# start Py2K +# v = 0L +# for i in map(ord, value): +# v = v << 8 | i +# end Py2K +# start Py3K + v = 0 + for i in value: v = v << 8 | i - # end Py2K - # Py3K - #v = 0 - #for i in value: - # v = v << 8 | i +# end Py3K return v return value return process diff --git a/lib/sqlalchemy/dialects/mysql/oursql.py b/lib/sqlalchemy/dialects/mysql/oursql.py index db24adf03..b97afe933 100644 --- a/lib/sqlalchemy/dialects/mysql/oursql.py +++ b/lib/sqlalchemy/dialects/mysql/oursql.py @@ -55,9 +55,9 @@ class MySQLExecutionContext_oursql(MySQLExecutionContext): class MySQLDialect_oursql(MySQLDialect): driver = 'oursql' -# Py2K - supports_unicode_binds = True - supports_unicode_statements = True +# start Py2K +# supports_unicode_binds = True +# supports_unicode_statements = True # end Py2K supports_native_decimal = True @@ -90,12 +90,13 @@ class MySQLDialect_oursql(MySQLDialect): connection.cursor().execute('BEGIN', plain_query=True) def _xa_query(self, connection, query, xid): -# Py2K - arg = connection.connection._escape_string(xid) +# start Py2K +# arg = connection.connection._escape_string(xid) # end Py2K -# Py3K -# charset = self._connection_charset -# arg = connection.connection._escape_string(xid.encode(charset)).decode(charset) +# start Py3K + charset = self._connection_charset + arg = connection.connection._escape_string(xid.encode(charset)).decode(charset) +# end Py3K arg = "'%s'" % arg connection.execution_options(_oursql_plain_query=True).execute(query % arg) diff --git a/lib/sqlalchemy/dialects/mysql/zxjdbc.py b/lib/sqlalchemy/dialects/mysql/zxjdbc.py index ea01da21c..20f2e7359 100644 --- a/lib/sqlalchemy/dialects/mysql/zxjdbc.py +++ b/lib/sqlalchemy/dialects/mysql/zxjdbc.py @@ -37,7 +37,7 @@ class _ZxJDBCBit(BIT): return value if isinstance(value, bool): return int(value) - v = 0L + v = 0 for i in value: v = v << 8 | (i & 0xff) value = v diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index 831ba5f1b..a45793367 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -437,7 +437,7 @@ class OracleCompiler(compiler.SQLCompiler): def get_select_hint_text(self, byfroms): return " ".join( - "/*+ %s */" % text for table, text in byfroms.items() + "/*+ %s */" % text for table, text in list(byfroms.items()) ) def function_argspec(self, fn, **kw): @@ -654,14 +654,14 @@ class OracleDDLCompiler(compiler.DDLCompiler): class OracleIdentifierPreparer(compiler.IdentifierPreparer): reserved_words = set([x.lower() for x in RESERVED_WORDS]) - illegal_initial_characters = set(xrange(0, 10)).union(["_", "$"]) + illegal_initial_characters = set(range(0, 10)).union(["_", "$"]) def _bindparam_requires_quotes(self, value): """Return True if the given identifier requires quoting.""" lc_value = value.lower() return (lc_value in self.reserved_words or value[0] in self.illegal_initial_characters - or not self.legal_characters.match(unicode(value)) + or not self.legal_characters.match(str(value)) ) def format_savepoint(self, savepoint): @@ -765,10 +765,10 @@ class OracleDialect(default.DefaultDialect): def normalize_name(self, name): if name is None: return None - # Py2K - if isinstance(name, str): - name = name.decode(self.encoding) - # end Py2K +# start Py2K +# if isinstance(name, str): +# name = name.decode(self.encoding) +# end Py2K if name.upper() == name and \ not self.identifier_preparer._requires_quotes(name.lower()): return name.lower() @@ -780,16 +780,16 @@ class OracleDialect(default.DefaultDialect): return None elif name.lower() == name and not self.identifier_preparer._requires_quotes(name.lower()): name = name.upper() - # Py2K - if not self.supports_unicode_binds: - name = name.encode(self.encoding) - else: - name = unicode(name) - # end Py2K +# start Py2K +# if not self.supports_unicode_binds: +# name = name.encode(self.encoding) +# else: +# name = unicode(name) +# end Py2K return name def _get_default_schema_name(self, connection): - return self.normalize_name(connection.execute(u'SELECT USER FROM DUAL').scalar()) + return self.normalize_name(connection.execute('SELECT USER FROM DUAL').scalar()) def _resolve_synonym(self, connection, desired_owner=None, desired_synonym=None, desired_table=None): """search for a local synonym matching the given desired owner/name. @@ -1167,7 +1167,7 @@ class OracleDialect(default.DefaultDialect): local_cols.append(local_column) remote_cols.append(remote_column) - return fkeys.values() + return list(fkeys.values()) @reflection.cache def get_view_definition(self, connection, view_name, schema=None, diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index b8f7439f5..10ec20dee 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -182,7 +182,7 @@ a period "." as the decimal character. """ -from __future__ import absolute_import + from .base import OracleCompiler, OracleDialect, OracleExecutionContext from . import base as oracle @@ -268,20 +268,21 @@ class _LOBMixin(object): class _NativeUnicodeMixin(object): - # Py3K - #pass - # Py2K - def bind_processor(self, dialect): - if dialect._cx_oracle_with_unicode: - def process(value): - if value is None: - return value - else: - return unicode(value) - return process - else: - return super(_NativeUnicodeMixin, self).bind_processor(dialect) - # end Py2K +# start Py3K + pass +# end Py3K +# start Py2K +# def bind_processor(self, dialect): +# if dialect._cx_oracle_with_unicode: +# def process(value): +# if value is None: +# return value +# else: +# return unicode(value) +# return process +# else: +# return super(_NativeUnicodeMixin, self).bind_processor(dialect) +# end Py2K # we apply a connection output handler that returns # unicode in all cases, so the "native_unicode" flag @@ -391,10 +392,10 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): (fromname.encode(self.dialect.encoding), toname.encode(self.dialect.encoding)) for fromname, toname in - quoted_bind_names.items() + list(quoted_bind_names.items()) ) for param in self.parameters: - for fromname, toname in quoted_bind_names.items(): + for fromname, toname in list(quoted_bind_names.items()): param[toname] = param[fromname] del param[fromname] @@ -408,7 +409,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): # if a single execute, check for outparams if len(self.compiled_parameters) == 1: - for bindparam in self.compiled.binds.values(): + for bindparam in list(self.compiled.binds.values()): if bindparam.isoutparam: dbtype = bindparam.type.dialect_impl(self.dialect).\ get_dbapi_type(self.dialect.dbapi) @@ -437,7 +438,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): if hasattr(self, 'out_parameters') and self.compiled.returning: returning_params = dict( (k, v.getvalue()) - for k, v in self.out_parameters.items() + for k, v in list(self.out_parameters.items()) ) return ReturningResultProxy(self, returning_params) @@ -456,7 +457,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): len(self.compiled_parameters) == 1: result.out_parameters = out_parameters = {} - for bind, name in self.compiled.bind_names.items(): + for bind, name in list(self.compiled.bind_names.items()): if name in self.out_parameters: type = bind.type impl_type = type.dialect_impl(self.dialect) @@ -472,7 +473,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): else: result.out_parameters = dict( (k, v.getvalue()) - for k, v in self.out_parameters.items() + for k, v in list(self.out_parameters.items()) ) return result @@ -493,11 +494,11 @@ class OracleExecutionContext_cx_oracle_with_unicode(OracleExecutionContext_cx_or """ def __init__(self, *arg, **kw): OracleExecutionContext_cx_oracle.__init__(self, *arg, **kw) - self.statement = unicode(self.statement) + self.statement = str(self.statement) def _execute_scalar(self, stmt): return super(OracleExecutionContext_cx_oracle_with_unicode, self).\ - _execute_scalar(unicode(stmt)) + _execute_scalar(str(stmt)) class ReturningResultProxy(_result.FullyBufferedResultProxy): @@ -607,19 +608,19 @@ class OracleDialect_cx_oracle(OracleDialect): self.supports_unicode_statements = True self.supports_unicode_binds = True self._cx_oracle_with_unicode = True - # Py2K - # There's really no reason to run with WITH_UNICODE under Python 2.x. - # Give the user a hint. - util.warn("cx_Oracle is compiled under Python 2.xx using the " - "WITH_UNICODE flag. Consider recompiling cx_Oracle without " - "this flag, which is in no way necessary for full support of Unicode. " - "Otherwise, all string-holding bind parameters must " - "be explicitly typed using SQLAlchemy's String type or one of its subtypes," - "or otherwise be passed as Python unicode. Plain Python strings " - "passed as bind parameters will be silently corrupted by cx_Oracle." - ) - self.execution_ctx_cls = OracleExecutionContext_cx_oracle_with_unicode - # end Py2K +# start Py2K +# # There's really no reason to run with WITH_UNICODE under Python 2.x. +# # Give the user a hint. +# util.warn("cx_Oracle is compiled under Python 2.xx using the " +# "WITH_UNICODE flag. Consider recompiling cx_Oracle without " +# "this flag, which is in no way necessary for full support of Unicode. " +# "Otherwise, all string-holding bind parameters must " +# "be explicitly typed using SQLAlchemy's String type or one of its subtypes," +# "or otherwise be passed as Python unicode. Plain Python strings " +# "passed as bind parameters will be silently corrupted by cx_Oracle." +# ) +# self.execution_ctx_cls = OracleExecutionContext_cx_oracle_with_unicode +# end Py2K else: self._cx_oracle_with_unicode = False @@ -731,7 +732,7 @@ class OracleDialect_cx_oracle(OracleDialect): arraysize=cursor.arraysize) # allow all strings to come back natively as Unicode elif defaultType in (cx_Oracle.STRING, cx_Oracle.FIXED_CHAR): - return cursor.var(unicode, size, cursor.arraysize) + return cursor.var(str, size, cursor.arraysize) def on_connect(conn): conn.outputtypehandler = output_type_handler @@ -766,20 +767,20 @@ class OracleDialect_cx_oracle(OracleDialect): twophase=self.allow_twophase, ) - # Py2K - if self._cx_oracle_with_unicode: - for k, v in opts.items(): - if isinstance(v, str): - opts[k] = unicode(v) - else: - for k, v in opts.items(): - if isinstance(v, unicode): - opts[k] = str(v) - # end Py2K +# start Py2K +# if self._cx_oracle_with_unicode: +# for k, v in opts.items(): +# if isinstance(v, str): +# opts[k] = unicode(v) +# else: +# for k, v in opts.items(): +# if isinstance(v, unicode): +# opts[k] = str(v) +# end Py2K if 'mode' in url.query: opts['mode'] = url.query['mode'] - if isinstance(opts['mode'], basestring): + if isinstance(opts['mode'], str): mode = opts['mode'].upper() if mode == 'SYSDBA': opts['mode'] = self.dbapi.SYSDBA diff --git a/lib/sqlalchemy/dialects/oracle/zxjdbc.py b/lib/sqlalchemy/dialects/oracle/zxjdbc.py index d74f21aca..ad53b89a1 100644 --- a/lib/sqlalchemy/dialects/oracle/zxjdbc.py +++ b/lib/sqlalchemy/dialects/oracle/zxjdbc.py @@ -95,8 +95,8 @@ class OracleExecutionContext_zxjdbc(OracleExecutionContext): try: try: rrs = self.statement.__statement__.getReturnResultSet() - rrs.next() - except SQLException, sqle: + next(rrs) + except SQLException as sqle: msg = '%s [SQLCode: %d]' % (sqle.getMessage(), sqle.getErrorCode()) if sqle.getSQLState() is not None: msg += ' [SQLState: %s]' % sqle.getSQLState() diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 1acdb57b9..992995434 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -1419,7 +1419,7 @@ class PGDialect(default.DefaultDialect): query, bindparams=[ sql.bindparam( - 'schema', unicode(schema.lower()), + 'schema', str(schema.lower()), type_=sqltypes.Unicode)] ) ) @@ -1435,7 +1435,7 @@ class PGDialect(default.DefaultDialect): "n.oid=c.relnamespace where n.nspname=current_schema() and " "relname=:name", bindparams=[ - sql.bindparam('name', unicode(table_name), + sql.bindparam('name', str(table_name), type_=sqltypes.Unicode)] ) ) @@ -1447,9 +1447,9 @@ class PGDialect(default.DefaultDialect): "relname=:name", bindparams=[ sql.bindparam('name', - unicode(table_name), type_=sqltypes.Unicode), + str(table_name), type_=sqltypes.Unicode), sql.bindparam('schema', - unicode(schema), type_=sqltypes.Unicode)] + str(schema), type_=sqltypes.Unicode)] ) ) return bool(cursor.first()) @@ -1463,7 +1463,7 @@ class PGDialect(default.DefaultDialect): "n.nspname=current_schema() " "and relname=:name", bindparams=[ - sql.bindparam('name', unicode(sequence_name), + sql.bindparam('name', str(sequence_name), type_=sqltypes.Unicode) ] ) @@ -1475,10 +1475,10 @@ class PGDialect(default.DefaultDialect): "n.oid=c.relnamespace where relkind='S' and " "n.nspname=:schema and relname=:name", bindparams=[ - sql.bindparam('name', unicode(sequence_name), + sql.bindparam('name', str(sequence_name), type_=sqltypes.Unicode), sql.bindparam('schema', - unicode(schema), type_=sqltypes.Unicode) + str(schema), type_=sqltypes.Unicode) ] ) ) @@ -1488,9 +1488,9 @@ class PGDialect(default.DefaultDialect): def has_type(self, connection, type_name, schema=None): bindparams = [ sql.bindparam('typname', - unicode(type_name), type_=sqltypes.Unicode), + str(type_name), type_=sqltypes.Unicode), sql.bindparam('nspname', - unicode(schema), type_=sqltypes.Unicode), + str(schema), type_=sqltypes.Unicode), ] if schema is not None: query = """ @@ -1546,9 +1546,9 @@ class PGDialect(default.DefaultDialect): """ % schema_where_clause # Since we're binding to unicode, table_name and schema_name must be # unicode. - table_name = unicode(table_name) + table_name = str(table_name) if schema is not None: - schema = unicode(schema) + schema = str(schema) s = sql.text(query, bindparams=[ sql.bindparam('table_name', type_=sqltypes.Unicode), sql.bindparam('schema', type_=sqltypes.Unicode) @@ -1570,13 +1570,14 @@ class PGDialect(default.DefaultDialect): """ rp = connection.execute(s) # what about system tables? - # Py3K - #schema_names = [row[0] for row in rp \ - # if not row[0].startswith('pg_')] - # Py2K - schema_names = [row[0].decode(self.encoding) for row in rp \ +# start Py3K + schema_names = [row[0] for row in rp \ if not row[0].startswith('pg_')] - # end Py2K +# end Py3K +# start Py2K +# schema_names = [row[0].decode(self.encoding) for row in rp \ +# if not row[0].startswith('pg_')] +# end Py2K return schema_names @reflection.cache @@ -1587,7 +1588,7 @@ class PGDialect(default.DefaultDialect): current_schema = self.default_schema_name result = connection.execute( - sql.text(u"SELECT relname FROM pg_class c " + sql.text("SELECT relname FROM pg_class c " "WHERE relkind = 'r' " "AND '%s' = (select nspname from pg_namespace n " "where n.oid = c.relnamespace) " % @@ -1610,12 +1611,13 @@ class PGDialect(default.DefaultDialect): AND '%(schema)s' = (select nspname from pg_namespace n where n.oid = c.relnamespace) """ % dict(schema=current_schema) - # Py3K - #view_names = [row[0] for row in connection.execute(s)] - # Py2K - view_names = [row[0].decode(self.encoding) - for row in connection.execute(s)] - # end Py2K +# start Py3K + view_names = [row[0] for row in connection.execute(s)] +# end Py3K +# start Py2K +# view_names = [row[0].decode(self.encoding) +# for row in connection.execute(s)] +# end Py2K return view_names @reflection.cache @@ -1632,11 +1634,12 @@ class PGDialect(default.DefaultDialect): rp = connection.execute(sql.text(s), view_name=view_name, schema=current_schema) if rp: - # Py3K - #view_def = rp.scalar() - # Py2K - view_def = rp.scalar().decode(self.encoding) - # end Py2K +# start Py3K + view_def = rp.scalar() +# end Py3K +# start Py2K +# view_def = rp.scalar().decode(self.encoding) +# end Py2K return view_def @reflection.cache diff --git a/lib/sqlalchemy/dialects/postgresql/hstore.py b/lib/sqlalchemy/dialects/postgresql/hstore.py index e555a1afd..d7fd34d05 100644 --- a/lib/sqlalchemy/dialects/postgresql/hstore.py +++ b/lib/sqlalchemy/dialects/postgresql/hstore.py @@ -96,14 +96,14 @@ def _serialize_hstore(val): def esc(s, position): if position == 'value' and s is None: return 'NULL' - elif isinstance(s, basestring): + elif isinstance(s, str): return '"%s"' % s.replace('"', r'\"') else: raise ValueError("%r in %s position is not a string." % (s, position)) return ', '.join('%s=>%s' % (esc(k, 'key'), esc(v, 'value')) - for k, v in val.iteritems()) + for k, v in val.items()) class HSTORE(sqltypes.Concatenable, sqltypes.TypeEngine): diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index 805fc72af..2893a3872 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -142,7 +142,7 @@ type. This replaces SQLAlchemy's pure-Python HSTORE coercion which takes effect for other DBAPIs. """ -from __future__ import absolute_import + import re import logging @@ -190,22 +190,22 @@ class _PGNumeric(sqltypes.Numeric): class _PGEnum(ENUM): def __init__(self, *arg, **kw): super(_PGEnum, self).__init__(*arg, **kw) - # Py2K - if self.convert_unicode: - self.convert_unicode = "force" - # end Py2K +# start Py2K +# if self.convert_unicode: +# self.convert_unicode = "force" +# end Py2K class _PGArray(ARRAY): def __init__(self, *arg, **kw): super(_PGArray, self).__init__(*arg, **kw) - # Py2K - # FIXME: this check won't work for setups that - # have convert_unicode only on their create_engine(). - if isinstance(self.item_type, sqltypes.String) and \ - self.item_type.convert_unicode: - self.item_type.convert_unicode = "force" - # end Py2K +# start Py2K +# # FIXME: this check won't work for setups that +# # have convert_unicode only on their create_engine(). +# if isinstance(self.item_type, sqltypes.String) and \ +# self.item_type.convert_unicode: +# self.item_type.convert_unicode = "force" +# end Py2K class _PGHStore(HSTORE): @@ -294,9 +294,9 @@ class PGIdentifierPreparer_psycopg2(PGIdentifierPreparer): class PGDialect_psycopg2(PGDialect): driver = 'psycopg2' - # Py2K - supports_unicode_statements = False - # end Py2K +# start Py2K +# supports_unicode_statements = False +# end Py2K default_paramstyle = 'pyformat' supports_sane_multi_rowcount = False execution_ctx_cls = PGExecutionContext_psycopg2 diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index f21a81d0c..d742a71b5 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -508,7 +508,7 @@ class SQLiteDDLCompiler(compiler.DDLCompiler): def visit_foreign_key_constraint(self, constraint): - local_table = constraint._elements.values()[0].parent.table + local_table = list(constraint._elements.values())[0].parent.table remote_table = list(constraint._elements.values())[0].column.table if local_table.schema != remote_table.schema: @@ -812,7 +812,7 @@ class SQLiteDialect(default.DefaultDialect): coltype = sqltypes.NullType() if default is not None: - default = unicode(default) + default = str(default) return { 'name': name, diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py index d827607ba..4a86d38d2 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py @@ -267,8 +267,9 @@ class SQLiteDialect_pysqlite(SQLiteDialect): } ) - # Py3K - #description_encoding = None +# start Py3K + description_encoding = None +# end Py3K driver = 'pysqlite' @@ -288,7 +289,7 @@ class SQLiteDialect_pysqlite(SQLiteDialect): def dbapi(cls): try: from pysqlite2 import dbapi2 as sqlite - except ImportError, e: + except ImportError as e: try: from sqlite3 import dbapi2 as sqlite # try 2.5+ stdlib name. except ImportError: diff --git a/lib/sqlalchemy/dialects/sybase/__init__.py b/lib/sqlalchemy/dialects/sybase/__init__.py index 7d504e54e..f61352ceb 100644 --- a/lib/sqlalchemy/dialects/sybase/__init__.py +++ b/lib/sqlalchemy/dialects/sybase/__init__.py @@ -9,7 +9,7 @@ from sqlalchemy.dialects.sybase import base, pysybase, pyodbc # default dialect base.dialect = pyodbc.dialect -from base import CHAR, VARCHAR, TIME, NCHAR, NVARCHAR,\ +from .base import CHAR, VARCHAR, TIME, NCHAR, NVARCHAR,\ TEXT, DATE, DATETIME, FLOAT, NUMERIC,\ BIGINT, INT, INTEGER, SMALLINT, BINARY,\ VARBINARY, UNITEXT, UNICHAR, UNIVARCHAR,\ diff --git a/lib/sqlalchemy/dialects/sybase/base.py b/lib/sqlalchemy/dialects/sybase/base.py index a9e5c5fda..6770ed8e7 100644 --- a/lib/sqlalchemy/dialects/sybase/base.py +++ b/lib/sqlalchemy/dialects/sybase/base.py @@ -475,12 +475,12 @@ class SybaseDialect(default.DefaultDialect): AND o.type in ('U', 'V') """) - # Py2K - if isinstance(schema, unicode): - schema = schema.encode("ascii") - if isinstance(table_name, unicode): - table_name = table_name.encode("ascii") - # end Py2K +# start Py2K +# if isinstance(schema, unicode): +# schema = schema.encode("ascii") +# if isinstance(table_name, unicode): +# table_name = table_name.encode("ascii") +# end Py2K result = connection.execute(TABLEID_SQL, schema_name=schema, table_name=table_name) @@ -759,10 +759,10 @@ class SybaseDialect(default.DefaultDialect): AND o.type = 'U' """) - # Py2K - if isinstance(schema, unicode): - schema = schema.encode("ascii") - # end Py2K +# start Py2K +# if isinstance(schema, unicode): +# schema = schema.encode("ascii") +# end Py2K tables = connection.execute(TABLE_SQL, schema_name=schema) return [t["name"] for t in tables] @@ -779,10 +779,10 @@ class SybaseDialect(default.DefaultDialect): AND o.type = 'V' """) - # Py2K - if isinstance(view_name, unicode): - view_name = view_name.encode("ascii") - # end Py2K +# start Py2K +# if isinstance(view_name, unicode): +# view_name = view_name.encode("ascii") +# end Py2K view = connection.execute(VIEW_DEF_SQL, view_name=view_name) return view.scalar() @@ -799,10 +799,10 @@ class SybaseDialect(default.DefaultDialect): AND o.type = 'V' """) - # Py2K - if isinstance(schema, unicode): - schema = schema.encode("ascii") - # end Py2K +# start Py2K +# if isinstance(schema, unicode): +# schema = schema.encode("ascii") +# end Py2K views = connection.execute(VIEW_SQL, schema_name=schema) return [v["name"] for v in views] diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index b4c9b1e1c..9eb3d6128 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -9,7 +9,7 @@ """ -from __future__ import with_statement + import sys from .. import exc, schema, util, log, interfaces from ..sql import expression, util as sql_util @@ -460,7 +460,7 @@ class Connection(Connectable): try: self.engine.dialect.do_begin(self.connection) - except Exception, e: + except Exception as e: self._handle_dbapi_exception(e, None, None, None, None) def _rollback_impl(self): @@ -473,7 +473,7 @@ class Connection(Connectable): try: self.engine.dialect.do_rollback(self.connection) self.__transaction = None - except Exception, e: + except Exception as e: self._handle_dbapi_exception(e, None, None, None, None) else: self.__transaction = None @@ -487,7 +487,7 @@ class Connection(Connectable): try: self.engine.dialect.do_commit(self.connection) self.__transaction = None - except Exception, e: + except Exception as e: self._handle_dbapi_exception(e, None, None, None, None) def _savepoint_impl(self, name=None): @@ -688,7 +688,7 @@ class Connection(Connectable): dialect = self.dialect ctx = dialect.execution_ctx_cls._init_default( dialect, self, conn) - except Exception, e: + except Exception as e: self._handle_dbapi_exception(e, None, None, None, None) ret = ctx._exec_default(default, None) @@ -734,7 +734,7 @@ class Connection(Connectable): distilled_params = _distill_params(multiparams, params) if distilled_params: - keys = distilled_params[0].keys() + keys = list(distilled_params[0].keys()) else: keys = [] @@ -822,7 +822,7 @@ class Connection(Connectable): conn = self._revalidate_connection() context = constructor(dialect, self, conn, *args) - except Exception, e: + except Exception as e: self._handle_dbapi_exception(e, str(statement), parameters, None, None) @@ -865,7 +865,7 @@ class Connection(Connectable): statement, parameters, context) - except Exception, e: + except Exception as e: self._handle_dbapi_exception( e, statement, @@ -939,7 +939,7 @@ class Connection(Connectable): cursor, statement, parameters) - except Exception, e: + except Exception as e: self._handle_dbapi_exception( e, statement, @@ -954,7 +954,7 @@ class Connection(Connectable): """ try: cursor.close() - except Exception, e: + except Exception as e: try: ex_text = str(e) except TypeError: @@ -1045,7 +1045,7 @@ class Connection(Connectable): Compiled: _execute_compiled, schema.SchemaItem: _execute_default, schema.DDLElement: _execute_ddl, - basestring: _execute_text + str: _execute_text } def default_schema_name(self): diff --git a/lib/sqlalchemy/engine/ddl.py b/lib/sqlalchemy/engine/ddl.py index c61a9d59c..56f475e30 100644 --- a/lib/sqlalchemy/engine/ddl.py +++ b/lib/sqlalchemy/engine/ddl.py @@ -52,10 +52,10 @@ class SchemaGenerator(DDLBase): if self.tables is not None: tables = self.tables else: - tables = metadata.tables.values() + tables = list(metadata.tables.values()) collection = [t for t in sql_util.sort_tables(tables) if self._can_create_table(t)] - seq_coll = [s for s in metadata._sequences.values() + seq_coll = [s for s in list(metadata._sequences.values()) if s.column is None and self._can_create_sequence(s)] metadata.dispatch.before_create(metadata, self.connection, @@ -120,7 +120,7 @@ class SchemaDropper(DDLBase): if self.tables is not None: tables = self.tables else: - tables = metadata.tables.values() + tables = list(metadata.tables.values()) collection = [ t @@ -130,7 +130,7 @@ class SchemaDropper(DDLBase): seq_coll = [ s - for s in metadata._sequences.values() + for s in list(metadata._sequences.values()) if s.column is None and self._can_drop_sequence(s) ] diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index daa9fe085..9dda6d81e 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -57,17 +57,18 @@ class DefaultDialect(interfaces.Dialect): # *not* the FLOAT type however. supports_native_decimal = False - # Py3K - #supports_unicode_statements = True - #supports_unicode_binds = True - #returns_unicode_strings = True - #description_encoding = None - # Py2K - supports_unicode_statements = False - supports_unicode_binds = False - returns_unicode_strings = False - description_encoding = 'use_encoding' - # end Py2K +# start Py3K + supports_unicode_statements = True + supports_unicode_binds = True + returns_unicode_strings = True + description_encoding = None +# end Py3K +# start Py2K +# supports_unicode_statements = False +# supports_unicode_binds = False +# returns_unicode_strings = False +# description_encoding = 'use_encoding' +# end Py2K name = 'default' @@ -201,14 +202,15 @@ class DefaultDialect(interfaces.Dialect): return None def _check_unicode_returns(self, connection): - # Py2K - if self.supports_unicode_statements: - cast_to = unicode - else: - cast_to = str - # end Py2K - # Py3K - #cast_to = str +# start Py2K +# if self.supports_unicode_statements: +# cast_to = unicode +# else: +# cast_to = str +# end Py2K +# start Py3K + cast_to = str +# end Py3K def check_unicode(formatstr, type_): cursor = connection.connection.cursor() @@ -226,8 +228,8 @@ class DefaultDialect(interfaces.Dialect): ) row = cursor.fetchone() - return isinstance(row[0], unicode) - except self.dbapi.Error, de: + return isinstance(row[0], str) + except self.dbapi.Error as de: util.warn("Exception attempting to " "detect unicode returns: %r" % de) return False @@ -373,10 +375,10 @@ class DefaultExecutionContext(interfaces.ExecutionContext): self.execution_options.update(connection._execution_options) if not dialect.supports_unicode_statements: - self.unicode_statement = unicode(compiled) + self.unicode_statement = str(compiled) self.statement = dialect._encoder(self.unicode_statement)[0] else: - self.statement = self.unicode_statement = unicode(compiled) + self.statement = self.unicode_statement = str(compiled) self.cursor = self.create_cursor() self.compiled_parameters = [] @@ -414,7 +416,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): self.result_map = compiled.result_map - self.unicode_statement = unicode(compiled) + self.unicode_statement = str(compiled) if not dialect.supports_unicode_statements: self.statement = self.unicode_statement.encode( self.dialect.encoding) @@ -519,7 +521,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): self.executemany = len(parameters) > 1 if not dialect.supports_unicode_statements and \ - isinstance(statement, unicode): + isinstance(statement, str): self.unicode_statement = statement self.statement = dialect._encoder(statement)[0] else: @@ -573,7 +575,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): """ conn = self.root_connection - if isinstance(stmt, unicode) and \ + if isinstance(stmt, str) and \ not self.dialect.supports_unicode_statements: stmt = self.dialect._encoder(stmt)[0] @@ -734,12 +736,12 @@ class DefaultExecutionContext(interfaces.ExecutionContext): inputsizes.append(dbtype) try: self.cursor.setinputsizes(*inputsizes) - except Exception, e: + except Exception as e: self.root_connection._handle_dbapi_exception( e, None, None, None, self) else: inputsizes = {} - for key in self.compiled.bind_names.values(): + for key in list(self.compiled.bind_names.values()): typeengine = types[key] dbtype = typeengine.dialect_impl(self.dialect).\ get_dbapi_type(self.dialect.dbapi) @@ -752,7 +754,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): inputsizes[key] = dbtype try: self.cursor.setinputsizes(**inputsizes) - except Exception, e: + except Exception as e: self.root_connection._handle_dbapi_exception( e, None, None, None, self) diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index 90f21db09..cf4a1d532 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -41,8 +41,8 @@ def cache(fn, self, con, *args, **kw): return fn(self, con, *args, **kw) key = ( fn.__name__, - tuple(a for a in args if isinstance(a, basestring)), - tuple((k, v) for k, v in kw.iteritems() if isinstance(v, (basestring, int, float))) + tuple(a for a in args if isinstance(a, str)), + tuple((k, v) for k, v in kw.items() if isinstance(v, (str, int, float))) ) ret = info_cache.get(key) if ret is None: @@ -381,16 +381,16 @@ class Inspector(object): # table.kwargs will need to be passed to each reflection method. Make # sure keywords are strings. tblkw = table.kwargs.copy() - for (k, v) in tblkw.items(): + for (k, v) in list(tblkw.items()): del tblkw[k] tblkw[str(k)] = v - # Py2K - if isinstance(schema, str): - schema = schema.decode(dialect.encoding) - if isinstance(table_name, str): - table_name = table_name.decode(dialect.encoding) - # end Py2K +# start Py2K +# if isinstance(schema, str): +# schema = schema.decode(dialect.encoding) +# if isinstance(table_name, str): +# table_name = table_name.decode(dialect.encoding) +# end Py2K # columns found_table = False diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py index 88930081e..0bd501423 100644 --- a/lib/sqlalchemy/engine/result.py +++ b/lib/sqlalchemy/engine/result.py @@ -8,7 +8,7 @@ and :class:`.RowProxy.""" -from itertools import izip + from .. import exc, types, util from ..sql import expression import collections @@ -55,7 +55,7 @@ except ImportError: return list(self) def __iter__(self): - for processor, value in izip(self._processors, self._row): + for processor, value in zip(self._processors, self._row): if processor is None: yield value else: @@ -72,7 +72,7 @@ except ImportError: except TypeError: if isinstance(key, slice): l = [] - for processor, value in izip(self._processors[key], + for processor, value in zip(self._processors[key], self._row[key]): if processor is None: l.append(value) @@ -93,7 +93,7 @@ except ImportError: def __getattr__(self, name): try: return self[name] - except KeyError, e: + except KeyError as e: raise AttributeError(e.args[0]) @@ -142,7 +142,7 @@ class RowProxy(BaseRowProxy): def items(self): """Return a list of tuples, each tuple containing a key/value pair.""" # TODO: no coverage here - return [(key, self[key]) for key in self.iterkeys()] + return [(key, self[key]) for key in self.keys()] def keys(self): """Return the list of keys as strings represented by this RowProxy.""" @@ -274,7 +274,7 @@ class ResultMetaData(object): def _key_fallback(self, key, raiseerr=True): map = self._keymap result = None - if isinstance(key, basestring): + if isinstance(key, str): result = map.get(key if self.case_sensitive else key.lower()) # fallback for targeting a ColumnElement to a textual expression # this is a rare use case which only occurs when matching text() @@ -328,8 +328,8 @@ class ResultMetaData(object): return { '_pickled_keymap': dict( (key, index) - for key, (processor, obj, index) in self._keymap.iteritems() - if isinstance(key, (basestring, int)) + for key, (processor, obj, index) in self._keymap.items() + if isinstance(key, (str, int)) ), 'keys': self.keys, "case_sensitive": self.case_sensitive, @@ -338,9 +338,9 @@ class ResultMetaData(object): def __setstate__(self, state): # the row has been processed at pickling time so we don't need any # processor anymore - self._processors = [None for _ in xrange(len(state['keys']))] + self._processors = [None for _ in range(len(state['keys']))] self._keymap = keymap = {} - for key, index in state['_pickled_keymap'].iteritems(): + for key, index in state['_pickled_keymap'].items(): # not preserving "obj" here, unfortunately our # proxy comparison fails with the unpickle keymap[key] = (None, None, index) @@ -440,7 +440,7 @@ class ResultProxy(object): """ try: return self.context.rowcount - except Exception, e: + except Exception as e: self.connection._handle_dbapi_exception( e, None, None, self.cursor, self.context) @@ -462,7 +462,7 @@ class ResultProxy(object): """ try: return self._saved_cursor.lastrowid - except Exception, e: + except Exception as e: self.connection._handle_dbapi_exception( e, None, None, self._saved_cursor, self.context) @@ -746,7 +746,7 @@ class ResultProxy(object): l = self.process_rows(self._fetchall_impl()) self.close() return l - except Exception, e: + except Exception as e: self.connection._handle_dbapi_exception( e, None, None, self.cursor, self.context) @@ -765,7 +765,7 @@ class ResultProxy(object): if len(l) == 0: self.close() return l - except Exception, e: + except Exception as e: self.connection._handle_dbapi_exception( e, None, None, self.cursor, self.context) @@ -784,7 +784,7 @@ class ResultProxy(object): else: self.close() return None - except Exception, e: + except Exception as e: self.connection._handle_dbapi_exception( e, None, None, self.cursor, self.context) @@ -800,7 +800,7 @@ class ResultProxy(object): try: row = self._fetchone_impl() - except Exception, e: + except Exception as e: self.connection._handle_dbapi_exception( e, None, None, self.cursor, self.context) @@ -966,9 +966,9 @@ class BufferedColumnResultProxy(ResultProxy): # constructed. metadata._orig_processors = metadata._processors # replace the all type processors by None processors. - metadata._processors = [None for _ in xrange(len(metadata.keys))] + metadata._processors = [None for _ in range(len(metadata.keys))] keymap = {} - for k, (func, obj, index) in metadata._keymap.iteritems(): + for k, (func, obj, index) in metadata._keymap.items(): keymap[k] = (None, obj, index) self._metadata._keymap = keymap @@ -989,7 +989,7 @@ class BufferedColumnResultProxy(ResultProxy): if size is None: return self.fetchall() l = [] - for i in xrange(size): + for i in range(size): row = self.fetchone() if row is None: break diff --git a/lib/sqlalchemy/engine/strategies.py b/lib/sqlalchemy/engine/strategies.py index 4c81df8f0..bed14c671 100644 --- a/lib/sqlalchemy/engine/strategies.py +++ b/lib/sqlalchemy/engine/strategies.py @@ -78,20 +78,21 @@ class DefaultEngineStrategy(EngineStrategy): def connect(): try: return dialect.connect(*cargs, **cparams) - except Exception, e: + except Exception as e: invalidated = dialect.is_disconnect(e, None, None) - # Py3K - #raise exc.DBAPIError.instance(None, None, - # e, dialect.dbapi.Error, - # connection_invalidated=invalidated - #) from e - # Py2K - import sys - raise exc.DBAPIError.instance( - None, None, e, dialect.dbapi.Error, +# start Py3K + raise exc.DBAPIError.instance(None, None, + e, dialect.dbapi.Error, connection_invalidated=invalidated - ), None, sys.exc_info()[2] - # end Py2K + ) from e +# end Py3K +# start Py2K +# import sys +# raise exc.DBAPIError.instance( +# None, None, e, dialect.dbapi.Error, +# connection_invalidated=invalidated +# ), None, sys.exc_info()[2] +# end Py2K creator = kwargs.pop('creator', connect) diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index c4931b48c..45768c5dc 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -14,7 +14,7 @@ be used directly and is also accepted directly by ``create_engine()``. """ import re -import urllib +import urllib.request, urllib.parse, urllib.error from .. import exc, util from . import Dialect @@ -67,7 +67,7 @@ class URL(object): if self.username is not None: s += self.username if self.password is not None: - s += ':' + urllib.quote_plus(self.password) + s += ':' + urllib.parse.quote_plus(self.password) s += "@" if self.host is not None: s += self.host @@ -76,7 +76,7 @@ class URL(object): if self.database is not None: s += '/' + self.database if self.query: - keys = self.query.keys() + keys = list(self.query.keys()) keys.sort() s += '?' + "&".join("%s=%s" % (k, self.query[k]) for k in keys) return s @@ -150,7 +150,7 @@ def make_url(name_or_url): existing URL object is passed, just returns the object. """ - if isinstance(name_or_url, basestring): + if isinstance(name_or_url, str): return _parse_rfc1738_args(name_or_url) else: return name_or_url @@ -177,17 +177,17 @@ def _parse_rfc1738_args(name): tokens = components['database'].split('?', 2) components['database'] = tokens[0] query = (len(tokens) > 1 and dict(util.parse_qsl(tokens[1]))) or None - # Py2K - if query is not None: - query = dict((k.encode('ascii'), query[k]) for k in query) - # end Py2K +# start Py2K +# if query is not None: +# query = dict((k.encode('ascii'), query[k]) for k in query) +# end Py2K else: query = None components['query'] = query if components['password'] is not None: components['password'] = \ - urllib.unquote_plus(components['password']) + urllib.parse.unquote_plus(components['password']) name = components.pop('name') return URL(name, **components) diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index f28f19ee9..de054b0fd 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -201,11 +201,9 @@ def _remove_dispatcher(cls): del _registrars[k] -class Events(object): +class Events(object, metaclass=_EventMeta): """Define event listening functions for a particular target type.""" - __metaclass__ = _EventMeta - @classmethod def _accept_with(cls, target): # Mapper, ClassManager, Session override this to @@ -302,7 +300,7 @@ class _DispatchDescriptor(object): def clear(self): """Clear all class level listeners""" - for dispatcher in self._clslevel.values(): + for dispatcher in list(self._clslevel.values()): dispatcher[:] = [] def for_modify(self, obj): @@ -377,7 +375,7 @@ class _EmptyListener(object): def __iter__(self): return iter(self.parent_listeners) - def __nonzero__(self): + def __bool__(self): return bool(self.parent_listeners) @@ -414,7 +412,7 @@ class _CompoundListener(object): def __iter__(self): return chain(self.parent_listeners, self.listeners) - def __nonzero__(self): + def __bool__(self): return bool(self.listeners or self.parent_listeners) diff --git a/lib/sqlalchemy/exc.py b/lib/sqlalchemy/exc.py index 0ce5393be..f5dc1119d 100644 --- a/lib/sqlalchemy/exc.py +++ b/lib/sqlalchemy/exc.py @@ -285,7 +285,7 @@ class DBAPIError(StatementError): text = str(orig) except (KeyboardInterrupt, SystemExit): raise - except Exception, e: + except Exception as e: text = 'Error in str() of DB-API-generated exception: ' + str(e) StatementError.__init__( self, diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index 252efcb42..ad09db831 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -475,7 +475,7 @@ class _AssociationCollection(object): def __len__(self): return len(self.col) - def __nonzero__(self): + def __bool__(self): return bool(self.col) def __getstate__(self): @@ -514,7 +514,7 @@ class _AssociationList(_AssociationCollection): stop = index.stop step = index.step or 1 - rng = range(index.start or 0, stop, step) + rng = list(range(index.start or 0, stop, step)) if step == 1: for i in rng: del self[index.start] @@ -569,7 +569,7 @@ class _AssociationList(_AssociationCollection): def count(self, value): return sum([1 for _ in - itertools.ifilter(lambda v: v == value, iter(self))]) + filter(lambda v: v == value, iter(self))]) def extend(self, values): for v in values: @@ -668,8 +668,8 @@ class _AssociationList(_AssociationCollection): def __hash__(self): raise TypeError("%s objects are unhashable" % type(self).__name__) - for func_name, func in locals().items(): - if (util.callable(func) and func.func_name == func_name and + for func_name, func in list(locals().items()): + if (util.callable(func) and func.__name__ == func_name and not func.__doc__ and hasattr(list, func_name)): func.__doc__ = getattr(list, func_name).__doc__ del func_name, func @@ -711,7 +711,7 @@ class _AssociationDict(_AssociationCollection): return key in self.col def __iter__(self): - return self.col.iterkeys() + return iter(self.col.keys()) def clear(self): self.col.clear() @@ -738,7 +738,7 @@ class _AssociationDict(_AssociationCollection): return cmp(dict(self), other) def __repr__(self): - return repr(dict(self.items())) + return repr(dict(list(self.items()))) def get(self, key, default=None): try: @@ -754,13 +754,13 @@ class _AssociationDict(_AssociationCollection): return self[key] def keys(self): - return self.col.keys() + return list(self.col.keys()) def iterkeys(self): - return self.col.iterkeys() + return iter(self.col.keys()) def values(self): - return [self._get(member) for member in self.col.values()] + return [self._get(member) for member in list(self.col.values())] def itervalues(self): for key in self.col: @@ -811,13 +811,13 @@ class _AssociationDict(_AssociationCollection): self[key] = value def copy(self): - return dict(self.items()) + return dict(list(self.items())) def __hash__(self): raise TypeError("%s objects are unhashable" % type(self).__name__) - for func_name, func in locals().items(): - if (util.callable(func) and func.func_name == func_name and + for func_name, func in list(locals().items()): + if (util.callable(func) and func.__name__ == func_name and not func.__doc__ and hasattr(dict, func_name)): func.__doc__ = getattr(dict, func_name).__doc__ del func_name, func @@ -838,7 +838,7 @@ class _AssociationSet(_AssociationCollection): def __len__(self): return len(self.col) - def __nonzero__(self): + def __bool__(self): if self.col: return True else: @@ -1014,8 +1014,8 @@ class _AssociationSet(_AssociationCollection): def __hash__(self): raise TypeError("%s objects are unhashable" % type(self).__name__) - for func_name, func in locals().items(): - if (util.callable(func) and func.func_name == func_name and + for func_name, func in list(locals().items()): + if (util.callable(func) and func.__name__ == func_name and not func.__doc__ and hasattr(set, func_name)): func.__doc__ = getattr(set, func_name).__doc__ del func_name, func diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py index 6f3ffddc7..21fac8534 100644 --- a/lib/sqlalchemy/ext/declarative/api.py +++ b/lib/sqlalchemy/ext/declarative/api.py @@ -424,7 +424,7 @@ class DeferredReflection(object): def prepare(cls, engine): """Reflect all :class:`.Table` objects for all current :class:`.DeferredReflection` subclasses""" - to_map = [m for m in _MapperConfig.configs.values() + to_map = [m for m in list(_MapperConfig.configs.values()) if issubclass(m.cls, cls)] for thingy in to_map: cls._sa_decl_prepare(thingy.local_table, engine) diff --git a/lib/sqlalchemy/ext/declarative/base.py b/lib/sqlalchemy/ext/declarative/base.py index ee2f0134a..2099f9eb0 100644 --- a/lib/sqlalchemy/ext/declarative/base.py +++ b/lib/sqlalchemy/ext/declarative/base.py @@ -57,7 +57,7 @@ def _as_declarative(cls, classname, dict_): class_mapped = _declared_mapping_info(base) is not None - for name, obj in vars(base).items(): + for name, obj in list(vars(base).items()): if name == '__mapper_args__': if not mapper_args_fn and ( not class_mapped or @@ -129,7 +129,7 @@ def _as_declarative(cls, classname, dict_): ret.doc = obj.__doc__ # apply inherited columns as we should - for k, v in potential_columns.items(): + for k, v in list(potential_columns.items()): dict_[k] = v if inherited_table_args and not tablename: @@ -173,7 +173,7 @@ def _as_declarative(cls, classname, dict_): # extract columns from the class dict declared_columns = set() - for key, c in our_stuff.iteritems(): + for key, c in our_stuff.items(): if isinstance(c, (ColumnProperty, CompositeProperty)): for col in c.columns: if isinstance(col, Column) and \ @@ -354,7 +354,7 @@ class _MapperConfig(object): # in which case the mapper makes this combination). # See if the superclass has a similar column property. # If so, join them together. - for k, col in properties.items(): + for k, col in list(properties.items()): if not isinstance(col, expression.ColumnElement): continue if k in inherited_mapper._props: diff --git a/lib/sqlalchemy/ext/declarative/clsregistry.py b/lib/sqlalchemy/ext/declarative/clsregistry.py index 89975716d..95aba93fa 100644 --- a/lib/sqlalchemy/ext/declarative/clsregistry.py +++ b/lib/sqlalchemy/ext/declarative/clsregistry.py @@ -255,7 +255,7 @@ def _resolver(cls, prop): return x.cls else: return x - except NameError, n: + except NameError as n: raise exc.InvalidRequestError( "When initializing mapper %s, expression %r failed to " "locate a name (%r). If this is a class name, consider " @@ -275,14 +275,14 @@ def _deferred_relationship(cls, prop): for attr in ('argument', 'order_by', 'primaryjoin', 'secondaryjoin', 'secondary', '_user_defined_foreign_keys', 'remote_side'): v = getattr(prop, attr) - if isinstance(v, basestring): + if isinstance(v, str): setattr(prop, attr, resolve_arg(v)) if prop.backref and isinstance(prop.backref, tuple): key, kwargs = prop.backref for attr in ('primaryjoin', 'secondaryjoin', 'secondary', 'foreign_keys', 'remote_side', 'order_by'): - if attr in kwargs and isinstance(kwargs[attr], basestring): + if attr in kwargs and isinstance(kwargs[attr], str): kwargs[attr] = resolve_arg(kwargs[attr]) return prop diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py index b1b851f72..08c0bdf13 100644 --- a/lib/sqlalchemy/ext/mutable.py +++ b/lib/sqlalchemy/ext/mutable.py @@ -485,7 +485,7 @@ class Mutable(MutableBase): def changed(self): """Subclasses should call this method whenever change events occur.""" - for parent, key in self._parents.items(): + for parent, key in list(self._parents.items()): flag_modified(parent, key) @classmethod @@ -579,7 +579,7 @@ class MutableComposite(MutableBase): def changed(self): """Subclasses should call this method whenever change events occur.""" - for parent, key in self._parents.items(): + for parent, key in list(self._parents.items()): prop = object_mapper(parent).get_property(key) for value, attr_name in zip( diff --git a/lib/sqlalchemy/ext/orderinglist.py b/lib/sqlalchemy/ext/orderinglist.py index ffdd971a0..930464d7b 100644 --- a/lib/sqlalchemy/ext/orderinglist.py +++ b/lib/sqlalchemy/ext/orderinglist.py @@ -324,7 +324,7 @@ class OrderingList(list): if stop < 0: stop += len(self) - for i in xrange(start, stop, step): + for i in range(start, stop, step): self.__setitem__(i, entity[i]) else: self._order_entity(index, entity, True) @@ -334,21 +334,21 @@ class OrderingList(list): super(OrderingList, self).__delitem__(index) self._reorder() - # Py2K - def __setslice__(self, start, end, values): - super(OrderingList, self).__setslice__(start, end, values) - self._reorder() - - def __delslice__(self, start, end): - super(OrderingList, self).__delslice__(start, end) - self._reorder() - # end Py2K +# start Py2K +# def __setslice__(self, start, end, values): +# super(OrderingList, self).__setslice__(start, end, values) +# self._reorder() +# +# def __delslice__(self, start, end): +# super(OrderingList, self).__delslice__(start, end) +# self._reorder() +# end Py2K def __reduce__(self): return _reconstitute, (self.__class__, self.__dict__, list(self)) - for func_name, func in locals().items(): - if (util.callable(func) and func.func_name == func_name and + for func_name, func in list(locals().items()): + if (util.callable(func) and func.__name__ == func_name and not func.__doc__ and hasattr(list, func_name)): func.__doc__ = getattr(list, func_name).__doc__ del func_name, func diff --git a/lib/sqlalchemy/ext/serializer.py b/lib/sqlalchemy/ext/serializer.py index 5a3fb5937..759652014 100644 --- a/lib/sqlalchemy/ext/serializer.py +++ b/lib/sqlalchemy/ext/serializer.py @@ -61,20 +61,22 @@ from ..engine import Engine from ..util import pickle import re import base64 -# Py3K -#from io import BytesIO as byte_buffer -# Py2K -from cStringIO import StringIO as byte_buffer +# start Py3K +from io import BytesIO as byte_buffer +# end Py3K +# start Py2K +#from cStringIO import StringIO as byte_buffer # end Py2K -# Py3K -#def b64encode(x): -# return base64.b64encode(x).decode('ascii') -#def b64decode(x): -# return base64.b64decode(x.encode('ascii')) -# Py2K -b64encode = base64.b64encode -b64decode = base64.b64decode +# start Py3K +def b64encode(x): + return base64.b64encode(x).decode('ascii') +def b64decode(x): + return base64.b64decode(x.encode('ascii')) +# end Py3K +# start Py2K +#b64encode = base64.b64encode +#b64decode = base64.b64decode # end Py2K __all__ = ['Serializer', 'Deserializer', 'dumps', 'loads'] diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index 0132bb389..07927890e 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -1628,7 +1628,7 @@ def contains_eager(*keys, **kwargs): alias = kwargs.pop('alias', None) if kwargs: raise exc.ArgumentError( - 'Invalid kwargs for contains_eager: %r' % kwargs.keys()) + 'Invalid kwargs for contains_eager: %r' % list(kwargs.keys())) return strategies.EagerLazyOption(keys, lazy='joined', propagate_to_loaders=False, chained=True), \ strategies.LoadEagerFromAliasOption(keys, alias=alias, chained=True) diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 3eda127fd..691904bb3 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -1214,7 +1214,7 @@ class History(History): """ - def __nonzero__(self): + def __bool__(self): return self != HISTORY_BLANK def empty(self): diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index 5691acfff..0a11b83c6 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -657,11 +657,12 @@ class CollectionAdapter(object): if getattr(obj, '_sa_adapter', None) is not None: return getattr(obj, '_sa_adapter') elif setting_type == dict: - # Py3K - #return obj.values() - # Py2K - return getattr(obj, 'itervalues', getattr(obj, 'values'))() - # end Py2K +# start Py3K + return list(obj.values()) +# end Py3K +# start Py2K +# return getattr(obj, 'itervalues', getattr(obj, 'values'))() +# end Py2K else: return iter(obj) @@ -705,14 +706,15 @@ class CollectionAdapter(object): def __iter__(self): """Iterate over entities in the collection.""" - # Py3K requires iter() here +# start Py3K +# end Py3K return iter(getattr(self._data(), '_sa_iterator')()) def __len__(self): """Count entities in the collection.""" return len(list(getattr(self._data(), '_sa_iterator')())) - def __nonzero__(self): + def __bool__(self): return True def fire_append_event(self, item, initiator=None): @@ -883,7 +885,7 @@ def _instrument_class(cls): # search for _sa_instrument_role-decorated methods in # method resolution order, assign to roles for supercls in cls.__mro__: - for name, method in vars(supercls).items(): + for name, method in list(vars(supercls).items()): if not util.callable(method): continue @@ -917,11 +919,11 @@ def _instrument_class(cls): collection_type = util.duck_type_collection(cls) if collection_type in __interfaces: canned_roles, decorators = __interfaces[collection_type] - for role, name in canned_roles.items(): + for role, name in list(canned_roles.items()): roles.setdefault(role, name) # apply ABC auto-decoration to methods that need it - for method, decorator in decorators.items(): + for method, decorator in list(decorators.items()): fn = getattr(cls, method, None) if (fn and method not in methods and not hasattr(fn, '_sa_instrumented')): @@ -952,12 +954,12 @@ def _instrument_class(cls): # apply ad-hoc instrumentation from decorators, class-level defaults # and implicit role declarations - for method_name, (before, argument, after) in methods.items(): + for method_name, (before, argument, after) in list(methods.items()): setattr(cls, method_name, _instrument_membership_mutator(getattr(cls, method_name), before, argument, after)) # intern the role map - for role, method_name in roles.items(): + for role, method_name in list(roles.items()): setattr(cls, '_sa_%s' % role, getattr(cls, method_name)) setattr(cls, '_sa_instrumented', id(cls)) @@ -1094,14 +1096,14 @@ def _list_decorators(): stop += len(self) if step == 1: - for i in xrange(start, stop, step): + for i in range(start, stop, step): if len(self) > start: del self[start] for i, item in enumerate(value): self.insert(i + start, item) else: - rng = range(start, stop, step) + rng = list(range(start, stop, step)) if len(value) != len(rng): raise ValueError( "attempt to assign sequence of size %s to " @@ -1128,24 +1130,24 @@ def _list_decorators(): _tidy(__delitem__) return __delitem__ - # Py2K - def __setslice__(fn): - def __setslice__(self, start, end, values): - for value in self[start:end]: - __del(self, value) - values = [__set(self, value) for value in values] - fn(self, start, end, values) - _tidy(__setslice__) - return __setslice__ - - def __delslice__(fn): - def __delslice__(self, start, end): - for value in self[start:end]: - __del(self, value) - fn(self, start, end) - _tidy(__delslice__) - return __delslice__ - # end Py2K +# start Py2K +# def __setslice__(fn): +# def __setslice__(self, start, end, values): +# for value in self[start:end]: +# __del(self, value) +# values = [__set(self, value) for value in values] +# fn(self, start, end, values) +# _tidy(__setslice__) +# return __setslice__ +# +# def __delslice__(fn): +# def __delslice__(self, start, end): +# for value in self[start:end]: +# __del(self, value) +# fn(self, start, end) +# _tidy(__delslice__) +# return __delslice__ +# end Py2K def extend(fn): def extend(self, iterable): @@ -1251,7 +1253,7 @@ def _dict_decorators(): def update(self, __other=Unspecified, **kw): if __other is not Unspecified: if hasattr(__other, 'keys'): - for key in __other.keys(): + for key in list(__other.keys()): if (key not in self or self[key] is not __other[key]): self[key] = __other[key] @@ -1467,11 +1469,12 @@ __interfaces = { ), # decorators are required for dicts and object collections. - # Py3K - #dict: ({'iterator': 'values'}, _dict_decorators()), - # Py2K - dict: ({'iterator': 'itervalues'}, _dict_decorators()), - # end Py2K +# start Py3K + dict: ({'iterator': 'values'}, _dict_decorators()), +# end Py3K +# start Py2K +# dict: ({'iterator': 'itervalues'}, _dict_decorators()), +# end Py2K } diff --git a/lib/sqlalchemy/orm/descriptor_props.py b/lib/sqlalchemy/orm/descriptor_props.py index 1969bd03b..86b445bb6 100644 --- a/lib/sqlalchemy/orm/descriptor_props.py +++ b/lib/sqlalchemy/orm/descriptor_props.py @@ -184,7 +184,7 @@ class CompositeProperty(DescriptorProperty): def _init_props(self): self.props = props = [] for attr in self.attrs: - if isinstance(attr, basestring): + if isinstance(attr, str): prop = self.parent.get_property(attr) elif isinstance(attr, schema.Column): prop = self.parent._columntoproperty[attr] diff --git a/lib/sqlalchemy/orm/evaluator.py b/lib/sqlalchemy/orm/evaluator.py index 0844e2f72..e8433290c 100644 --- a/lib/sqlalchemy/orm/evaluator.py +++ b/lib/sqlalchemy/orm/evaluator.py @@ -13,9 +13,9 @@ class UnevaluatableError(Exception): _straight_ops = set(getattr(operators, op) for op in ('add', 'mul', 'sub', - # Py2K - 'div', - # end Py2K +# start Py2K +# 'div', +# end Py2K 'mod', 'truediv', 'lt', 'le', 'ne', 'gt', 'ge', 'eq')) @@ -50,7 +50,7 @@ class EvaluatorCompiler(object): return lambda obj: get_corresponding_attr(obj) def visit_clauselist(self, clause): - evaluators = map(self.process, clause.clauses) + evaluators = list(map(self.process, clause.clauses)) if clause.operator is operators.or_: def evaluate(obj): has_null = False @@ -79,8 +79,8 @@ class EvaluatorCompiler(object): return evaluate def visit_binary(self, clause): - eval_left, eval_right = map(self.process, - [clause.left, clause.right]) + eval_left, eval_right = list(map(self.process, + [clause.left, clause.right])) operator = clause.operator if operator is operators.is_: def evaluate(obj): diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py index 01d34428e..f010a7699 100644 --- a/lib/sqlalchemy/orm/identity.py +++ b/lib/sqlalchemy/orm/identity.py @@ -75,7 +75,7 @@ class WeakInstanceDict(IdentityMap): state = dict.__getitem__(self, key) o = state.obj() if o is None: - raise KeyError, key + raise KeyError(key) return o def __contains__(self, key): @@ -152,30 +152,32 @@ class WeakInstanceDict(IdentityMap): return result - # Py3K - #def items(self): - # return iter(self._items()) - # - #def values(self): - # return iter(self._values()) - # Py2K - items = _items - - def iteritems(self): - return iter(self.items()) - - values = _values - - def itervalues(self): - return iter(self.values()) - # end Py2K +# start Py3K + def items(self): + return iter(self._items()) + + def values(self): + return iter(self._values()) +# end Py3K +# start Py2K +# items = _items +# +# def iteritems(self): +# return iter(self.items()) +# +# values = _values +# +# def itervalues(self): +# return iter(self.values()) +# end Py2K def all_states(self): - # Py3K - # return list(dict.values(self)) - # Py2K - return dict.values(self) - # end Py2K +# start Py3K + return list(dict.values(self)) +# end Py3K +# start Py2K +# return dict.values(self) +# end Py2K def discard(self, state): st = dict.get(self, state.key, None) @@ -189,7 +191,7 @@ class WeakInstanceDict(IdentityMap): class StrongInstanceDict(IdentityMap): def all_states(self): - return [attributes.instance_state(o) for o in self.itervalues()] + return [attributes.instance_state(o) for o in self.values()] def contains_state(self, state): return ( diff --git a/lib/sqlalchemy/orm/instrumentation.py b/lib/sqlalchemy/orm/instrumentation.py index 0e71494c4..ce12acf20 100644 --- a/lib/sqlalchemy/orm/instrumentation.py +++ b/lib/sqlalchemy/orm/instrumentation.py @@ -279,7 +279,7 @@ class ClassManager(dict): @property def attributes(self): - return self.itervalues() + return iter(self.values()) ## InstanceState management @@ -325,7 +325,7 @@ class ClassManager(dict): """TODO""" return self.get_impl(key).hasparent(state, optimistic=optimistic) - def __nonzero__(self): + def __bool__(self): """All ClassManagers are non-zero regardless of attribute state.""" return True @@ -444,21 +444,23 @@ def __init__(%(apply_pos)s): func_vars = util.format_argspec_init(original__init__, grouped=False) func_text = func_body % func_vars - # Py3K - #func_defaults = getattr(original__init__, '__defaults__', None) - #func_kw_defaults = getattr(original__init__, '__kwdefaults__', None) - # Py2K - func = getattr(original__init__, 'im_func', original__init__) - func_defaults = getattr(func, 'func_defaults', None) - # end Py2K +# start Py3K + func_defaults = getattr(original__init__, '__defaults__', None) + func_kw_defaults = getattr(original__init__, '__kwdefaults__', None) +# end Py3K +# start Py2K +# func = getattr(original__init__, 'im_func', original__init__) +# func_defaults = getattr(func, 'func_defaults', None) +# end Py2K env = locals().copy() - exec func_text in env + exec(func_text, env) __init__ = env['__init__'] __init__.__doc__ = original__init__.__doc__ if func_defaults: - __init__.func_defaults = func_defaults - # Py3K - #if func_kw_defaults: - # __init__.__kwdefaults__ = func_kw_defaults + __init__.__defaults__ = func_defaults +# start Py3K + if func_kw_defaults: + __init__.__kwdefaults__ = func_kw_defaults +# end Py3K return __init__ diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index 70743624c..f14c8ca47 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -15,7 +15,7 @@ Other than the deprecated extensions, this module and the classes within should be considered mostly private. """ -from __future__ import absolute_import + from .. import exc as sa_exc, util, inspect from ..sql import operators @@ -659,7 +659,7 @@ class PropertyOption(MapperOption): tokens = deque(self.key) while tokens: token = tokens.popleft() - if isinstance(token, basestring): + if isinstance(token, str): # wildcard token if token.endswith(':*'): return [path.token(token)] diff --git a/lib/sqlalchemy/orm/loading.py b/lib/sqlalchemy/orm/loading.py index 5937197fd..e1f4d1b7c 100644 --- a/lib/sqlalchemy/orm/loading.py +++ b/lib/sqlalchemy/orm/loading.py @@ -11,7 +11,7 @@ the functions here are called primarily by Query, Mapper, as well as some of the attribute loading strategies. """ -from __future__ import absolute_import + from .. import util from . import attributes, exc as orm_exc, state as statelib @@ -47,11 +47,11 @@ def instances(query, cursor, context): query._entities[0].mapper.dispatch.append_result (process, labels) = \ - zip(*[ + list(zip(*[ query_entity.row_processor(query, context, custom_rows) for query_entity in query._entities - ]) + ])) while True: context.progress = {} @@ -84,11 +84,11 @@ def instances(query, cursor, context): context.progress.pop(context.refresh_state) statelib.InstanceState._commit_all_states( - context.progress.items(), + list(context.progress.items()), session.identity_map ) - for state, (dict_, attrs) in context.partials.iteritems(): + for state, (dict_, attrs) in context.partials.items(): state._commit(dict_, attrs) for row in rows: @@ -507,7 +507,7 @@ def _populators(mapper, context, path, row, adapter, pops = (new_populators, existing_populators, delayed_populators, eager_populators) - for prop in mapper._props.itervalues(): + for prop in mapper._props.values(): for i, pop in enumerate(prop.create_row_processor( context, diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index c08d91b57..91c678547 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -13,7 +13,7 @@ This is a semi-private module; the main configurational API of the ORM is available in :class:`~sqlalchemy.orm.`. """ -from __future__ import absolute_import + import types import weakref from itertools import chain @@ -581,7 +581,7 @@ class Mapper(_InspectionAttr): if with_polymorphic == '*': self.with_polymorphic = ('*', None) elif isinstance(with_polymorphic, (tuple, list)): - if isinstance(with_polymorphic[0], (basestring, tuple, list)): + if isinstance(with_polymorphic[0], (str, tuple, list)): self.with_polymorphic = with_polymorphic else: self.with_polymorphic = (with_polymorphic, None) @@ -626,7 +626,7 @@ class Mapper(_InspectionAttr): self.inherits._inheriting_mappers.add(self) self.passive_updates = self.inherits.passive_updates self._all_tables = self.inherits._all_tables - for key, prop in mapper._props.iteritems(): + for key, prop in mapper._props.items(): if key not in self._props and \ not self._should_exclude(key, key, local=False, column=None): @@ -866,12 +866,12 @@ class Mapper(_InspectionAttr): # load custom properties if self._init_properties: - for key, prop in self._init_properties.iteritems(): + for key, prop in self._init_properties.items(): self._configure_property(key, prop, False) # pull properties from the inherited mapper if any. if self.inherits: - for key, prop in self.inherits._props.iteritems(): + for key, prop in self.inherits._props.items(): if key not in self._props and \ not self._should_exclude(key, key, local=False, column=None): @@ -919,7 +919,7 @@ class Mapper(_InspectionAttr): if self.polymorphic_on is not None: setter = True - if isinstance(self.polymorphic_on, basestring): + if isinstance(self.polymorphic_on, str): # polymorphic_on specified as as string - link # it to mapped ColumnProperty try: @@ -1235,7 +1235,7 @@ class Mapper(_InspectionAttr): """ self._log("_post_configure_properties() started") - l = [(key, prop) for key, prop in self._props.iteritems()] + l = [(key, prop) for key, prop in self._props.items()] for key, prop in l: self._log("initialize prop %s", key) @@ -1253,7 +1253,7 @@ class Mapper(_InspectionAttr): using `add_property`. """ - for key, value in dict_of_properties.iteritems(): + for key, value in dict_of_properties.items(): self.add_property(key, value) def add_property(self, key, prop): @@ -1350,7 +1350,7 @@ class Mapper(_InspectionAttr): """return an iterator of all MapperProperty objects.""" if _new_mappers: configure_mappers() - return self._props.itervalues() + return iter(self._props.values()) def _mappers_from_spec(self, spec, selectable): """given a with_polymorphic() argument, return the set of mappers it @@ -1623,7 +1623,7 @@ class Mapper(_InspectionAttr): if _new_mappers: configure_mappers() return util.ImmutableProperties(util.OrderedDict( - (k, v) for k, v in self._props.iteritems() + (k, v) for k, v in self._props.items() if isinstance(v, type_) )) @@ -1972,7 +1972,7 @@ class Mapper(_InspectionAttr): visited_states = set() prp, mpp = object(), object() - visitables = deque([(deque(self._props.values()), prp, + visitables = deque([(deque(list(self._props.values())), prp, state, state.dict)]) while visitables: @@ -1994,7 +1994,7 @@ class Mapper(_InspectionAttr): corresponding_dict = iterator.popleft() yield instance, instance_mapper, \ corresponding_state, corresponding_dict - visitables.append((deque(instance_mapper._props.values()), + visitables.append((deque(list(instance_mapper._props.values())), prp, corresponding_state, corresponding_dict)) @@ -2011,7 +2011,7 @@ class Mapper(_InspectionAttr): table_to_mapper.setdefault(t, mapper) extra_dependencies = [] - for table, mapper in table_to_mapper.items(): + for table, mapper in list(table_to_mapper.items()): super_ = mapper.inherits if super_: extra_dependencies.extend([ @@ -2040,7 +2040,7 @@ class Mapper(_InspectionAttr): return fk.parent not in cols return False - sorted_ = sql_util.sort_tables(table_to_mapper.iterkeys(), + sorted_ = sql_util.sort_tables(iter(table_to_mapper.keys()), skip_fn=skip, extra_dependencies=extra_dependencies) diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py index e225a7c83..0eedea793 100644 --- a/lib/sqlalchemy/orm/persistence.py +++ b/lib/sqlalchemy/orm/persistence.py @@ -45,7 +45,7 @@ def save_obj(base_mapper, states, uowtransaction, single=False): cached_connections = _cached_connection_dict(base_mapper) - for table, mapper in base_mapper._sorted_tables.iteritems(): + for table, mapper in base_mapper._sorted_tables.items(): insert = _collect_insert_commands(base_mapper, uowtransaction, table, states_to_insert) @@ -77,7 +77,7 @@ def post_update(base_mapper, states, uowtransaction, post_update_cols): base_mapper, states, uowtransaction) - for table, mapper in base_mapper._sorted_tables.iteritems(): + for table, mapper in base_mapper._sorted_tables.items(): update = _collect_post_update_commands(base_mapper, uowtransaction, table, states_to_update, post_update_cols) @@ -105,7 +105,7 @@ def delete_obj(base_mapper, states, uowtransaction): table_to_mapper = base_mapper._sorted_tables - for table in reversed(table_to_mapper.keys()): + for table in reversed(list(table_to_mapper.keys())): delete = _collect_delete_commands(base_mapper, uowtransaction, table, states_to_delete) @@ -318,7 +318,7 @@ def _collect_update_commands(base_mapper, uowtransaction, # history is only # in a different table than the one # where the version_id_col is. - for prop in mapper._columntoproperty.itervalues(): + for prop in mapper._columntoproperty.values(): history = attributes.get_state_history( state, prop.key, attributes.PASSIVE_NO_INITIALIZE) @@ -526,7 +526,7 @@ def _emit_insert_statements(base_mapper, uowtransaction, for (connection, pkeys, hasvalue, has_all_pks), \ records in groupby(insert, lambda rec: (rec[4], - rec[2].keys(), + list(rec[2].keys()), bool(rec[5]), rec[6]) ): @@ -612,7 +612,7 @@ def _emit_post_update_statements(base_mapper, uowtransaction, # also group them into common (connection, cols) sets # to support executemany(). for key, grouper in groupby( - update, lambda rec: (rec[4], rec[2].keys()) + update, lambda rec: (rec[4], list(rec[2].keys())) ): connection = key[0] multiparams = [params for state, state_dict, @@ -646,7 +646,7 @@ def _emit_delete_statements(base_mapper, uowtransaction, cached_connections, return table.delete(clause) - for connection, del_objects in delete.iteritems(): + for connection, del_objects in delete.items(): statement = base_mapper._memo(('delete', table), delete_stmt) connection = cached_connections[connection] @@ -803,7 +803,7 @@ class BulkUD(object): raise sa_exc.ArgumentError( "Valid strategies for session synchronization " "are %s" % (", ".join(sorted(repr(x) - for x in lookup.keys())))) + for x in list(lookup.keys()))))) else: return klass(*arg) @@ -868,7 +868,7 @@ class BulkEvaluate(BulkUD): #TODO: detect when the where clause is a trivial primary key match self.matched_objects = [ obj for (cls, pk), obj in - query.session.identity_map.iteritems() + query.session.identity_map.items() if issubclass(cls, target_cls) and eval_condition(obj)] @@ -951,7 +951,7 @@ class BulkUpdateEvaluate(BulkEvaluate, BulkUpdate): def _additional_evaluators(self, evaluator_compiler): self.value_evaluators = {} - for key, value in self.values.iteritems(): + for key, value in self.values.items(): key = _attr_as_key(key) self.value_evaluators[key] = evaluator_compiler.process( expression._literal_as_binds(value)) @@ -959,7 +959,7 @@ class BulkUpdateEvaluate(BulkEvaluate, BulkUpdate): def _do_post_synchronize(self): session = self.query.session states = set() - evaluated_keys = self.value_evaluators.keys() + evaluated_keys = list(self.value_evaluators.keys()) for obj in self.matched_objects: state, dict_ = attributes.instance_state(obj),\ attributes.instance_dict(obj) diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 9f8721de9..8c0576527 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -27,7 +27,7 @@ from .interfaces import MANYTOMANY, MANYTOONE, ONETOMANY,\ mapperlib = util.importlater("sqlalchemy.orm", "mapperlib") NoneType = type(None) -from descriptor_props import CompositeProperty, SynonymProperty, \ +from .descriptor_props import CompositeProperty, SynonymProperty, \ ComparableProperty, ConcreteInheritedProperty __all__ = ['ColumnProperty', 'CompositeProperty', 'SynonymProperty', @@ -1204,7 +1204,7 @@ class RelationshipProperty(StrategizedProperty): if not self.is_primary(): return if self.backref is not None and not self.back_populates: - if isinstance(self.backref, basestring): + if isinstance(self.backref, str): backref_key, kwargs = self.backref, {} else: backref_key, kwargs = self.backref diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index c9f3a2699..80441b976 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -47,7 +47,7 @@ def _generative(*assertions): def generate(fn, *args, **kw): self = args[0]._clone() for assertion in assertions: - assertion(self, fn.func_name) + assertion(self, fn.__name__) fn(self, *args[1:], **kw) return self return generate @@ -981,11 +981,12 @@ class Query(object): """Return a scalar result corresponding to the given column expression.""" try: - # Py3K - #return self.values(column).__next__()[0] - # Py2K - return self.values(column).next()[0] - # end Py2K +# start Py3K + return self.values(column).__next__()[0] +# end Py3K +# start Py2K +# return self.values(column).next()[0] +# end Py2K except StopIteration: return None @@ -1231,7 +1232,7 @@ class Query(object): """ clauses = [_entity_descriptor(self._joinpoint_zero(), key) == value - for key, value in kwargs.iteritems()] + for key, value in kwargs.items()] return self.filter(sql.and_(*clauses)) @_generative(_no_statement_condition, _no_limit_offset) @@ -1296,7 +1297,7 @@ class Query(object): """ - if isinstance(criterion, basestring): + if isinstance(criterion, str): criterion = sql.text(criterion) if criterion is not None and \ @@ -1655,7 +1656,7 @@ class Query(object): kwargs.pop('from_joinpoint', False) if kwargs: raise TypeError("unknown arguments: %s" % - ','.join(kwargs.iterkeys())) + ','.join(iter(kwargs.keys()))) return self._join(props, outerjoin=False, create_aliases=aliased, from_joinpoint=from_joinpoint) @@ -1671,7 +1672,7 @@ class Query(object): kwargs.pop('from_joinpoint', False) if kwargs: raise TypeError("unknown arguments: %s" % - ','.join(kwargs.iterkeys())) + ','.join(iter(kwargs.keys()))) return self._join(props, outerjoin=True, create_aliases=aliased, from_joinpoint=from_joinpoint) @@ -1701,7 +1702,7 @@ class Query(object): if len(keys) == 2 and \ isinstance(keys[0], (expression.FromClause, type, AliasedClass)) and \ - isinstance(keys[1], (basestring, expression.ClauseElement, + isinstance(keys[1], (str, expression.ClauseElement, interfaces.PropComparator)): # detect 2-arg form of join and # convert to a tuple. @@ -1721,14 +1722,14 @@ class Query(object): # is a little bit of legacy behavior still at work here # which means they might be in either order. may possibly # lock this down to (right_entity, onclause) in 0.6. - if isinstance(arg1, (interfaces.PropComparator, basestring)): + if isinstance(arg1, (interfaces.PropComparator, str)): right_entity, onclause = arg2, arg1 else: right_entity, onclause = arg1, arg2 left_entity = prop = None - if isinstance(onclause, basestring): + if isinstance(onclause, str): left_entity = self._joinpoint_zero() descriptor = _entity_descriptor(left_entity, onclause) @@ -1922,7 +1923,7 @@ class Query(object): clause = orm_join(clause, right, onclause, isouter=outerjoin) - except sa_exc.ArgumentError, ae: + except sa_exc.ArgumentError as ae: raise sa_exc.InvalidRequestError( "Could not find a FROM clause to join from. " "Tried joining to %s, but got: %s" % (right, ae)) @@ -1947,7 +1948,7 @@ class Query(object): try: clause = orm_join(clause, right, onclause, isouter=outerjoin) - except sa_exc.ArgumentError, ae: + except sa_exc.ArgumentError as ae: raise sa_exc.InvalidRequestError( "Could not find a FROM clause to join from. " "Tried joining to %s, but got: %s" % (right, ae)) @@ -2115,7 +2116,7 @@ class Query(object): appropriate to the entity class represented by this ``Query``. """ - if isinstance(statement, basestring): + if isinstance(statement, str): statement = sql.text(statement) if not isinstance(statement, @@ -2609,7 +2610,7 @@ class Query(object): use_labels=context.labels) from_clause = inner - for eager_join in context.eager_joins.values(): + for eager_join in list(context.eager_joins.values()): # EagerLoader places a 'stop_on' attribute on the join, # giving us a marker as to where the "splice point" of # the join should be @@ -2674,7 +2675,7 @@ class Query(object): subtypes are selected from the total results. """ - for (ext_info, adapter) in self._mapper_adapter_map.values(): + for (ext_info, adapter) in list(self._mapper_adapter_map.values()): if ext_info in self._join_entities: continue single_crit = ext_info.mapper._single_table_criterion @@ -2697,7 +2698,7 @@ class _QueryEntity(object): def __new__(cls, *args, **kwargs): if cls is _QueryEntity: entity = args[1] - if not isinstance(entity, basestring) and \ + if not isinstance(entity, str) and \ _is_mapped_class(entity): cls = _MapperEntity else: @@ -2905,7 +2906,7 @@ class _ColumnEntity(_QueryEntity): self.expr = column self.namespace = namespace - if isinstance(column, basestring): + if isinstance(column, str): column = sql.literal_column(column) self._label_name = column.name elif isinstance(column, ( @@ -3080,7 +3081,7 @@ class AliasOption(interfaces.MapperOption): self.alias = alias def process_query(self, query): - if isinstance(self.alias, basestring): + if isinstance(self.alias, str): alias = query._mapper_zero().mapped_table.alias(self.alias) else: alias = self.alias diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index f7a5558f1..3d5f94246 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -5,7 +5,7 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php """Provides the Session class and related utilities.""" -from __future__ import with_statement + import weakref from .. import util, sql, engine, exc as sa_exc, event @@ -35,7 +35,7 @@ class _SessionClassMethods(object): def close_all(cls): """Close *all* sessions in memory.""" - for sess in _sessions.values(): + for sess in list(_sessions.values()): sess.close() @classmethod @@ -249,7 +249,7 @@ class SessionTransaction(object): if s.key: del s.key - for s, (oldkey, newkey) in self._key_switches.items(): + for s, (oldkey, newkey) in list(self._key_switches.items()): self.session.identity_map.discard(s) s.key = oldkey self.session.identity_map.replace(s) @@ -327,7 +327,7 @@ class SessionTransaction(object): subtransaction.commit() if not self.session._flushing: - for _flush_guard in xrange(100): + for _flush_guard in range(100): if self.session._is_clean(): break self.session.flush() @@ -604,7 +604,7 @@ class Session(_SessionClassMethods): SessionExtension._adapt_listener(self, ext) if binds is not None: - for mapperortable, bind in binds.iteritems(): + for mapperortable, bind in binds.items(): if isinstance(mapperortable, (type, Mapper)): self.bind_mapper(mapperortable, bind) else: @@ -1775,7 +1775,7 @@ class Session(_SessionClassMethods): Session. """ - return iter(list(self._new.values()) + self.identity_map.values()) + return iter(list(self._new.values()) + list(self.identity_map.values())) def _contains_state(self, state): return state in self._new or self.identity_map.contains_state(state) @@ -2138,13 +2138,13 @@ class Session(_SessionClassMethods): def deleted(self): "The set of all instances marked as 'deleted' within this ``Session``" - return util.IdentitySet(self._deleted.values()) + return util.IdentitySet(list(self._deleted.values())) @property def new(self): "The set of all instances marked as 'new' within this ``Session``." - return util.IdentitySet(self._new.values()) + return util.IdentitySet(list(self._new.values())) class sessionmaker(_SessionClassMethods): @@ -2236,7 +2236,7 @@ class sessionmaker(_SessionClassMethods): session = Session() # invokes sessionmaker.__call__() """ - for k, v in self.kw.items(): + for k, v in list(self.kw.items()): local_kw.setdefault(k, v) return self.class_(**local_kw) @@ -2255,7 +2255,7 @@ class sessionmaker(_SessionClassMethods): return "%s(class_=%r%s)" % ( self.__class__.__name__, self.class_.__name__, - ", ".join("%s=%r" % (k, v) for k, v in self.kw.items()) + ", ".join("%s=%r" % (k, v) for k, v in list(self.kw.items())) ) _sessions = weakref.WeakValueDictionary() diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 6ade91b3e..8fe37e41c 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -417,7 +417,7 @@ class InstanceState(interfaces._InspectionAttr): against this set when a refresh operation occurs. """ - return set([k for k, v in self.callables.items() if v is self]) + return set([k for k, v in list(self.callables.items()) if v is self]) def _instance_dict(self): return None diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 6660a39ef..e80745c79 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -359,7 +359,7 @@ class LazyLoader(AbstractRelationshipLoader): ) if self.use_get: - for col in self._equated_columns.keys(): + for col in list(self._equated_columns.keys()): if col in self.mapper._equivalent_columns: for c in self.mapper._equivalent_columns[col]: self._equated_columns[c] = self._equated_columns[col] @@ -1332,7 +1332,7 @@ class EagerLazyOption(StrategizedOption): def __init__(self, key, lazy=True, chained=False, propagate_to_loaders=True ): - if isinstance(key[0], basestring) and key[0] == '*': + if isinstance(key[0], str) and key[0] == '*': if len(key) != 1: raise sa_exc.ArgumentError( "Wildcard identifier '*' must " @@ -1384,7 +1384,7 @@ class LoadEagerFromAliasOption(PropertyOption): def __init__(self, key, alias=None, chained=False): super(LoadEagerFromAliasOption, self).__init__(key) if alias is not None: - if not isinstance(alias, basestring): + if not isinstance(alias, str): info = inspect(alias) alias = info.selectable self.alias = alias @@ -1401,7 +1401,7 @@ class LoadEagerFromAliasOption(PropertyOption): root_mapper, prop = paths[-1].path[-2:] if self.alias is not None: - if isinstance(self.alias, basestring): + if isinstance(self.alias, str): self.alias = prop.target.alias(self.alias) paths[-1].set(query, "user_defined_eager_row_processor", sql_util.ColumnAdapter(self.alias, diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 1f5115c41..54b0ebf72 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -315,7 +315,7 @@ class UOWTransaction(object): # see if the graph of mapper dependencies has cycles. self.cycles = cycles = topological.find_cycles( self.dependencies, - self.postsort_actions.values()) + list(self.postsort_actions.values())) if cycles: # if yes, break the per-mapper actions into @@ -342,7 +342,7 @@ class UOWTransaction(object): for dep in convert[edge[1]]: self.dependencies.add((edge[0], dep)) - return set([a for a in self.postsort_actions.values() + return set([a for a in list(self.postsort_actions.values()) if not a.disabled ] ).difference(cycles) @@ -381,7 +381,7 @@ class UOWTransaction(object): """ states = set(self.states) isdel = set( - s for (s, (isdelete, listonly)) in self.states.iteritems() + s for (s, (isdelete, listonly)) in self.states.items() if isdelete ) other = states.difference(isdel) @@ -461,7 +461,7 @@ class PostSortRec(object): def __repr__(self): return "%s(%s)" % ( self.__class__.__name__, - ",".join(str(x) for x in self.__dict__.values()) + ",".join(str(x) for x in list(self.__dict__.values())) ) diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 35cb0bdf5..30a8a8084 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -120,7 +120,7 @@ def polymorphic_union(table_map, typecolname, colnames = util.OrderedSet() colnamemaps = {} types = {} - for key in table_map.keys(): + for key in list(table_map.keys()): table = table_map[key] # mysql doesnt like selecting from a select; @@ -146,7 +146,7 @@ def polymorphic_union(table_map, typecolname, return sql.type_coerce(sql.null(), types[name]).label(name) result = [] - for type, table in table_map.iteritems(): + for type, table in table_map.items(): if typecolname is not None: result.append( sql.select([col(name, table) for name in colnames] + @@ -203,7 +203,7 @@ def identity_key(*args, **kwargs): "positional arguments, got %s" % len(args)) if kwargs: raise sa_exc.ArgumentError("unknown keyword arguments: %s" - % ", ".join(kwargs.keys())) + % ", ".join(list(kwargs.keys()))) mapper = class_mapper(class_) if "ident" in locals(): return mapper.identity_key_from_primary_key(util.to_list(ident)) @@ -211,7 +211,7 @@ def identity_key(*args, **kwargs): instance = kwargs.pop("instance") if kwargs: raise sa_exc.ArgumentError("unknown keyword arguments: %s" - % ", ".join(kwargs.keys())) + % ", ".join(list(kwargs.keys()))) mapper = object_mapper(instance) return mapper.identity_key_from_instance(instance) @@ -300,7 +300,7 @@ class PathRegistry(object): def pairs(self): path = self.path - for i in xrange(0, len(path), 2): + for i in range(0, len(path), 2): yield path[i], path[i + 1] def contains_mapper(self, mapper): @@ -314,10 +314,10 @@ class PathRegistry(object): def serialize(self): path = self.path - return zip( + return list(zip( [m.class_ for m in [path[i] for i in range(0, len(path), 2)]], [path[i].key for i in range(1, len(path), 2)] + [None] - ) + )) @classmethod def deserialize(cls, path): @@ -411,7 +411,7 @@ class EntityRegistry(PathRegistry, dict): self.path = parent.path + (entity,) - def __nonzero__(self): + def __bool__(self): return True def __getitem__(self, entity): @@ -589,8 +589,8 @@ class AliasedClass(object): return self.__adapt_prop(attr, key) elif hasattr(attr, 'func_code'): is_method = getattr(self.__target, key, None) - if is_method and is_method.im_self is not None: - return util.types.MethodType(attr.im_func, self, self) + if is_method and is_method.__self__ is not None: + return util.types.MethodType(attr.__func__, self, self) else: return None elif hasattr(attr, '__get__'): @@ -880,7 +880,7 @@ class _ORMJoin(expression.Join): self._joined_from_info = right_info - if isinstance(onclause, basestring): + if isinstance(onclause, str): onclause = getattr(left_orm_info.entity, onclause) if isinstance(onclause, attributes.QueryableAttribute): @@ -1001,7 +1001,7 @@ def with_parent(instance, prop): parent/child relationship. """ - if isinstance(prop, basestring): + if isinstance(prop, str): mapper = object_mapper(instance) prop = getattr(mapper.class_, prop).property elif isinstance(prop, attributes.QueryableAttribute): diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 501b6d2a0..562a76163 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -57,7 +57,7 @@ def clear_managers(): All pools and connections are disposed. """ - for manager in proxies.itervalues(): + for manager in proxies.values(): manager.close() proxies.clear() @@ -368,7 +368,7 @@ class _ConnectionRecord(object): connection = self.__pool._creator() self.__pool.logger.debug("Created new connection %r", connection) return connection - except Exception, e: + except Exception as e: self.__pool.logger.debug("Error on connect(): %s", e) raise @@ -391,7 +391,7 @@ def _finalize_fairy(connection, connection_record, pool, ref, echo): # Immediately close detached instances if connection_record is None: pool._close_connection(connection) - except Exception, e: + except Exception as e: if connection_record is not None: connection_record.invalidate(e=e) if isinstance(e, (SystemExit, KeyboardInterrupt)): @@ -499,7 +499,7 @@ class _ConnectionFairy(object): self._connection_record, self) return self - except exc.DisconnectionError, e: + except exc.DisconnectionError as e: self._pool.logger.info( "Disconnection detected on checkout: %s", e) self._connection_record.invalidate(e) @@ -755,7 +755,7 @@ class QueuePool(Pool): wait = self._max_overflow > -1 and \ self._overflow >= self._max_overflow return self._pool.get(wait, self._timeout) - except sqla_queue.SAAbort, aborted: + except sqla_queue.SAAbort as aborted: return aborted.context._do_get() except sqla_queue.Empty: if self._max_overflow > -1 and \ @@ -1004,7 +1004,7 @@ class _DBProxy(object): self._create_pool_mutex = threading.Lock() def close(self): - for key in self.pools.keys(): + for key in list(self.pools.keys()): del self.pools[key] def __del__(self): diff --git a/lib/sqlalchemy/processors.py b/lib/sqlalchemy/processors.py index 9963ca9a3..bf95d146b 100644 --- a/lib/sqlalchemy/processors.py +++ b/lib/sqlalchemy/processors.py @@ -38,10 +38,10 @@ def str_to_datetime_processor_factory(regexp, type_): "'%s'" % (type_.__name__, value)) if has_named_groups: groups = m.groupdict(0) - return type_(**dict(zip(groups.iterkeys(), - map(int, groups.itervalues())))) + return type_(**dict(list(zip(iter(groups.keys()), + list(map(int, iter(groups.values()))))))) else: - return type_(*map(int, m.groups(0))) + return type_(*list(map(int, m.groups(0)))) return process diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 9a07b9de4..030c400a7 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -27,7 +27,7 @@ Since these objects are part of the SQL expression language, they are usable as components in SQL expressions. """ -from __future__ import with_statement + import re import inspect from . import exc, util, dialects, event, events, inspection @@ -683,7 +683,7 @@ class Table(SchemaItem, expression.TableClause): continue Index(index.name, unique=index.unique, - *[table.c[col] for col in index.columns.keys()], + *[table.c[col] for col in list(index.columns.keys())], **index.kwargs) table.dispatch._update(self.dispatch) return table @@ -898,7 +898,7 @@ class Column(SchemaItem, expression.ColumnClause): type_ = kwargs.pop('type_', None) args = list(args) if args: - if isinstance(args[0], basestring): + if isinstance(args[0], str): if name is not None: raise exc.ArgumentError( "May not pass name positionally and as a keyword.") @@ -944,11 +944,12 @@ class Column(SchemaItem, expression.ColumnClause): args.append(self.default) else: if getattr(self.type, '_warn_on_bytestring', False): - # Py3K - #if isinstance(self.default, bytes): - # Py2K - if isinstance(self.default, str): - # end Py2K +# start Py3K + if isinstance(self.default, bytes): +# end Py3K +# start Py2K +# if isinstance(self.default, str): +# end Py2K util.warn("Unicode column received non-unicode " "default value.") args.append(ColumnDefault(self.default)) @@ -983,7 +984,7 @@ class Column(SchemaItem, expression.ColumnClause): if kwargs: raise exc.ArgumentError( - "Unknown arguments passed to Column: " + repr(kwargs.keys())) + "Unknown arguments passed to Column: " + repr(list(kwargs.keys()))) def __str__(self): if self.name is None: @@ -1069,7 +1070,7 @@ class Column(SchemaItem, expression.ColumnClause): self.table = table if self.index: - if isinstance(self.index, basestring): + if isinstance(self.index, str): raise exc.ArgumentError( "The 'index' keyword argument on Column is boolean only. " "To create indexes with a specific name, create an " @@ -1077,7 +1078,7 @@ class Column(SchemaItem, expression.ColumnClause): Index(expression._truncated_label('ix_%s' % self._label), self, unique=self.unique) elif self.unique: - if isinstance(self.unique, basestring): + if isinstance(self.unique, str): raise exc.ArgumentError( "The 'unique' keyword argument on Column is boolean " "only. To create unique constraints or indexes with a " @@ -1153,23 +1154,24 @@ class Column(SchemaItem, expression.ColumnClause): nullable=self.nullable, quote=self.quote, _proxies=[self], *fk) - except TypeError, e: - # Py3K - #raise TypeError( - # "Could not create a copy of this %r object. " - # "Ensure the class includes a _constructor() " - # "attribute or method which accepts the " - # "standard Column constructor arguments, or " - # "references the Column class itself." % self.__class__) from e - # Py2K + except TypeError as e: +# start Py3K raise TypeError( "Could not create a copy of this %r object. " "Ensure the class includes a _constructor() " "attribute or method which accepts the " "standard Column constructor arguments, or " - "references the Column class itself. " - "Original error: %s" % (self.__class__, e)) - # end Py2K + "references the Column class itself." % self.__class__) from e +# end Py3K +# start Py2K +# raise TypeError( +# "Could not create a copy of this %r object. " +# "Ensure the class includes a _constructor() " +# "attribute or method which accepts the " +# "standard Column constructor arguments, or " +# "references the Column class itself. " +# "Original error: %s" % (self.__class__, e)) +# end Py2K c.table = selectable selectable._columns.add(c) @@ -1345,7 +1347,7 @@ class ForeignKey(SchemaItem): if schema: return schema + "." + self.column.table.name + \ "." + self.column.key - elif isinstance(self._colspec, basestring): + elif isinstance(self._colspec, str): return self._colspec elif hasattr(self._colspec, '__clause_element__'): _column = self._colspec.__clause_element__() @@ -1390,7 +1392,7 @@ class ForeignKey(SchemaItem): """ # ForeignKey inits its remote column as late as possible, so tables # can be defined without dependencies - if isinstance(self._colspec, basestring): + if isinstance(self._colspec, str): # locate the parent table this foreign key is attached to. we # use the "original" column which our parent column represents # (its a list of columns/other ColumnElements if the parent @@ -1657,7 +1659,8 @@ class ColumnDefault(DefaultGenerator): defaulted = argspec[3] is not None and len(argspec[3]) or 0 positionals = len(argspec[0]) - defaulted - # Py3K compat - no unbound methods +# start Py3K +# end Py3K if inspect.ismethod(inspectable) or inspect.isclass(fn): positionals -= 1 @@ -1919,7 +1922,7 @@ class DefaultClause(FetchedValue): has_argument = True def __init__(self, arg, for_update=False, _reflected=False): - util.assert_arg_type(arg, (basestring, + util.assert_arg_type(arg, (str, expression.ClauseElement, expression.TextClause), 'arg') super(DefaultClause, self).__init__(for_update) @@ -2029,7 +2032,7 @@ class ColumnCollectionMixin(object): def _set_parent(self, table): for col in self._pending_colargs: - if isinstance(col, basestring): + if isinstance(col, str): col = table.c[col] self.columns.add(col) @@ -2066,7 +2069,7 @@ class ColumnCollectionConstraint(ColumnCollectionMixin, Constraint): def copy(self, **kw): c = self.__class__(name=self.name, deferrable=self.deferrable, - initially=self.initially, *self.columns.keys()) + initially=self.initially, *list(self.columns.keys())) c.dispatch._update(self.dispatch) return c @@ -2256,19 +2259,19 @@ class ForeignKeyConstraint(Constraint): @property def columns(self): - return self._elements.keys() + return list(self._elements.keys()) @property def elements(self): - return self._elements.values() + return list(self._elements.values()) def _set_parent(self, table): super(ForeignKeyConstraint, self)._set_parent(table) - for col, fk in self._elements.iteritems(): + for col, fk in self._elements.items(): # string-specified column names now get # resolved to Column objects - if isinstance(col, basestring): + if isinstance(col, str): try: col = table.c[col] except KeyError: @@ -2293,8 +2296,8 @@ class ForeignKeyConstraint(Constraint): def copy(self, schema=None, **kw): fkc = ForeignKeyConstraint( - [x.parent.key for x in self._elements.values()], - [x._get_colspec(schema=schema) for x in self._elements.values()], + [x.parent.key for x in list(self._elements.values())], + [x._get_colspec(schema=schema) for x in list(self._elements.values())], name=self.name, onupdate=self.onupdate, ondelete=self.ondelete, @@ -2569,7 +2572,7 @@ class MetaData(SchemaItem): return 'MetaData(bind=%r)' % self.bind def __contains__(self, table_or_key): - if not isinstance(table_or_key, basestring): + if not isinstance(table_or_key, str): table_or_key = table_or_key.key return table_or_key in self.tables @@ -2584,7 +2587,7 @@ class MetaData(SchemaItem): dict.pop(self.tables, key, None) if self._schemas: self._schemas = set([t.schema - for t in self.tables.values() + for t in list(self.tables.values()) if t.schema is not None]) def __getstate__(self): @@ -2629,7 +2632,7 @@ class MetaData(SchemaItem): def _bind_to(self, bind): """Bind this MetaData to an Engine, Connection, string or URL.""" - if isinstance(bind, (basestring, url.URL)): + if isinstance(bind, (str, url.URL)): from sqlalchemy import create_engine self._bind = create_engine(bind) else: @@ -2662,7 +2665,7 @@ class MetaData(SchemaItem): :meth:`.Inspector.sorted_tables` """ - return sqlutil.sort_tables(self.tables.itervalues()) + return sqlutil.sort_tables(iter(self.tables.values())) def reflect(self, bind=None, schema=None, views=False, only=None): """Load all available table definitions from the database. @@ -2723,7 +2726,7 @@ class MetaData(SchemaItem): bind.dialect.get_view_names(conn, schema) ) - current = set(self.tables.iterkeys()) + current = set(self.tables.keys()) if only is None: load = [name for name in available if name not in current] @@ -2845,7 +2848,7 @@ class ThreadLocalMetaData(MetaData): def _bind_to(self, bind): """Bind to a Connectable in the caller's thread.""" - if isinstance(bind, (basestring, url.URL)): + if isinstance(bind, (str, url.URL)): try: self.context._engine = self.__engines[bind] except KeyError: @@ -2870,7 +2873,7 @@ class ThreadLocalMetaData(MetaData): def dispose(self): """Dispose all bound engines, in all thread contexts.""" - for e in self.__engines.itervalues(): + for e in self.__engines.values(): if hasattr(e, 'dispose'): e.dispose() @@ -3075,7 +3078,7 @@ class DDLElement(expression.Executable, _DDLCompiles): not self._should_execute_deprecated(None, target, bind, **kw): return False - if isinstance(self.dialect, basestring): + if isinstance(self.dialect, str): if self.dialect != bind.engine.name: return False elif isinstance(self.dialect, (tuple, list, set)): @@ -3090,7 +3093,7 @@ class DDLElement(expression.Executable, _DDLCompiles): def _should_execute_deprecated(self, event, target, bind, **kw): if self.on is None: return True - elif isinstance(self.on, basestring): + elif isinstance(self.on, str): return self.on == bind.engine.name elif isinstance(self.on, (tuple, list, set)): return bind.engine.name in self.on @@ -3105,7 +3108,7 @@ class DDLElement(expression.Executable, _DDLCompiles): def _check_ddl_on(self, on): if (on is not None and - (not isinstance(on, (basestring, tuple, list, set)) and + (not isinstance(on, (str, tuple, list, set)) and not util.callable(on))): raise exc.ArgumentError( "Expected the name of a database dialect, a tuple " @@ -3230,7 +3233,7 @@ class DDL(DDLElement): """ - if not isinstance(statement, basestring): + if not isinstance(statement, str): raise exc.ArgumentError( "Expected a string or unicode SQL statement, got '%r'" % statement) @@ -3262,7 +3265,7 @@ def _to_schema_column(element): def _to_schema_column_or_string(element): if hasattr(element, '__clause_element__'): element = element.__clause_element__() - if not isinstance(element, (basestring, expression.ColumnElement)): + if not isinstance(element, (str, expression.ColumnElement)): msg = "Element %r is not a string name or column element" raise exc.ArgumentError(msg % element) return element diff --git a/lib/sqlalchemy/sql/__init__.py b/lib/sqlalchemy/sql/__init__.py index 1b81a18c5..9700f26a0 100644 --- a/lib/sqlalchemy/sql/__init__.py +++ b/lib/sqlalchemy/sql/__init__.py @@ -64,5 +64,5 @@ from .expression import ( from .visitors import ClauseVisitor -__tmp = locals().keys() +__tmp = list(locals().keys()) __all__ = sorted([i for i in __tmp if not i.startswith('__')]) diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index b902f9ffc..e5a2da366 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -51,7 +51,7 @@ RESERVED_WORDS = set([ 'using', 'verbose', 'when', 'where']) LEGAL_CHARACTERS = re.compile(r'^[A-Z0-9_$]+$', re.I) -ILLEGAL_INITIAL_CHARACTERS = set([str(x) for x in xrange(0, 10)]).union(['$']) +ILLEGAL_INITIAL_CHARACTERS = set([str(x) for x in range(0, 10)]).union(['$']) BIND_PARAMS = re.compile(r'(?> sys.stderr, "Error emptying table %s: %r" % ( - table, ex) + except sa.exc.DBAPIError as ex: + print("Error emptying table %s: %r" % ( + table, ex), file=sys.stderr) def setup(self): self._setup_each_tables() @@ -187,10 +187,10 @@ class TablesTest(TestBase): def _load_fixtures(cls): """Insert rows as represented by the fixtures() method.""" headers, rows = {}, {} - for table, data in cls.fixtures().iteritems(): + for table, data in cls.fixtures().items(): if len(data) < 2: continue - if isinstance(table, basestring): + if isinstance(table, str): table = cls.tables[table] headers[table] = data[0] rows[table] = data[1:] @@ -199,7 +199,7 @@ class TablesTest(TestBase): continue cls.bind.execute( table.insert(), - [dict(zip(headers[table], column_values)) + [dict(list(zip(headers[table], column_values))) for column_values in rows[table]]) @@ -284,8 +284,8 @@ class MappedTest(_ORMTest, TablesTest, assertions.AssertsExecutionResults): cls_registry[classname] = cls return type.__init__(cls, classname, bases, dict_) - class _Base(object): - __metaclass__ = FindFixture + class _Base(object, metaclass=FindFixture): + pass class Basic(BasicEntity, _Base): pass diff --git a/lib/sqlalchemy/testing/plugin/noseplugin.py b/lib/sqlalchemy/testing/plugin/noseplugin.py index 5bd7ff3cd..7ad61c7b9 100644 --- a/lib/sqlalchemy/testing/plugin/noseplugin.py +++ b/lib/sqlalchemy/testing/plugin/noseplugin.py @@ -9,10 +9,10 @@ When third party libraries use this plugin, it can be imported normally as "from sqlalchemy.testing.plugin import noseplugin". """ -from __future__ import absolute_import + import os -import ConfigParser +import configparser from nose.plugins import Plugin from nose import SkipTest @@ -55,9 +55,9 @@ def _log(option, opt_str, value, parser): def _list_dbs(*args): - print "Available --db options (use --dburi to override)" + print("Available --db options (use --dburi to override)") for macro in sorted(file_config.options('db')): - print "%20s\t%s" % (macro, file_config.get('db', macro)) + print("%20s\t%s" % (macro, file_config.get('db', macro))) sys.exit(0) @@ -318,7 +318,7 @@ class NoseSQLAlchemy(Plugin): opt("--write-profiles", action="store_true", dest="write_profiles", default=False, help="Write/update profiling data.") global file_config - file_config = ConfigParser.ConfigParser() + file_config = configparser.ConfigParser() file_config.read(['setup.cfg', 'test.cfg']) def configure(self, options, conf): diff --git a/lib/sqlalchemy/testing/profiling.py b/lib/sqlalchemy/testing/profiling.py index 19a9731be..bda44d80c 100644 --- a/lib/sqlalchemy/testing/profiling.py +++ b/lib/sqlalchemy/testing/profiling.py @@ -60,9 +60,9 @@ def profiled(target=None, **target_opts): if report: sort_ = target_opts.get('sort', profile_config['sort']) limit = target_opts.get('limit', profile_config['limit']) - print ("Profile report for target '%s' (%s)" % ( + print(("Profile report for target '%s' (%s)" % ( target, filename) - ) + )) stats = load_stats() stats.sort_stats(*sort_) @@ -198,7 +198,7 @@ class ProfileStatsFile(object): profile_f.close() def _write(self): - print("Writing profile file %s" % self.fname) + print(("Writing profile file %s" % self.fname)) profile_f = open(self.fname, "w") profile_f.write(self._header()) for test_key in sorted(self.data): @@ -253,11 +253,11 @@ def function_call_count(variance=0.05): else: line_no, expected_count = expected - print("Pstats calls: %d Expected %s" % ( + print(("Pstats calls: %d Expected %s" % ( callcount, expected_count ) - ) + )) stats.print_stats() #stats.print_callers() diff --git a/lib/sqlalchemy/testing/schema.py b/lib/sqlalchemy/testing/schema.py index 325d74f1e..6f3e87cc9 100644 --- a/lib/sqlalchemy/testing/schema.py +++ b/lib/sqlalchemy/testing/schema.py @@ -11,7 +11,7 @@ table_options = {} def Table(*args, **kw): """A schema.Table wrapper/hook for dialect-specific tweaks.""" - test_opts = dict([(k, kw.pop(k)) for k in kw.keys() + test_opts = dict([(k, kw.pop(k)) for k in list(kw.keys()) if k.startswith('test_')]) kw.update(table_options) @@ -58,7 +58,7 @@ def Table(*args, **kw): def Column(*args, **kw): """A schema.Column wrapper/hook for dialect-specific tweaks.""" - test_opts = dict([(k, kw.pop(k)) for k in kw.keys() + test_opts = dict([(k, kw.pop(k)) for k in list(kw.keys()) if k.startswith('test_')]) if not config.requirements.foreign_key_ddl.enabled: diff --git a/lib/sqlalchemy/testing/suite/test_ddl.py b/lib/sqlalchemy/testing/suite/test_ddl.py index fc1c19362..28251b807 100644 --- a/lib/sqlalchemy/testing/suite/test_ddl.py +++ b/lib/sqlalchemy/testing/suite/test_ddl.py @@ -1,4 +1,4 @@ -from __future__ import with_statement + from .. import fixtures, config, util from ..config import requirements diff --git a/lib/sqlalchemy/testing/suite/test_reflection.py b/lib/sqlalchemy/testing/suite/test_reflection.py index 7cae48572..ff76bd2cd 100644 --- a/lib/sqlalchemy/testing/suite/test_reflection.py +++ b/lib/sqlalchemy/testing/suite/test_reflection.py @@ -1,4 +1,4 @@ -from __future__ import with_statement + import sqlalchemy as sa from sqlalchemy import exc as sa_exc @@ -386,7 +386,7 @@ class ComponentReflectionTest(fixtures.TablesTest): self.tables.email_addresses, self.tables.dingalings insp = inspect(meta.bind) oid = insp.get_table_oid(table_name, schema) - self.assert_(isinstance(oid, (int, long))) + self.assert_(isinstance(oid, int)) def test_get_table_oid(self): self._test_get_table_oid('users') diff --git a/lib/sqlalchemy/testing/suite/test_types.py b/lib/sqlalchemy/testing/suite/test_types.py index 0716b1b91..4dd3884ed 100644 --- a/lib/sqlalchemy/testing/suite/test_types.py +++ b/lib/sqlalchemy/testing/suite/test_types.py @@ -15,9 +15,9 @@ import datetime class _UnicodeFixture(object): __requires__ = 'unicode_data', - data = u"Alors vous imaginez ma surprise, au lever du jour, "\ - u"quand une drôle de petite voix m’a réveillé. Elle "\ - u"disait: « S’il vous plaît… dessine-moi un mouton! »" + data = "Alors vous imaginez ma surprise, au lever du jour, "\ + "quand une drôle de petite voix m’a réveillé. Elle "\ + "disait: « S’il vous plaît… dessine-moi un mouton! »" @classmethod def define_tables(cls, metadata): @@ -47,7 +47,7 @@ class _UnicodeFixture(object): row, (self.data, ) ) - assert isinstance(row[0], unicode) + assert isinstance(row[0], str) def test_round_trip_executemany(self): unicode_table = self.tables.unicode_table @@ -58,7 +58,7 @@ class _UnicodeFixture(object): { 'unicode_data': self.data, } - for i in xrange(3) + for i in range(3) ] ) @@ -69,22 +69,22 @@ class _UnicodeFixture(object): ).fetchall() eq_( rows, - [(self.data, ) for i in xrange(3)] + [(self.data, ) for i in range(3)] ) for row in rows: - assert isinstance(row[0], unicode) + assert isinstance(row[0], str) def _test_empty_strings(self): unicode_table = self.tables.unicode_table config.db.execute( unicode_table.insert(), - {"unicode_data": u''} + {"unicode_data": ''} ) row = config.db.execute( select([unicode_table.c.unicode_data]) ).first() - eq_(row, (u'',)) + eq_(row, ('',)) class UnicodeVarcharTest(_UnicodeFixture, fixtures.TablesTest): diff --git a/lib/sqlalchemy/testing/util.py b/lib/sqlalchemy/testing/util.py index d9ff14eaf..5facd2f06 100644 --- a/lib/sqlalchemy/testing/util.py +++ b/lib/sqlalchemy/testing/util.py @@ -32,13 +32,13 @@ else: def picklers(): picklers = set() - # Py2K - try: - import cPickle - picklers.add(cPickle) - except ImportError: - pass - # end Py2K +# start Py2K +# try: +# import cPickle +# picklers.add(cPickle) +# except ImportError: +# pass +# end Py2K import pickle picklers.add(pickle) @@ -130,8 +130,8 @@ def function_named(fn, name): try: fn.__name__ = name except TypeError: - fn = types.FunctionType(fn.func_code, fn.func_globals, name, - fn.func_defaults, fn.func_closure) + fn = types.FunctionType(fn.__code__, fn.__globals__, name, + fn.__defaults__, fn.__closure__) return fn diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py index 41f3dbfed..9546945eb 100644 --- a/lib/sqlalchemy/testing/warnings.py +++ b/lib/sqlalchemy/testing/warnings.py @@ -1,4 +1,4 @@ -from __future__ import absolute_import + import warnings from .. import exc as sa_exc @@ -10,7 +10,7 @@ def testing_warn(msg, stacklevel=3): filename = "sqlalchemy.testing.warnings" lineno = 1 - if isinstance(msg, basestring): + if isinstance(msg, str): warnings.warn_explicit(msg, sa_exc.SAWarning, filename, lineno) else: warnings.warn_explicit(msg, filename, lineno) diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index 46cf9e2a1..4fbadcb0c 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -156,8 +156,8 @@ class TypeEngine(AbstractType): """ - return self.__class__.column_expression.func_code \ - is not TypeEngine.column_expression.func_code + return self.__class__.column_expression.__code__ \ + is not TypeEngine.column_expression.__code__ def bind_expression(self, bindvalue): """"Given a bind value (i.e. a :class:`.BindParameter` instance), @@ -194,8 +194,8 @@ class TypeEngine(AbstractType): """ - return self.__class__.bind_expression.func_code \ - is not TypeEngine.bind_expression.func_code + return self.__class__.bind_expression.__code__ \ + is not TypeEngine.bind_expression.__code__ def compare_values(self, x, y): """Compare two values for equality.""" @@ -392,12 +392,13 @@ class TypeEngine(AbstractType): return default.DefaultDialect() def __str__(self): - # Py3K - #return unicode(self.compile()) - # Py2K - return unicode(self.compile()).\ - encode('ascii', 'backslashreplace') - # end Py2K +# start Py3K + return str(self.compile()) +# end Py3K +# start Py2K +# return unicode(self.compile()).\ +# encode('ascii', 'backslashreplace') +# end Py2K def __init__(self, *args, **kwargs): """Support implementations that were passing arguments""" @@ -723,8 +724,8 @@ class TypeDecorator(TypeEngine): """ - return self.__class__.process_bind_param.func_code \ - is not TypeDecorator.process_bind_param.func_code + return self.__class__.process_bind_param.__code__ \ + is not TypeDecorator.process_bind_param.__code__ def bind_processor(self, dialect): """Provide a bound value processing function for the @@ -769,8 +770,8 @@ class TypeDecorator(TypeEngine): exception throw. """ - return self.__class__.process_result_value.func_code \ - is not TypeDecorator.process_result_value.func_code + return self.__class__.process_result_value.__code__ \ + is not TypeDecorator.process_result_value.__code__ def result_processor(self, dialect, coltype): """Provide a result value processing function for the given @@ -1114,11 +1115,12 @@ class String(Concatenable, TypeEngine): self.convert_unicode != 'force': if self._warn_on_bytestring: def process(value): - # Py3K - #if isinstance(value, bytes): - # Py2K - if isinstance(value, str): - # end Py2K +# start Py3K + if isinstance(value, bytes): +# end Py3K +# start Py2K +# if isinstance(value, str): +# end Py2K util.warn("Unicode type received non-unicode bind " "param value.") return value @@ -1130,7 +1132,7 @@ class String(Concatenable, TypeEngine): warn_on_bytestring = self._warn_on_bytestring def process(value): - if isinstance(value, unicode): + if isinstance(value, str): return encoder(value, self.unicode_error)[0] elif warn_on_bytestring and value is not None: util.warn("Unicode type received non-unicode bind " @@ -1156,7 +1158,7 @@ class String(Concatenable, TypeEngine): # habits. since we will be getting back unicode # in most cases, we check for it (decode will fail). def process(value): - if isinstance(value, unicode): + if isinstance(value, str): return value else: return to_unicode(value) @@ -1171,7 +1173,7 @@ class String(Concatenable, TypeEngine): @property def python_type(self): if self.convert_unicode: - return unicode + return str else: return str @@ -1318,12 +1320,12 @@ class Integer(_DateAffinity, TypeEngine): Integer: self.__class__, Numeric: Numeric, }, - # Py2K - operators.div: { - Integer: self.__class__, - Numeric: Numeric, - }, - # end Py2K +# start Py2K +# operators.div: { +# Integer: self.__class__, +# Numeric: Numeric, +# }, +# end Py2K operators.truediv: { Integer: self.__class__, Numeric: Numeric, @@ -1488,12 +1490,12 @@ class Numeric(_DateAffinity, TypeEngine): Numeric: self.__class__, Integer: self.__class__, }, - # Py2K - operators.div: { - Numeric: self.__class__, - Integer: self.__class__, - }, - # end Py2K +# start Py2K +# operators.div: { +# Numeric: self.__class__, +# Integer: self.__class__, +# }, +# end Py2K operators.truediv: { Numeric: self.__class__, Integer: self.__class__, @@ -1558,11 +1560,11 @@ class Float(Numeric): Interval: Interval, Numeric: self.__class__, }, - # Py2K - operators.div: { - Numeric: self.__class__, - }, - # end Py2K +# start Py2K +# operators.div: { +# Numeric: self.__class__, +# }, +# end Py2K operators.truediv: { Numeric: self.__class__, }, @@ -1693,11 +1695,12 @@ class _Binary(TypeEngine): @property def python_type(self): - # Py3K - #return bytes - # Py2K - return str - # end Py2K +# start Py3K + return bytes +# end Py3K +# start Py2K +# return str +# end Py2K # Python 3 - sqlite3 doesn't need the `Binary` conversion # here, though pg8000 does to indicate "bytea" @@ -1715,32 +1718,33 @@ class _Binary(TypeEngine): # Python 3 has native bytes() type # both sqlite3 and pg8000 seem to return it, # psycopg2 as of 2.5 returns 'memoryview' - # Py3K - #def result_processor(self, dialect, coltype): - # def process(value): - # if value is not None: - # value = bytes(value) - # return value - # return process - # Py2K +# start Py3K def result_processor(self, dialect, coltype): - if util.jython: - def process(value): - if value is not None: - if isinstance(value, array.array): - return value.tostring() - return str(value) - else: - return None - else: - process = processors.to_str + def process(value): + if value is not None: + value = bytes(value) + return value return process - # end Py2K +# end Py3K +# start Py2K +# def result_processor(self, dialect, coltype): +# if util.jython: +# def process(value): +# if value is not None: +# if isinstance(value, array.array): +# return value.tostring() +# return str(value) +# else: +# return None +# else: +# process = processors.to_str +# return process +# end Py2K def coerce_compared_value(self, op, value): """See :meth:`.TypeEngine.coerce_compared_value` for a description.""" - if isinstance(value, basestring): + if isinstance(value, str): return self else: return super(_Binary, self).coerce_compared_value(op, value) @@ -1997,7 +2001,7 @@ class Enum(String, SchemaType): convert_unicode = kw.pop('convert_unicode', None) if convert_unicode is None: for e in enums: - if isinstance(e, unicode): + if isinstance(e, str): convert_unicode = True break else: @@ -2296,11 +2300,11 @@ class Interval(_DateAffinity, TypeDecorator): operators.truediv: { Numeric: self.__class__ }, - # Py2K - operators.div: { - Numeric: self.__class__ - } - # end Py2K +# start Py2K +# operators.div: { +# Numeric: self.__class__ +# } +# end Py2K } @property @@ -2451,11 +2455,12 @@ STRINGTYPE = String() _type_map = { str: String(), - # Py3K - #bytes: LargeBinary(), - # Py2K - unicode: Unicode(), - # end Py2K +# start Py3K + bytes: LargeBinary(), +# end Py3K +# start Py2K +# unicode: Unicode(), +# end Py2K int: Integer(), float: Numeric(), bool: BOOLEANTYPE, diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index 8e61275e7..e505bdd5f 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -55,7 +55,7 @@ class KeyedTuple(tuple): t = tuple.__new__(cls, vals) t._labels = [] if labels: - t.__dict__.update(zip(labels, vals)) + t.__dict__.update(list(zip(labels, vals))) t._labels = labels return t @@ -94,7 +94,7 @@ class KeyedTuple(tuple): .. versionadded:: 0.8 """ - return dict((key, self.__dict__[key]) for key in self.keys()) + return dict((key, self.__dict__[key]) for key in list(self.keys())) class ImmutableContainer(object): @@ -142,7 +142,7 @@ class Properties(object): return len(self._data) def __iter__(self): - return self._data.itervalues() + return iter(self._data.values()) def __add__(self, other): return list(self) + list(other) @@ -189,13 +189,13 @@ class Properties(object): return default def keys(self): - return self._data.keys() + return list(self._data.keys()) def values(self): - return self._data.values() + return list(self._data.values()) def items(self): - return self._data.items() + return list(self._data.items()) def has_key(self, key): return key in self._data @@ -242,7 +242,7 @@ class OrderedDict(dict): def update(self, ____sequence=None, **kwargs): if ____sequence is not None: if hasattr(____sequence, 'keys'): - for key in ____sequence.keys(): + for key in list(____sequence.keys()): self.__setitem__(key, ____sequence[key]) else: for key, value in ____sequence: @@ -270,13 +270,13 @@ class OrderedDict(dict): return list(self._list) def iterkeys(self): - return iter(self.keys()) + return iter(list(self.keys())) def items(self): - return [(key, self[key]) for key in self.keys()] + return [(key, self[key]) for key in list(self.keys())] def iteritems(self): - return iter(self.items()) + return iter(list(self.items())) def __setitem__(self, key, object): if key not in self: @@ -470,8 +470,8 @@ class IdentitySet(object): if len(self) > len(other): return False - for m in itertools.ifilterfalse(other._members.__contains__, - self._members.iterkeys()): + for m in itertools.filterfalse(other._members.__contains__, + iter(self._members.keys())): return False return True @@ -491,8 +491,8 @@ class IdentitySet(object): if len(self) < len(other): return False - for m in itertools.ifilterfalse(self._members.__contains__, - other._members.iterkeys()): + for m in itertools.filterfalse(self._members.__contains__, + iter(other._members.keys())): return False return True @@ -582,7 +582,7 @@ class IdentitySet(object): return result def _member_id_tuples(self): - return ((id(v), v) for v in self._members.itervalues()) + return ((id(v), v) for v in self._members.values()) def __xor__(self, other): if not isinstance(other, IdentitySet): @@ -599,7 +599,7 @@ class IdentitySet(object): return self def copy(self): - return type(self)(self._members.itervalues()) + return type(self)(iter(self._members.values())) __copy__ = copy @@ -607,13 +607,13 @@ class IdentitySet(object): return len(self._members) def __iter__(self): - return self._members.itervalues() + return iter(self._members.values()) def __hash__(self): raise TypeError('set objects are unhashable') def __repr__(self): - return '%s(%r)' % (type(self).__name__, self._members.values()) + return '%s(%r)' % (type(self).__name__, list(self._members.values())) class WeakSequence(object): @@ -623,7 +623,7 @@ class WeakSequence(object): ) def __iter__(self): - return self._storage.itervalues() + return iter(self._storage.values()) def __getitem__(self, index): try: @@ -754,7 +754,7 @@ def flatten_iterator(x): """ for elem in x: - if not isinstance(elem, basestring) and hasattr(elem, '__iter__'): + if not isinstance(elem, str) and hasattr(elem, '__iter__'): for y in flatten_iterator(elem): yield y else: diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 033a87cc7..4eb915469 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -43,14 +43,14 @@ else: if sys.version_info < (2, 6): def next(iter): - return iter.next() + return iter.__next__() else: next = next if py3k_warning: import pickle else: try: - import cPickle as pickle + import pickle as pickle except ImportError: import pickle @@ -59,12 +59,13 @@ if sys.version_info < (2, 6): # in newer pythons from cgi import parse_qsl else: - from urlparse import parse_qsl + from urllib.parse import parse_qsl -# Py3K -#from inspect import getfullargspec as inspect_getfullargspec -# Py2K -from inspect import getargspec as inspect_getfullargspec +# start Py3K +from inspect import getfullargspec as inspect_getfullargspec +# end Py3K +# start Py2K +#from inspect import getargspec as inspect_getfullargspec # end Py2K if py3k_warning: diff --git a/lib/sqlalchemy/util/deprecations.py b/lib/sqlalchemy/util/deprecations.py index 34be4fbf8..e0dc168db 100644 --- a/lib/sqlalchemy/util/deprecations.py +++ b/lib/sqlalchemy/util/deprecations.py @@ -10,7 +10,7 @@ functionality.""" from .. import exc import warnings import re -from langhelpers import decorator +from .langhelpers import decorator def warn_deprecated(msg, stacklevel=3): diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index f6d9164e6..26dd97549 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -21,10 +21,12 @@ from functools import update_wrapper from .. import exc import hashlib from . import compat +import collections def md5_hex(x): - # Py3K - #x = x.encode('utf-8') +# start Py3K + x = x.encode('utf-8') +# end Py3K m = hashlib.md5() m.update(x) return m.hexdigest() @@ -77,8 +79,8 @@ def _unique_symbols(used, *bases): used = set(used) for base in bases: pool = itertools.chain((base,), - itertools.imap(lambda i: base + str(i), - xrange(1000))) + map(lambda i: base + str(i), + range(1000))) for sym in pool: if sym not in used: used.add(sym) @@ -95,7 +97,7 @@ def decorator(target): if not inspect.isfunction(fn): raise Exception("not a decoratable function") spec = inspect_getfullargspec(fn) - names = tuple(spec[0]) + spec[1:3] + (fn.func_name,) + names = tuple(spec[0]) + spec[1:3] + (fn.__name__,) targ_name, fn_name = _unique_symbols(names, 'target', 'fn') metadata = dict(target=targ_name, fn=fn_name) @@ -104,7 +106,7 @@ def decorator(target): code = 'lambda %(args)s: %(target)s(%(fn)s, %(apply_kw)s)' % ( metadata) decorated = eval(code, {targ_name: target, fn_name: fn}) - decorated.func_defaults = getattr(fn, 'im_func', fn).func_defaults + decorated.__defaults__ = getattr(fn, 'im_func', fn).__defaults__ return update_wrapper(decorated, fn) return update_wrapper(decorate, target) @@ -176,7 +178,7 @@ def get_cls_kwargs(cls): ctr = class_.__dict__.get('__init__', False) if (not ctr or not isinstance(ctr, types.FunctionType) or - not isinstance(ctr.func_code, types.CodeType)): + not isinstance(ctr.__code__, types.CodeType)): stack.update(class_.__bases__) continue @@ -194,7 +196,7 @@ try: from inspect import CO_VARKEYWORDS def inspect_func_args(fn): - co = fn.func_code + co = fn.__code__ nargs = co.co_argcount names = co.co_varnames args = list(names[:nargs]) @@ -250,7 +252,7 @@ def format_argspec_plus(fn, grouped=True): 'apply_pos': '(self, a, b, c, **d)'} """ - if callable(fn): + if isinstance(fn, collections.Callable): spec = inspect_getfullargspec(fn) else: # we accept an existing argspec... @@ -263,22 +265,23 @@ def format_argspec_plus(fn, grouped=True): else: self_arg = None - # Py3K - #apply_pos = inspect.formatargspec(spec[0], spec[1], - # spec[2], None, spec[4]) - #num_defaults = 0 - #if spec[3]: - # num_defaults += len(spec[3]) - #if spec[4]: - # num_defaults += len(spec[4]) - #name_args = spec[0] + spec[4] - # Py2K - apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2]) +# start Py3K + apply_pos = inspect.formatargspec(spec[0], spec[1], + spec[2], None, spec[4]) num_defaults = 0 if spec[3]: num_defaults += len(spec[3]) - name_args = spec[0] - # end Py2K + if spec[4]: + num_defaults += len(spec[4]) + name_args = spec[0] + spec[4] +# end Py3K +# start Py2K +# apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2]) +# num_defaults = 0 +# if spec[3]: +# num_defaults += len(spec[3]) +# name_args = spec[0] +# end Py2K if num_defaults: defaulted_vals = name_args[0 - num_defaults:] @@ -341,8 +344,8 @@ def unbound_method_to_callable(func_or_cls): """ - if isinstance(func_or_cls, types.MethodType) and not func_or_cls.im_self: - return func_or_cls.im_func + if isinstance(func_or_cls, types.MethodType) and not func_or_cls.__self__: + return func_or_cls.__func__ else: return func_or_cls @@ -399,7 +402,7 @@ class portable_instancemethod(object): """ def __init__(self, meth): - self.target = meth.im_self + self.target = meth.__self__ self.name = meth.__name__ def __call__(self, *arg, **kw): @@ -419,32 +422,34 @@ def class_hierarchy(cls): will not be descended. """ - # Py2K - if isinstance(cls, types.ClassType): - return list() - # end Py2K +# start Py2K +# if isinstance(cls, types.ClassType): +# return list() +# end Py2K hier = set([cls]) process = list(cls.__mro__) while process: c = process.pop() - # Py2K - if isinstance(c, types.ClassType): - continue +# start Py2K +# if isinstance(c, types.ClassType): +# continue +# for b in (_ for _ in c.__bases__ +# if _ not in hier and not isinstance(_, types.ClassType)): +# end Py2K +# start Py3K for b in (_ for _ in c.__bases__ - if _ not in hier and not isinstance(_, types.ClassType)): - # end Py2K - # Py3K - #for b in (_ for _ in c.__bases__ - # if _ not in hier): + if _ not in hier): +# end Py3K process.append(b) hier.add(b) - # Py3K - #if c.__module__ == 'builtins' or not hasattr(c, '__subclasses__'): - # continue - # Py2K - if c.__module__ == '__builtin__' or not hasattr(c, '__subclasses__'): +# start Py3K + if c.__module__ == 'builtins' or not hasattr(c, '__subclasses__'): continue - # end Py2K +# end Py3K +# start Py2K +# if c.__module__ == '__builtin__' or not hasattr(c, '__subclasses__'): +# continue +# end Py2K for s in [_ for _ in c.__subclasses__() if _ not in hier]: process.append(s) hier.add(s) @@ -501,9 +506,9 @@ def monkeypatch_proxied_specials(into_cls, from_cls, skip=None, only=None, "return %(name)s.%(method)s%(d_args)s" % locals()) env = from_instance is not None and {name: from_instance} or {} - exec py in env + exec(py, env) try: - env[method].func_defaults = fn.func_defaults + env[method].__defaults__ = fn.__defaults__ except AttributeError: pass setattr(into_cls, method, env[method]) @@ -512,11 +517,12 @@ def monkeypatch_proxied_specials(into_cls, from_cls, skip=None, only=None, def methods_equivalent(meth1, meth2): """Return True if the two methods are the same implementation.""" - # Py3K - #return getattr(meth1, '__func__', meth1) is getattr(meth2, '__func__', meth2) - # Py2K - return getattr(meth1, 'im_func', meth1) is getattr(meth2, 'im_func', meth2) - # end Py2K +# start Py3K + return getattr(meth1, '__func__', meth1) is getattr(meth2, '__func__', meth2) +# end Py3K +# start Py2K +# return getattr(meth1, 'im_func', meth1) is getattr(meth2, 'im_func', meth2) +# end Py2K def as_interface(obj, cls=None, methods=None, required=None): @@ -589,7 +595,7 @@ def as_interface(obj, cls=None, methods=None, required=None): for method, impl in dictlike_iteritems(obj): if method not in interface: raise TypeError("%r: unknown in this interface" % method) - if not callable(impl): + if not isinstance(impl, collections.Callable): raise TypeError("%r=%r is not callable" % (method, impl)) setattr(AnonymousInterface, method, staticmethod(impl)) found.add(method) @@ -753,7 +759,7 @@ class importlater(object): # from paste.deploy.converters def asbool(obj): - if isinstance(obj, (str, unicode)): + if isinstance(obj, str): obj = obj.strip().lower() if obj in ['true', 'yes', 'on', 'y', 't', '1']: return True @@ -814,13 +820,13 @@ def counter(): """Return a threadsafe counter function.""" lock = threading.Lock() - counter = itertools.count(1L) + counter = itertools.count(1) # avoid the 2to3 "next" transformation... def _next(): lock.acquire() try: - return counter.next() + return next(counter) finally: lock.release() @@ -876,15 +882,16 @@ def assert_arg_type(arg, argtype, name): def dictlike_iteritems(dictlike): """Return a (key, value) iterator for almost any dict-like object.""" - # Py3K - #if hasattr(dictlike, 'items'): - # return dictlike.items() - # Py2K - if hasattr(dictlike, 'iteritems'): - return dictlike.iteritems() - elif hasattr(dictlike, 'items'): - return iter(dictlike.items()) - # end Py2K +# start Py3K + if hasattr(dictlike, 'items'): + return list(dictlike.items()) +# end Py3K +# start Py2K +# if hasattr(dictlike, 'iteritems'): +# return dictlike.iteritems() +# elif hasattr(dictlike, 'items'): +# return iter(dictlike.items()) +# end Py2K getter = getattr(dictlike, '__getitem__', getattr(dictlike, 'get', None)) if getter is None: @@ -893,11 +900,11 @@ def dictlike_iteritems(dictlike): if hasattr(dictlike, 'iterkeys'): def iterator(): - for key in dictlike.iterkeys(): + for key in dictlike.keys(): yield key, getter(key) return iterator() elif hasattr(dictlike, 'keys'): - return iter((key, getter(key)) for key in dictlike.keys()) + return iter((key, getter(key)) for key in list(dictlike.keys())) else: raise TypeError( "Object '%r' is not dict-like" % dictlike) @@ -1034,7 +1041,7 @@ def warn(msg, stacklevel=3): be controlled. """ - if isinstance(msg, basestring): + if isinstance(msg, str): warnings.warn(msg, exc.SAWarning, stacklevel=stacklevel) else: warnings.warn(msg, stacklevel=stacklevel) -- cgit v1.2.1 From 2709ae46884f405d95dc16be0667a6cbbebcfb69 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 27 Apr 2013 20:02:24 -0400 Subject: work through dialects --- lib/sqlalchemy/connectors/pyodbc.py | 29 ++++++++++++--------------- lib/sqlalchemy/dialects/informix/base.py | 6 +++--- lib/sqlalchemy/dialects/mssql/adodbapi.py | 2 +- lib/sqlalchemy/dialects/mssql/base.py | 8 ++++---- lib/sqlalchemy/util/__init__.py | 2 +- lib/sqlalchemy/util/compat.py | 33 +++++++++++++++---------------- 6 files changed, 38 insertions(+), 42 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/connectors/pyodbc.py b/lib/sqlalchemy/connectors/pyodbc.py index 504414b0f..784344b82 100644 --- a/lib/sqlalchemy/connectors/pyodbc.py +++ b/lib/sqlalchemy/connectors/pyodbc.py @@ -5,11 +5,11 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php from . import Connector -from ..util import asbool +from .. import util + import sys import re -import urllib.request, urllib.parse, urllib.error class PyODBCConnector(Connector): @@ -56,10 +56,10 @@ class PyODBCConnector(Connector): connect_args = {} for param in ('ansi', 'unicode_results', 'autocommit'): if param in keys: - connect_args[param] = asbool(keys.pop(param)) + connect_args[param] = util.asbool(keys.pop(param)) if 'odbc_connect' in keys: - connectors = [urllib.parse.unquote_plus(keys.pop('odbc_connect'))] + connectors = [util.unquote_plus(keys.pop('odbc_connect'))] else: dsn_connection = 'dsn' in keys or \ ('host' in keys and 'database' not in keys) @@ -121,18 +121,15 @@ class PyODBCConnector(Connector): self.freetds_driver_version = dbapi_con.getinfo( pyodbc.SQL_DRIVER_VER) - # the "Py2K only" part here is theoretical. - # have not tried pyodbc + python3.1 yet. -# start Py2K -# self.supports_unicode_statements = ( -# not self.freetds and not self.easysoft) -# if self._user_supports_unicode_binds is not None: -# self.supports_unicode_binds = self._user_supports_unicode_binds -# else: -# self.supports_unicode_binds = ( -# not self.freetds or self.freetds_driver_version >= '0.91' -# ) and not self.easysoft -# end Py2K + if not util.py3k: + self.supports_unicode_statements = ( + not self.freetds and not self.easysoft) + if self._user_supports_unicode_binds is not None: + self.supports_unicode_binds = self._user_supports_unicode_binds + else: + self.supports_unicode_binds = ( + not self.freetds or self.freetds_driver_version >= '0.91' + ) and not self.easysoft # run other initialization which asks for user name, etc. super(PyODBCConnector, self).initialize(connection) diff --git a/lib/sqlalchemy/dialects/informix/base.py b/lib/sqlalchemy/dialects/informix/base.py index 691400e05..a5a6917af 100644 --- a/lib/sqlalchemy/dialects/informix/base.py +++ b/lib/sqlalchemy/dialects/informix/base.py @@ -299,7 +299,7 @@ class InfoDDLCompiler(compiler.DDLCompiler): def get_column_default_string(self, column): if (isinstance(column.server_default, schema.DefaultClause) and - isinstance(column.server_default.arg, str)): + isinstance(column.server_default.arg, util.string_type)): if isinstance(column.type, (sqltypes.Integer, sqltypes.Numeric)): return self.sql_compiler.process(text(column.server_default.arg)) @@ -323,10 +323,10 @@ class InfoDDLCompiler(compiler.DDLCompiler): remote_table = list(constraint._elements.values())[0].column.table text = "FOREIGN KEY (%s) REFERENCES %s (%s)" % ( ', '.join(preparer.quote(f.parent.name, f.parent.quote) - for f in list(constraint._elements.values())), + for f in constraint._elements.values()), preparer.format_table(remote_table), ', '.join(preparer.quote(f.column.name, f.column.quote) - for f in list(constraint._elements.values())) + for f in constraint._elements.values()) ) text += self.define_constraint_cascades(constraint) text += self.define_constraint_deferrability(constraint) diff --git a/lib/sqlalchemy/dialects/mssql/adodbapi.py b/lib/sqlalchemy/dialects/mssql/adodbapi.py index 080382d55..167b4e807 100644 --- a/lib/sqlalchemy/dialects/mssql/adodbapi.py +++ b/lib/sqlalchemy/dialects/mssql/adodbapi.py @@ -44,7 +44,7 @@ class MSDialect_adodbapi(MSDialect): @classmethod def import_dbapi(cls): - from . import adodbapi as module + import adodbapi as module return module colspecs = util.update_copy( diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index 827cf0186..c5b86b887 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -295,7 +295,7 @@ class _MSDate(sqltypes.Date): def process(value): if isinstance(value, datetime.datetime): return value.date() - elif isinstance(value, str): + elif isinstance(value, util.string_type): return datetime.date(*[ int(x or 0) for x in self._reg.match(value).groups() @@ -328,7 +328,7 @@ class TIME(sqltypes.TIME): def process(value): if isinstance(value, datetime.datetime): return value.time() - elif isinstance(value, str): + elif isinstance(value, util.string_type): return datetime.time(*[ int(x or 0) for x in self._reg.match(value).groups()]) @@ -1002,7 +1002,7 @@ class MSDDLCompiler(compiler.DDLCompiler): # handle other included columns if index.kwargs.get("mssql_include"): inclusions = [index.table.c[col] - if isinstance(col, str) else col + if isinstance(col, util.string_type) else col for col in index.kwargs["mssql_include"]] text += " INCLUDE (%s)" \ @@ -1150,7 +1150,7 @@ class MSDialect(default.DefaultDialect): try: default_schema_name = connection.scalar(query, name=user_name) if default_schema_name is not None: - return str(default_schema_name) + return util.text_type(default_schema_name) except: pass return self.schema_name diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 3fa06c793..2fcfabefd 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -7,7 +7,7 @@ from .compat import callable, cmp, reduce, \ threading, py3k, py3k_warning, jython, pypy, cpython, win32, set_types, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ - raise_from_cause + raise_from_cause, text_type, string_type, binary_type, quote_plus from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ Properties, OrderedProperties, ImmutableProperties, OrderedDict, \ diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 4eb915469..d00e3ab23 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -21,11 +21,8 @@ pypy = hasattr(sys, 'pypy_version_info') win32 = sys.platform.startswith('win') cpython = not pypy and not jython # TODO: something better for this ? -if py3k_warning: +if py3k: set_types = set -elif sys.version_info < (2, 6): - import sets - set_types = set, sets.Set else: # 2.6 deprecates sets.Set, but we still need to be able to detect them # in user code and as return values from DB-APIs @@ -46,7 +43,7 @@ if sys.version_info < (2, 6): return iter.__next__() else: next = next -if py3k_warning: +if py3k: import pickle else: try: @@ -54,19 +51,21 @@ else: except ImportError: import pickle -if sys.version_info < (2, 6): - # emits a nasty deprecation warning - # in newer pythons - from cgi import parse_qsl +from urllib.parse import parse_qsl + + +if py3k: + from inspect import getfullargspec as inspect_getfullargspec + from urllib.parse import quote_plus, unquote_plus + string_types = str, + binary_type = bytes + text_type = str else: - from urllib.parse import parse_qsl - -# start Py3K -from inspect import getfullargspec as inspect_getfullargspec -# end Py3K -# start Py2K -#from inspect import getargspec as inspect_getfullargspec -# end Py2K + from inspect import getargspec as inspect_getfullargspec + from urllib import quote_plus, unquote_plus + string_types = basestring, + binary_type = str + text_type = unicode if py3k_warning: # they're bringing it back in 3.2. brilliant ! -- cgit v1.2.1 From c926f0a9d8910c67554f053ed0f7902542679f0d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 27 Apr 2013 20:38:53 -0400 Subject: plugging away --- lib/sqlalchemy/dialects/informix/base.py | 2 +- lib/sqlalchemy/dialects/mssql/base.py | 6 +-- .../dialects/mssql/information_schema.py | 7 ++- lib/sqlalchemy/dialects/mysql/base.py | 27 ++++------- lib/sqlalchemy/dialects/mysql/cymysql.py | 9 +--- lib/sqlalchemy/dialects/mysql/oursql.py | 20 ++++---- lib/sqlalchemy/engine/base.py | 6 +-- lib/sqlalchemy/engine/ddl.py | 4 +- lib/sqlalchemy/engine/default.py | 53 ++++++++++------------ lib/sqlalchemy/event.py | 5 +- lib/sqlalchemy/schema.py | 27 ++++------- lib/sqlalchemy/sql/visitors.py | 2 +- lib/sqlalchemy/util/__init__.py | 5 +- lib/sqlalchemy/util/compat.py | 41 ++++++++--------- lib/sqlalchemy/util/langhelpers.py | 40 ++++++++-------- 15 files changed, 107 insertions(+), 147 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/informix/base.py b/lib/sqlalchemy/dialects/informix/base.py index a5a6917af..e13ea8819 100644 --- a/lib/sqlalchemy/dialects/informix/base.py +++ b/lib/sqlalchemy/dialects/informix/base.py @@ -299,7 +299,7 @@ class InfoDDLCompiler(compiler.DDLCompiler): def get_column_default_string(self, column): if (isinstance(column.server_default, schema.DefaultClause) and - isinstance(column.server_default.arg, util.string_type)): + isinstance(column.server_default.arg, util.string_types)): if isinstance(column.type, (sqltypes.Integer, sqltypes.Numeric)): return self.sql_compiler.process(text(column.server_default.arg)) diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py index c5b86b887..d463b379d 100644 --- a/lib/sqlalchemy/dialects/mssql/base.py +++ b/lib/sqlalchemy/dialects/mssql/base.py @@ -295,7 +295,7 @@ class _MSDate(sqltypes.Date): def process(value): if isinstance(value, datetime.datetime): return value.date() - elif isinstance(value, util.string_type): + elif isinstance(value, util.string_types): return datetime.date(*[ int(x or 0) for x in self._reg.match(value).groups() @@ -328,7 +328,7 @@ class TIME(sqltypes.TIME): def process(value): if isinstance(value, datetime.datetime): return value.time() - elif isinstance(value, util.string_type): + elif isinstance(value, util.string_types): return datetime.time(*[ int(x or 0) for x in self._reg.match(value).groups()]) @@ -1002,7 +1002,7 @@ class MSDDLCompiler(compiler.DDLCompiler): # handle other included columns if index.kwargs.get("mssql_include"): inclusions = [index.table.c[col] - if isinstance(col, util.string_type) else col + if isinstance(col, util.string_types) else col for col in index.kwargs["mssql_include"]] text += " INCLUDE (%s)" \ diff --git a/lib/sqlalchemy/dialects/mssql/information_schema.py b/lib/sqlalchemy/dialects/mssql/information_schema.py index 61403271f..a7628f213 100644 --- a/lib/sqlalchemy/dialects/mssql/information_schema.py +++ b/lib/sqlalchemy/dialects/mssql/information_schema.py @@ -9,6 +9,7 @@ from ... import Table, MetaData, Column from ...types import String, Unicode, Integer, TypeDecorator from ... import cast +from ... import util ischema = MetaData() @@ -17,10 +18,8 @@ class CoerceUnicode(TypeDecorator): impl = Unicode def process_bind_param(self, value, dialect): -# start Py2K -# if isinstance(value, str): -# value = value.decode(dialect.encoding) -# end Py2K + if util.py2k and isinstance(value, util.binary_type): + value = value.decode(dialect.encoding) return value def bind_expression(self, bindvalue): diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index c0497b14f..1857c9a46 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -1171,7 +1171,7 @@ class SET(_StringType): super_convert = super(SET, self).bind_processor(dialect) def process(value): - if value is None or isinstance(value, (int, str)): + if value is None or isinstance(value, util.int_types + util.string_types): pass else: if None in value: @@ -1352,7 +1352,7 @@ class MySQLCompiler(compiler.SQLCompiler): of a SELECT. """ - if isinstance(select._distinct, str): + if isinstance(select._distinct, util.string_types): return select._distinct.upper() + " " elif select._distinct: return "DISTINCT " @@ -1494,7 +1494,7 @@ class MySQLDDLCompiler(compiler.DDLCompiler): k[len(self.dialect.name) + 1:].upper(), v ) - for k, v in list(table.kwargs.items()) + for k, v in table.kwargs.items() if k.startswith('%s_' % self.dialect.name) ) @@ -2485,7 +2485,7 @@ class MySQLTableDefinitionParser(object): for nope in ('auto_increment', 'data directory', 'index directory'): options.pop(nope, None) - for opt, val in list(options.items()): + for opt, val in options.items(): state.table_options['%s_%s' % (self.dialect.name, opt)] = val def _parse_column(self, line, state): @@ -2626,11 +2626,11 @@ class MySQLTableDefinitionParser(object): _final = self.preparer.final_quote - quotes = dict(list(zip(('iq', 'fq', 'esc_fq'), + quotes = dict(zip(('iq', 'fq', 'esc_fq'), [re.escape(s) for s in (self.preparer.initial_quote, _final, - self.preparer._escape_identifier(_final))]))) + self.preparer._escape_identifier(_final))])) self._pr_name = _pr_compile( r'^CREATE (?:\w+ +)?TABLE +' @@ -2802,12 +2802,8 @@ class _DecodingRowProxy(object): item = self.rowproxy[index] if isinstance(item, _array): item = item.tostring() -# start Py2K -# if self.charset and isinstance(item, str): -# end Py2K -# start Py3K - if self.charset and isinstance(item, bytes): -# end Py3K + + if self.charset and isinstance(item, util.binary_type): return item.decode(self.charset) else: return item @@ -2816,12 +2812,7 @@ class _DecodingRowProxy(object): item = getattr(self.rowproxy, attr) if isinstance(item, _array): item = item.tostring() -# start Py2K -# if self.charset and isinstance(item, str): -# end Py2K -# start Py3K - if self.charset and isinstance(item, bytes): -# end Py3K + if self.charset and isinstance(item, util.binary_type): return item.decode(self.charset) else: return item diff --git a/lib/sqlalchemy/dialects/mysql/cymysql.py b/lib/sqlalchemy/dialects/mysql/cymysql.py index 6fcbc2307..deb2de449 100644 --- a/lib/sqlalchemy/dialects/mysql/cymysql.py +++ b/lib/sqlalchemy/dialects/mysql/cymysql.py @@ -25,16 +25,9 @@ class _cymysqlBIT(BIT): def process(value): if value is not None: -# start Py2K -# v = 0L -# for i in map(ord, value): -# v = v << 8 | i -# end Py2K -# start Py3K v = 0 - for i in value: + for i in util.iterbytes(value): v = v << 8 | i -# end Py3K return v return value return process diff --git a/lib/sqlalchemy/dialects/mysql/oursql.py b/lib/sqlalchemy/dialects/mysql/oursql.py index b97afe933..77370f91d 100644 --- a/lib/sqlalchemy/dialects/mysql/oursql.py +++ b/lib/sqlalchemy/dialects/mysql/oursql.py @@ -55,10 +55,10 @@ class MySQLExecutionContext_oursql(MySQLExecutionContext): class MySQLDialect_oursql(MySQLDialect): driver = 'oursql' -# start Py2K -# supports_unicode_binds = True -# supports_unicode_statements = True -# end Py2K + + if util.py2k: + supports_unicode_binds = True + supports_unicode_statements = True supports_native_decimal = True @@ -90,13 +90,11 @@ class MySQLDialect_oursql(MySQLDialect): connection.cursor().execute('BEGIN', plain_query=True) def _xa_query(self, connection, query, xid): -# start Py2K -# arg = connection.connection._escape_string(xid) -# end Py2K -# start Py3K - charset = self._connection_charset - arg = connection.connection._escape_string(xid.encode(charset)).decode(charset) -# end Py3K + if util.py2k: + arg = connection.connection._escape_string(xid) + else: + charset = self._connection_charset + arg = connection.connection._escape_string(xid.encode(charset)).decode(charset) arg = "'%s'" % arg connection.execution_options(_oursql_plain_query=True).execute(query % arg) diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 9eb3d6128..dbc1ff820 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -3,7 +3,7 @@ # # This module is part of SQLAlchemy and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php - +from __future__ import with_statement """Defines :class:`.Connection` and :class:`.Engine`. @@ -734,7 +734,7 @@ class Connection(Connectable): distilled_params = _distill_params(multiparams, params) if distilled_params: - keys = list(distilled_params[0].keys()) + keys = list(distilled_params[0]) else: keys = [] @@ -1045,7 +1045,7 @@ class Connection(Connectable): Compiled: _execute_compiled, schema.SchemaItem: _execute_default, schema.DDLElement: _execute_ddl, - str: _execute_text + util.string_types[0]: _execute_text } def default_schema_name(self): diff --git a/lib/sqlalchemy/engine/ddl.py b/lib/sqlalchemy/engine/ddl.py index 56f475e30..6daa9be6b 100644 --- a/lib/sqlalchemy/engine/ddl.py +++ b/lib/sqlalchemy/engine/ddl.py @@ -55,7 +55,7 @@ class SchemaGenerator(DDLBase): tables = list(metadata.tables.values()) collection = [t for t in sql_util.sort_tables(tables) if self._can_create_table(t)] - seq_coll = [s for s in list(metadata._sequences.values()) + seq_coll = [s for s in metadata._sequences.values() if s.column is None and self._can_create_sequence(s)] metadata.dispatch.before_create(metadata, self.connection, @@ -130,7 +130,7 @@ class SchemaDropper(DDLBase): seq_coll = [ s - for s in list(metadata._sequences.values()) + for s in metadata._sequences.values() if s.column is None and self._can_drop_sequence(s) ] diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 9dda6d81e..e52aac427 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -57,18 +57,16 @@ class DefaultDialect(interfaces.Dialect): # *not* the FLOAT type however. supports_native_decimal = False -# start Py3K - supports_unicode_statements = True - supports_unicode_binds = True - returns_unicode_strings = True - description_encoding = None -# end Py3K -# start Py2K -# supports_unicode_statements = False -# supports_unicode_binds = False -# returns_unicode_strings = False -# description_encoding = 'use_encoding' -# end Py2K + if util.py3k: + supports_unicode_statements = True + supports_unicode_binds = True + returns_unicode_strings = True + description_encoding = None + else: + supports_unicode_statements = False + supports_unicode_binds = False + returns_unicode_strings = False + description_encoding = 'use_encoding' name = 'default' @@ -202,15 +200,10 @@ class DefaultDialect(interfaces.Dialect): return None def _check_unicode_returns(self, connection): -# start Py2K -# if self.supports_unicode_statements: -# cast_to = unicode -# else: -# cast_to = str -# end Py2K -# start Py3K - cast_to = str -# end Py3K + if util.py2k and not self.supports_unicode_statements: + cast_to = util.binary_type + else: + cast_to = util.text_type def check_unicode(formatstr, type_): cursor = connection.connection.cursor() @@ -219,8 +212,8 @@ class DefaultDialect(interfaces.Dialect): cursor.execute( cast_to( expression.select( - [expression.cast( - expression.literal_column( + [expression.cast( + expression.literal_column( "'test %s returns'" % formatstr), type_) ]).compile(dialect=self) @@ -228,7 +221,7 @@ class DefaultDialect(interfaces.Dialect): ) row = cursor.fetchone() - return isinstance(row[0], str) + return isinstance(row[0], util.string_types) except self.dbapi.Error as de: util.warn("Exception attempting to " "detect unicode returns: %r" % de) @@ -375,10 +368,10 @@ class DefaultExecutionContext(interfaces.ExecutionContext): self.execution_options.update(connection._execution_options) if not dialect.supports_unicode_statements: - self.unicode_statement = str(compiled) + self.unicode_statement = util.text_type(compiled) self.statement = dialect._encoder(self.unicode_statement)[0] else: - self.statement = self.unicode_statement = str(compiled) + self.statement = self.unicode_statement = util.text_type(compiled) self.cursor = self.create_cursor() self.compiled_parameters = [] @@ -416,7 +409,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): self.result_map = compiled.result_map - self.unicode_statement = str(compiled) + self.unicode_statement = util.text_type(compiled) if not dialect.supports_unicode_statements: self.statement = self.unicode_statement.encode( self.dialect.encoding) @@ -521,7 +514,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): self.executemany = len(parameters) > 1 if not dialect.supports_unicode_statements and \ - isinstance(statement, str): + isinstance(statement, util.text_type): self.unicode_statement = statement self.statement = dialect._encoder(statement)[0] else: @@ -575,8 +568,8 @@ class DefaultExecutionContext(interfaces.ExecutionContext): """ conn = self.root_connection - if isinstance(stmt, str) and \ - not self.dialect.supports_unicode_statements: + if isinstance(stmt, util.text_type) and \ + not self.dialect.supports_unicode_statements: stmt = self.dialect._encoder(stmt)[0] if self.dialect.positional: diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index de054b0fd..316161fdf 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -200,10 +200,11 @@ def _remove_dispatcher(cls): if not _registrars[k]: del _registrars[k] - -class Events(object, metaclass=_EventMeta): +class Events(object): #util.with_metaclass(_EventMeta, object)): """Define event listening functions for a particular target type.""" + __metaclass__ = _EventMeta + @classmethod def _accept_with(cls, target): # Mapper, ClassManager, Session override this to diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 030c400a7..b53eb8887 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -1154,24 +1154,15 @@ class Column(SchemaItem, expression.ColumnClause): nullable=self.nullable, quote=self.quote, _proxies=[self], *fk) - except TypeError as e: -# start Py3K - raise TypeError( - "Could not create a copy of this %r object. " - "Ensure the class includes a _constructor() " - "attribute or method which accepts the " - "standard Column constructor arguments, or " - "references the Column class itself." % self.__class__) from e -# end Py3K -# start Py2K -# raise TypeError( -# "Could not create a copy of this %r object. " -# "Ensure the class includes a _constructor() " -# "attribute or method which accepts the " -# "standard Column constructor arguments, or " -# "references the Column class itself. " -# "Original error: %s" % (self.__class__, e)) -# end Py2K + except TypeError: + util.raise_from_cause( + TypeError( + "Could not create a copy of this %r object. " + "Ensure the class includes a _constructor() " + "attribute or method which accepts the " + "standard Column constructor arguments, or " + "references the Column class itself." % self.__class__) + ) c.table = selectable selectable._columns.add(c) diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index 2ff7750ca..6efce504a 100644 --- a/lib/sqlalchemy/sql/visitors.py +++ b/lib/sqlalchemy/sql/visitors.py @@ -87,7 +87,7 @@ def _generate_dispatch(cls): cls._compiler_dispatch = _compiler_dispatch -class Visitable(object, metaclass=VisitableType): +class Visitable(util.with_metaclass(VisitableType, object)): """Base class for visitable objects, applies the ``VisitableType`` metaclass. diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 2fcfabefd..9e562402d 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -5,9 +5,10 @@ # the MIT License: http://www.opensource.org/licenses/mit-license.php from .compat import callable, cmp, reduce, \ - threading, py3k, py3k_warning, jython, pypy, cpython, win32, set_types, \ + threading, py3k, py2k, jython, pypy, cpython, win32, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ - raise_from_cause, text_type, string_type, binary_type, quote_plus + raise_from_cause, text_type, string_types, int_types, binary_type, \ + quote_plus, with_metaclass from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ Properties, OrderedProperties, ImmutableProperties, OrderedDict, \ diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index d00e3ab23..5042d505b 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -14,29 +14,13 @@ except ImportError: import dummy_threading as threading py32 = sys.version_info >= (3, 2) -py3k_warning = getattr(sys, 'py3kwarning', False) or sys.version_info >= (3, 0) py3k = sys.version_info >= (3, 0) +py2k = not py3k jython = sys.platform.startswith('java') pypy = hasattr(sys, 'pypy_version_info') win32 = sys.platform.startswith('win') cpython = not pypy and not jython # TODO: something better for this ? -if py3k: - set_types = set -else: - # 2.6 deprecates sets.Set, but we still need to be able to detect them - # in user code and as return values from DB-APIs - ignore = ('ignore', None, DeprecationWarning, None, 0) - import warnings - try: - warnings.filters.insert(0, ignore) - except Exception: - import sets - else: - import sets - warnings.filters.remove(ignore) - - set_types = set, sets.Set if sys.version_info < (2, 6): def next(iter): @@ -51,23 +35,28 @@ else: except ImportError: import pickle -from urllib.parse import parse_qsl if py3k: from inspect import getfullargspec as inspect_getfullargspec - from urllib.parse import quote_plus, unquote_plus + from urllib.parse import quote_plus, unquote_plus, parse_qsl string_types = str, binary_type = bytes text_type = str + int_types = int, + iterbytes = iter else: from inspect import getargspec as inspect_getfullargspec from urllib import quote_plus, unquote_plus + from urlparse import parse_qsl string_types = basestring, binary_type = str text_type = unicode + int_types = int, long + def iterbytes(buf): + return (ord(byte) for byte in buf) -if py3k_warning: +if py3k: # they're bringing it back in 3.2. brilliant ! def callable(fn): return hasattr(fn, '__call__') @@ -149,19 +138,25 @@ if py3k: raise value.with_traceback(tb) raise value - def raise_from_cause(exception, exc_info): + def raise_from_cause(exception, exc_info=None): + if exc_info is None: + exc_info = sys.exc_info() exc_type, exc_value, exc_tb = exc_info reraise(type(exception), exception, tb=exc_tb, cause=exc_value) else: exec("def reraise(tp, value, tb=None, cause=None):\n" " raise tp, value, tb\n") - def raise_from_cause(exception, exc_info): + def raise_from_cause(exception, exc_info=None): # not as nice as that of Py3K, but at least preserves # the code line where the issue occurred + if exc_info is None: + exc_info = sys.exc_info() exc_type, exc_value, exc_tb = exc_info reraise(type(exception), exception, tb=exc_tb) +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" - + return meta("MetaBase", bases, {}) diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 26dd97549..f65803dc6 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -15,8 +15,8 @@ import re import sys import types import warnings -from .compat import set_types, threading, \ - callable, inspect_getfullargspec +from .compat import threading, \ + callable, inspect_getfullargspec, py3k from functools import update_wrapper from .. import exc import hashlib @@ -265,23 +265,21 @@ def format_argspec_plus(fn, grouped=True): else: self_arg = None -# start Py3K - apply_pos = inspect.formatargspec(spec[0], spec[1], - spec[2], None, spec[4]) - num_defaults = 0 - if spec[3]: - num_defaults += len(spec[3]) - if spec[4]: - num_defaults += len(spec[4]) - name_args = spec[0] + spec[4] -# end Py3K -# start Py2K -# apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2]) -# num_defaults = 0 -# if spec[3]: -# num_defaults += len(spec[3]) -# name_args = spec[0] -# end Py2K + if py3k: + apply_pos = inspect.formatargspec(spec[0], spec[1], + spec[2], None, spec[4]) + num_defaults = 0 + if spec[3]: + num_defaults += len(spec[3]) + if spec[4]: + num_defaults += len(spec[4]) + name_args = spec[0] + spec[4] + else: + apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2]) + num_defaults = 0 + if spec[3]: + num_defaults += len(spec[3]) + name_args = spec[0] if num_defaults: defaulted_vals = name_args[0 - num_defaults:] @@ -842,7 +840,7 @@ def duck_type_collection(specimen, default=None): if hasattr(specimen, '__emulates__'): # canonicalize set vs sets.Set to a standard: the builtin set if (specimen.__emulates__ is not None and - issubclass(specimen.__emulates__, set_types)): + issubclass(specimen.__emulates__, set)): return set else: return specimen.__emulates__ @@ -850,7 +848,7 @@ def duck_type_collection(specimen, default=None): isa = isinstance(specimen, type) and issubclass or isinstance if isa(specimen, list): return list - elif isa(specimen, set_types): + elif isa(specimen, set): return set elif isa(specimen, dict): return dict -- cgit v1.2.1 From 32e0a1624bf1ae3cb6309062adefd2f5c89b541c Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 27 Apr 2013 20:58:13 -0400 Subject: import of "sqlalchemy" and "sqlalchemy.orm" works. --- lib/sqlalchemy/engine/strategies.py | 19 ++++++------------- lib/sqlalchemy/engine/url.py | 13 +++++-------- lib/sqlalchemy/event.py | 7 +++---- lib/sqlalchemy/orm/collections.py | 6 +----- lib/sqlalchemy/orm/interfaces.py | 1 + lib/sqlalchemy/orm/mapper.py | 5 +++-- lib/sqlalchemy/sql/compiler.py | 16 +++------------- lib/sqlalchemy/sql/functions.py | 17 +++++++++-------- lib/sqlalchemy/sql/visitors.py | 8 +++----- 9 files changed, 34 insertions(+), 58 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/strategies.py b/lib/sqlalchemy/engine/strategies.py index bed14c671..c65986ca2 100644 --- a/lib/sqlalchemy/engine/strategies.py +++ b/lib/sqlalchemy/engine/strategies.py @@ -80,19 +80,12 @@ class DefaultEngineStrategy(EngineStrategy): return dialect.connect(*cargs, **cparams) except Exception as e: invalidated = dialect.is_disconnect(e, None, None) -# start Py3K - raise exc.DBAPIError.instance(None, None, - e, dialect.dbapi.Error, - connection_invalidated=invalidated - ) from e -# end Py3K -# start Py2K -# import sys -# raise exc.DBAPIError.instance( -# None, None, e, dialect.dbapi.Error, -# connection_invalidated=invalidated -# ), None, sys.exc_info()[2] -# end Py2K + util.raise_from_cause( + exc.DBAPIError.instance(None, None, + e, dialect.dbapi.Error, + connection_invalidated=invalidated + ) + ) creator = kwargs.pop('creator', connect) diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index 45768c5dc..b7d56374e 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -14,7 +14,6 @@ be used directly and is also accepted directly by ``create_engine()``. """ import re -import urllib.request, urllib.parse, urllib.error from .. import exc, util from . import Dialect @@ -67,7 +66,7 @@ class URL(object): if self.username is not None: s += self.username if self.password is not None: - s += ':' + urllib.parse.quote_plus(self.password) + s += ':' + util.quote_plus(self.password) s += "@" if self.host is not None: s += self.host @@ -76,7 +75,7 @@ class URL(object): if self.database is not None: s += '/' + self.database if self.query: - keys = list(self.query.keys()) + keys = list(self.query) keys.sort() s += '?' + "&".join("%s=%s" % (k, self.query[k]) for k in keys) return s @@ -177,17 +176,15 @@ def _parse_rfc1738_args(name): tokens = components['database'].split('?', 2) components['database'] = tokens[0] query = (len(tokens) > 1 and dict(util.parse_qsl(tokens[1]))) or None -# start Py2K -# if query is not None: -# query = dict((k.encode('ascii'), query[k]) for k in query) -# end Py2K + if util.py2k and query is not None: + query = dict((k.encode('ascii'), query[k]) for k in query) else: query = None components['query'] = query if components['password'] is not None: components['password'] = \ - urllib.parse.unquote_plus(components['password']) + util.unquote_plus(components['password']) name = components.pop('name') return URL(name, **components) diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index 316161fdf..79d024f9b 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -171,7 +171,8 @@ class _EventMeta(type): associated _Dispatch classes.""" def __init__(cls, classname, bases, dict_): - _create_dispatcher_class(cls, classname, bases, dict_) + if classname != 'MetaBase': + _create_dispatcher_class(cls, classname, bases, dict_) return type.__init__(cls, classname, bases, dict_) @@ -200,11 +201,9 @@ def _remove_dispatcher(cls): if not _registrars[k]: del _registrars[k] -class Events(object): #util.with_metaclass(_EventMeta, object)): +class Events(util.with_metaclass(_EventMeta, object)): """Define event listening functions for a particular target type.""" - __metaclass__ = _EventMeta - @classmethod def _accept_with(cls, target): # Mapper, ClassManager, Session override this to diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index 0a11b83c6..c2a2c23f0 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -1272,11 +1272,7 @@ def _dict_decorators(): l.pop('Unspecified') return l -if util.py3k_warning: - _set_binop_bases = (set, frozenset) -else: - import sets - _set_binop_bases = (set, frozenset, sets.BaseSet) +_set_binop_bases = (set, frozenset) def _set_binops_check_strict(self, obj): diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index f14c8ca47..a81404401 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -16,6 +16,7 @@ classes within should be considered mostly private. """ +from __future__ import absolute_import from .. import exc as sa_exc, util, inspect from ..sql import operators diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 91c678547..645bf86e7 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -13,6 +13,7 @@ This is a semi-private module; the main configurational API of the ORM is available in :class:`~sqlalchemy.orm.`. """ +from __future__ import absolute_import import types import weakref @@ -26,8 +27,8 @@ from . import instrumentation, attributes, \ from .interfaces import MapperProperty, _InspectionAttr, _MappedAttribute from .util import _INSTRUMENTOR, _class_to_mapper, \ - _state_mapper, class_mapper, \ - PathRegistry + _state_mapper, class_mapper, \ + PathRegistry import sys properties = util.importlater("sqlalchemy.orm", "properties") descriptor_props = util.importlater("sqlalchemy.orm", "descriptor_props") diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index e5a2da366..b3f74ceef 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1869,22 +1869,12 @@ class DDLCompiler(engine.Compiled): if column.primary_key: first_pk = True except exc.CompileError as ce: -# start Py3K - raise exc.CompileError("(in table '%s', column '%s'): %s" - % ( + util.raise_from_cause( + exc.CompileError("(in table '%s', column '%s'): %s" % ( table.description, column.name, ce.args[0] - )) from ce -# end Py3K -# start Py2K -# raise exc.CompileError("(in table '%s', column '%s'): %s" -# % ( -# table.description, -# column.name, -# ce.args[0] -# )), None, sys.exc_info()[2] -# end Py2K + ))) const = self.create_table_constraints(table) if const: diff --git a/lib/sqlalchemy/sql/functions.py b/lib/sqlalchemy/sql/functions.py index a2b7ac628..244505bed 100644 --- a/lib/sqlalchemy/sql/functions.py +++ b/lib/sqlalchemy/sql/functions.py @@ -31,17 +31,18 @@ def register_function(identifier, fn, package="_default"): class _GenericMeta(VisitableType): def __init__(cls, clsname, bases, clsdict): - cls.name = name = clsdict.get('name', clsname) - cls.identifier = identifier = clsdict.get('identifier', name) - package = clsdict.pop('package', '_default') - # legacy - if '__return_type__' in clsdict: - cls.type = clsdict['__return_type__'] - register_function(identifier, cls, package) + if clsname != 'MetaBase': + cls.name = name = clsdict.get('name', clsname) + cls.identifier = identifier = clsdict.get('identifier', name) + package = clsdict.pop('package', '_default') + # legacy + if '__return_type__' in clsdict: + cls.type = clsdict['__return_type__'] + register_function(identifier, cls, package) super(_GenericMeta, cls).__init__(clsname, bases, clsdict) -class GenericFunction(Function, metaclass=_GenericMeta): +class GenericFunction(util.with_metaclass(_GenericMeta, Function)): """Define a 'generic' function. A generic function is a pre-established :class:`.Function` diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index 6efce504a..4d2948462 100644 --- a/lib/sqlalchemy/sql/visitors.py +++ b/lib/sqlalchemy/sql/visitors.py @@ -49,11 +49,9 @@ class VisitableType(type): Classes having no __visit_name__ attribute will remain unaffected. """ def __init__(cls, clsname, bases, clsdict): - if cls.__name__ == 'Visitable' or not hasattr(cls, '__visit_name__'): - super(VisitableType, cls).__init__(clsname, bases, clsdict) - return - - _generate_dispatch(cls) + if clsname not in ('MetaBase', 'Visitable') and \ + hasattr(cls, '__visit_name__'): + _generate_dispatch(cls) super(VisitableType, cls).__init__(clsname, bases, clsdict) -- cgit v1.2.1 From 1c647a879cbec0a301eb2cb021a30553abdced54 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 27 Apr 2013 21:01:54 -0400 Subject: cleanup --- lib/sqlalchemy/util/compat.py | 66 ++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 45 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 5042d505b..bdeb69d1e 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -22,11 +22,8 @@ win32 = sys.platform.startswith('win') cpython = not pypy and not jython # TODO: something better for this ? -if sys.version_info < (2, 6): - def next(iter): - return iter.__next__() -else: - next = next +next = next + if py3k: import pickle else: @@ -35,8 +32,6 @@ else: except ImportError: import pickle - - if py3k: from inspect import getfullargspec as inspect_getfullargspec from urllib.parse import quote_plus, unquote_plus, parse_qsl @@ -45,6 +40,21 @@ if py3k: text_type = str int_types = int, iterbytes = iter + + def b(s): + return s.encode("latin-1") + + if py32: + callable = callable + else: + def callable(fn): + return hasattr(fn, '__call__') + + def cmp(a, b): + return (a > b) - (a < b) + + from functools import reduce + else: from inspect import getargspec as inspect_getfullargspec from urllib import quote_plus, unquote_plus @@ -56,31 +66,13 @@ else: def iterbytes(buf): return (ord(byte) for byte in buf) -if py3k: - # they're bringing it back in 3.2. brilliant ! - def callable(fn): - return hasattr(fn, '__call__') - - def cmp(a, b): - return (a > b) - (a < b) + def b(s): + return s - from functools import reduce -else: callable = callable cmp = cmp reduce = reduce -try: - from collections import namedtuple -except ImportError: - def namedtuple(typename, fieldnames): - def __new__(cls, *values): - tup = tuple.__new__(cls, values) - for i, fname in enumerate(fieldnames): - setattr(tup, fname, tup[i]) - return tup - tuptype = type(typename, (tuple, ), {'__new__': __new__}) - return tuptype try: from weakref import WeakSet @@ -110,24 +102,8 @@ if win32 or jython: else: time_func = time.time - -if sys.version_info >= (2, 6): - from operator import attrgetter as dottedgetter -else: - def dottedgetter(attr): - def g(obj): - for name in attr.split("."): - obj = getattr(obj, name) - return obj - return g - -# Adapted from six.py -if py3k: - def b(s): - return s.encode("latin-1") -else: - def b(s): - return s +from collections import namedtuple +from operator import attrgetter as dottedgetter if py3k: -- cgit v1.2.1 From d37431d7a5f7c930527ad9418756d102adebffdb Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 28 Apr 2013 12:55:22 -0400 Subject: result --- lib/sqlalchemy/engine/result.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py index 0bd501423..65ce3b742 100644 --- a/lib/sqlalchemy/engine/result.py +++ b/lib/sqlalchemy/engine/result.py @@ -274,7 +274,7 @@ class ResultMetaData(object): def _key_fallback(self, key, raiseerr=True): map = self._keymap result = None - if isinstance(key, str): + if isinstance(key, util.string_types): result = map.get(key if self.case_sensitive else key.lower()) # fallback for targeting a ColumnElement to a textual expression # this is a rare use case which only occurs when matching text() @@ -329,7 +329,7 @@ class ResultMetaData(object): '_pickled_keymap': dict( (key, index) for key, (processor, obj, index) in self._keymap.items() - if isinstance(key, (str, int)) + if isinstance(key, util.string_types + util.int_types) ), 'keys': self.keys, "case_sensitive": self.case_sensitive, -- cgit v1.2.1 From 18370ac032a84da539c54640a425c0fca7613dc9 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 28 Apr 2013 14:08:28 -0400 Subject: - endless isinstance(x, str)s.... --- lib/sqlalchemy/schema.py | 66 +++++++++--------- lib/sqlalchemy/sql/compiler.py | 22 +++--- lib/sqlalchemy/sql/expression.py | 95 +++++++++++++------------- lib/sqlalchemy/sql/operators.py | 19 +++--- lib/sqlalchemy/testing/assertions.py | 24 +++---- lib/sqlalchemy/testing/fixtures.py | 12 ++-- lib/sqlalchemy/testing/plugin/noseplugin.py | 10 ++- lib/sqlalchemy/testing/warnings.py | 4 +- lib/sqlalchemy/util/__init__.py | 2 +- lib/sqlalchemy/util/compat.py | 40 +++++++++++ lib/sqlalchemy/util/langhelpers.py | 101 +++++++++++++--------------- 11 files changed, 212 insertions(+), 183 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index b53eb8887..a8705beb4 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -679,11 +679,11 @@ class Table(SchemaItem, expression.TableClause): # skip indexes that would be generated # by the 'index' flag on Column if len(index.columns) == 1 and \ - list(index.columns)[0].index: + list(index.columns)[0].index: continue Index(index.name, unique=index.unique, - *[table.c[col] for col in list(index.columns.keys())], + *[table.c[col] for col in index.columns.keys()], **index.kwargs) table.dispatch._update(self.dispatch) return table @@ -898,7 +898,7 @@ class Column(SchemaItem, expression.ColumnClause): type_ = kwargs.pop('type_', None) args = list(args) if args: - if isinstance(args[0], str): + if isinstance(args[0], util.string_types): if name is not None: raise exc.ArgumentError( "May not pass name positionally and as a keyword.") @@ -944,12 +944,7 @@ class Column(SchemaItem, expression.ColumnClause): args.append(self.default) else: if getattr(self.type, '_warn_on_bytestring', False): -# start Py3K - if isinstance(self.default, bytes): -# end Py3K -# start Py2K -# if isinstance(self.default, str): -# end Py2K + if isinstance(self.default, util.binary_type): util.warn("Unicode column received non-unicode " "default value.") args.append(ColumnDefault(self.default)) @@ -984,7 +979,7 @@ class Column(SchemaItem, expression.ColumnClause): if kwargs: raise exc.ArgumentError( - "Unknown arguments passed to Column: " + repr(list(kwargs.keys()))) + "Unknown arguments passed to Column: " + repr(list(kwargs))) def __str__(self): if self.name is None: @@ -1070,7 +1065,7 @@ class Column(SchemaItem, expression.ColumnClause): self.table = table if self.index: - if isinstance(self.index, str): + if isinstance(self.index, util.string_types): raise exc.ArgumentError( "The 'index' keyword argument on Column is boolean only. " "To create indexes with a specific name, create an " @@ -1078,7 +1073,7 @@ class Column(SchemaItem, expression.ColumnClause): Index(expression._truncated_label('ix_%s' % self._label), self, unique=self.unique) elif self.unique: - if isinstance(self.unique, str): + if isinstance(self.unique, util.string_types): raise exc.ArgumentError( "The 'unique' keyword argument on Column is boolean " "only. To create unique constraints or indexes with a " @@ -1338,7 +1333,7 @@ class ForeignKey(SchemaItem): if schema: return schema + "." + self.column.table.name + \ "." + self.column.key - elif isinstance(self._colspec, str): + elif isinstance(self._colspec, util.string_types): return self._colspec elif hasattr(self._colspec, '__clause_element__'): _column = self._colspec.__clause_element__() @@ -1383,7 +1378,7 @@ class ForeignKey(SchemaItem): """ # ForeignKey inits its remote column as late as possible, so tables # can be defined without dependencies - if isinstance(self._colspec, str): + if isinstance(self._colspec, util.string_types): # locate the parent table this foreign key is attached to. we # use the "original" column which our parent column represents # (its a list of columns/other ColumnElements if the parent @@ -1650,8 +1645,7 @@ class ColumnDefault(DefaultGenerator): defaulted = argspec[3] is not None and len(argspec[3]) or 0 positionals = len(argspec[0]) - defaulted -# start Py3K -# end Py3K + # Py3K compat - no unbound methods if inspect.ismethod(inspectable) or inspect.isclass(fn): positionals -= 1 @@ -1913,7 +1907,7 @@ class DefaultClause(FetchedValue): has_argument = True def __init__(self, arg, for_update=False, _reflected=False): - util.assert_arg_type(arg, (str, + util.assert_arg_type(arg, (util.string_types[0], expression.ClauseElement, expression.TextClause), 'arg') super(DefaultClause, self).__init__(for_update) @@ -2023,7 +2017,7 @@ class ColumnCollectionMixin(object): def _set_parent(self, table): for col in self._pending_colargs: - if isinstance(col, str): + if isinstance(col, util.string_types): col = table.c[col] self.columns.add(col) @@ -2060,7 +2054,7 @@ class ColumnCollectionConstraint(ColumnCollectionMixin, Constraint): def copy(self, **kw): c = self.__class__(name=self.name, deferrable=self.deferrable, - initially=self.initially, *list(self.columns.keys())) + initially=self.initially, *self.columns.keys()) c.dispatch._update(self.dispatch) return c @@ -2241,7 +2235,7 @@ class ForeignKeyConstraint(Constraint): self._set_parent_with_dispatch(table) elif columns and \ isinstance(columns[0], Column) and \ - columns[0].table is not None: + columns[0].table is not None: self._set_parent_with_dispatch(columns[0].table) @property @@ -2250,7 +2244,7 @@ class ForeignKeyConstraint(Constraint): @property def columns(self): - return list(self._elements.keys()) + return list(self._elements) @property def elements(self): @@ -2262,7 +2256,7 @@ class ForeignKeyConstraint(Constraint): for col, fk in self._elements.items(): # string-specified column names now get # resolved to Column objects - if isinstance(col, str): + if isinstance(col, util.string_types): try: col = table.c[col] except KeyError: @@ -2272,7 +2266,7 @@ class ForeignKeyConstraint(Constraint): "named '%s' is present." % (table.description, col)) if not hasattr(fk, 'parent') or \ - fk.parent is not col: + fk.parent is not col: fk._set_parent_with_dispatch(col) if self.use_alter: @@ -2287,8 +2281,8 @@ class ForeignKeyConstraint(Constraint): def copy(self, schema=None, **kw): fkc = ForeignKeyConstraint( - [x.parent.key for x in list(self._elements.values())], - [x._get_colspec(schema=schema) for x in list(self._elements.values())], + [x.parent.key for x in self._elements.values()], + [x._get_colspec(schema=schema) for x in self._elements.values()], name=self.name, onupdate=self.onupdate, ondelete=self.ondelete, @@ -2563,7 +2557,7 @@ class MetaData(SchemaItem): return 'MetaData(bind=%r)' % self.bind def __contains__(self, table_or_key): - if not isinstance(table_or_key, str): + if not isinstance(table_or_key, util.string_types): table_or_key = table_or_key.key return table_or_key in self.tables @@ -2578,7 +2572,7 @@ class MetaData(SchemaItem): dict.pop(self.tables, key, None) if self._schemas: self._schemas = set([t.schema - for t in list(self.tables.values()) + for t in self.tables.values() if t.schema is not None]) def __getstate__(self): @@ -2623,7 +2617,7 @@ class MetaData(SchemaItem): def _bind_to(self, bind): """Bind this MetaData to an Engine, Connection, string or URL.""" - if isinstance(bind, (str, url.URL)): + if isinstance(bind, util.string_types + (url.URL, )): from sqlalchemy import create_engine self._bind = create_engine(bind) else: @@ -2656,7 +2650,7 @@ class MetaData(SchemaItem): :meth:`.Inspector.sorted_tables` """ - return sqlutil.sort_tables(iter(self.tables.values())) + return sqlutil.sort_tables(self.tables.values()) def reflect(self, bind=None, schema=None, views=False, only=None): """Load all available table definitions from the database. @@ -2717,7 +2711,7 @@ class MetaData(SchemaItem): bind.dialect.get_view_names(conn, schema) ) - current = set(self.tables.keys()) + current = set(self.tables) if only is None: load = [name for name in available if name not in current] @@ -2839,7 +2833,7 @@ class ThreadLocalMetaData(MetaData): def _bind_to(self, bind): """Bind to a Connectable in the caller's thread.""" - if isinstance(bind, (str, url.URL)): + if isinstance(bind, util.string_types + (url.URL, )): try: self.context._engine = self.__engines[bind] except KeyError: @@ -3069,7 +3063,7 @@ class DDLElement(expression.Executable, _DDLCompiles): not self._should_execute_deprecated(None, target, bind, **kw): return False - if isinstance(self.dialect, str): + if isinstance(self.dialect, util.string_types): if self.dialect != bind.engine.name: return False elif isinstance(self.dialect, (tuple, list, set)): @@ -3084,7 +3078,7 @@ class DDLElement(expression.Executable, _DDLCompiles): def _should_execute_deprecated(self, event, target, bind, **kw): if self.on is None: return True - elif isinstance(self.on, str): + elif isinstance(self.on, util.string_types): return self.on == bind.engine.name elif isinstance(self.on, (tuple, list, set)): return bind.engine.name in self.on @@ -3099,7 +3093,7 @@ class DDLElement(expression.Executable, _DDLCompiles): def _check_ddl_on(self, on): if (on is not None and - (not isinstance(on, (str, tuple, list, set)) and + (not isinstance(on, util.string_types + (tuple, list, set)) and not util.callable(on))): raise exc.ArgumentError( "Expected the name of a database dialect, a tuple " @@ -3224,7 +3218,7 @@ class DDL(DDLElement): """ - if not isinstance(statement, str): + if not isinstance(statement, util.string_types): raise exc.ArgumentError( "Expected a string or unicode SQL statement, got '%r'" % statement) @@ -3256,7 +3250,7 @@ def _to_schema_column(element): def _to_schema_column_or_string(element): if hasattr(element, '__clause_element__'): element = element.__clause_element__() - if not isinstance(element, (str, expression.ColumnElement)): + if not isinstance(element, util.string_types + (expression.ColumnElement, )): msg = "Element %r is not a string name or column element" raise exc.ArgumentError(msg % element) return element diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index b3f74ceef..d51dd625a 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -83,9 +83,7 @@ OPERATORS = { operators.add: ' + ', operators.mul: ' * ', operators.sub: ' - ', -# start Py2K -# operators.div: ' / ', -# end Py2K + operators.div: ' / ', operators.mod: ' % ', operators.truediv: ' / ', operators.neg: '-', @@ -826,12 +824,12 @@ class SQLCompiler(engine.Compiled): of the DBAPI. """ - if isinstance(value, str): + if isinstance(value, util.string_types): value = value.replace("'", "''") return "'%s'" % value elif value is None: return "NULL" - elif isinstance(value, (float, int)): + elif isinstance(value, (float, ) + util.int_types): return repr(value) elif isinstance(value, decimal.Decimal): return str(value) @@ -1214,7 +1212,7 @@ class SQLCompiler(engine.Compiled): self.positiontup = self.cte_positional + self.positiontup cte_text = self.get_cte_preamble(self.ctes_recursive) + " " cte_text += ", \n".join( - [txt for txt in list(self.ctes.values())] + [txt for txt in self.ctes.values()] ) cte_text += "\n " return cte_text @@ -1325,7 +1323,7 @@ class SQLCompiler(engine.Compiled): dialect_hints = dict([ (table, hint_text) for (table, dialect), hint_text in - list(insert_stmt._hints.items()) + insert_stmt._hints.items() if dialect in ('*', self.dialect.name) ]) if insert_stmt.table in dialect_hints: @@ -1422,7 +1420,7 @@ class SQLCompiler(engine.Compiled): dialect_hints = dict([ (table, hint_text) for (table, dialect), hint_text in - list(update_stmt._hints.items()) + update_stmt._hints.items() if dialect in ('*', self.dialect.name) ]) if update_stmt.table in dialect_hints: @@ -1559,7 +1557,7 @@ class SQLCompiler(engine.Compiled): if extra_tables and stmt_parameters: normalized_params = dict( (sql._clause_element_as_expr(c), param) - for c, param in list(stmt_parameters.items()) + for c, param in stmt_parameters.items() ) assert self.isupdate affected_tables = set() @@ -1752,7 +1750,7 @@ class SQLCompiler(engine.Compiled): dialect_hints = dict([ (table, hint_text) for (table, dialect), hint_text in - list(delete_stmt._hints.items()) + delete_stmt._hints.items() if dialect in ('*', self.dialect.name) ]) if delete_stmt.table in dialect_hints: @@ -1870,11 +1868,11 @@ class DDLCompiler(engine.Compiled): first_pk = True except exc.CompileError as ce: util.raise_from_cause( - exc.CompileError("(in table '%s', column '%s'): %s" % ( + exc.CompileError(util.u("(in table '%s', column '%s'): %s" % ( table.description, column.name, ce.args[0] - ))) + )))) const = self.create_table_constraints(table) if const: diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 1ad6364d2..aff5512d3 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -26,7 +26,7 @@ to stay the same in future releases. """ - +from __future__ import unicode_literals import itertools import re from operator import attrgetter @@ -1375,7 +1375,7 @@ func = _FunctionGenerator() modifier = _FunctionGenerator(group=False) -class _truncated_label(str): +class _truncated_label(util.text_type): """A unicode subclass used to identify symbolic " "names that may require truncation.""" @@ -1395,13 +1395,13 @@ class _anonymous_label(_truncated_label): def __add__(self, other): return _anonymous_label( - str(self) + - str(other)) + util.text_type(self) + + util.text_type(other)) def __radd__(self, other): return _anonymous_label( - str(other) + - str(self)) + util.text_type(other) + + util.text_type(self)) def apply_map(self, map_): return self % map_ @@ -1422,7 +1422,7 @@ def _as_truncated(value): def _string_or_unprintable(element): - if isinstance(element, str): + if isinstance(element, util.string_types): return element else: try: @@ -1486,7 +1486,7 @@ def _labeled(element): def _column_as_key(element): - if isinstance(element, str): + if isinstance(element, util.string_types): return element if hasattr(element, '__clause_element__'): element = element.__clause_element__() @@ -1508,8 +1508,8 @@ def _literal_as_text(element): return element elif hasattr(element, '__clause_element__'): return element.__clause_element__() - elif isinstance(element, str): - return TextClause(str(element)) + elif isinstance(element, util.string_types): + return TextClause(util.text_type(element)) elif isinstance(element, (util.NoneType, bool)): return _const_expr(element) else: @@ -1583,8 +1583,8 @@ def _interpret_as_column_or_from(element): def _interpret_as_from(element): insp = inspection.inspect(element, raiseerr=False) if insp is None: - if isinstance(element, str): - return TextClause(str(element)) + if isinstance(element, util.string_types): + return TextClause(util.text_type(element)) elif hasattr(insp, "selectable"): return insp.selectable raise exc.ArgumentError("FROM expression expected") @@ -1914,12 +1914,10 @@ class ClauseElement(Visitable): return dialect.statement_compiler(dialect, self, **kw) def __str__(self): -# start Py3K - return str(self.compile()) -# end Py3K -# start Py2K -# return unicode(self.compile()).encode('ascii', 'backslashreplace') -# end Py2K + if util.py3k: + return str(self.compile()) + else: + return unicode(self.compile()).encode('ascii', 'backslashreplace') def __and__(self, other): return and_(self, other) @@ -1933,6 +1931,8 @@ class ClauseElement(Visitable): def __bool__(self): raise TypeError("Boolean value of this clause is not defined") + __nonzero__ = __bool__ + def _negate(self): if hasattr(self, 'negation_clause'): return self.negation_clause @@ -2508,7 +2508,7 @@ class ColumnCollection(util.OrderedProperties): def update(self, value): self._data.update(value) self._all_cols.clear() - self._all_cols.update(list(self._data.values())) + self._all_cols.update(self._data.values()) def extend(self, iter): self.update((c.key, c) for c in iter) @@ -2524,13 +2524,13 @@ class ColumnCollection(util.OrderedProperties): return and_(*l) def __contains__(self, other): - if not isinstance(other, str): + if not isinstance(other, util.string_types): raise exc.ArgumentError("__contains__ requires a string argument") return util.OrderedProperties.__contains__(self, other) def __setstate__(self, state): self.__dict__['_data'] = state['_data'] - self.__dict__['_all_cols'] = util.column_set(list(self._data.values())) + self.__dict__['_all_cols'] = util.column_set(self._data.values()) def contains_column(self, col): # this has to be done via set() membership @@ -3185,13 +3185,13 @@ class TextClause(Executable, ClauseElement): _hide_froms = [] def __init__( - self, - text='', - bind=None, - bindparams=None, - typemap=None, - autocommit=None, - ): + self, + text='', + bind=None, + bindparams=None, + typemap=None, + autocommit=None): + self._bind = bind self.bindparams = {} self.typemap = typemap @@ -3201,9 +3201,9 @@ class TextClause(Executable, ClauseElement): 'e)') self._execution_options = \ self._execution_options.union( - {'autocommit': autocommit}) + {'autocommit': autocommit}) if typemap is not None: - for key in list(typemap.keys()): + for key in typemap: typemap[key] = sqltypes.to_instance(typemap[key]) def repl(m): @@ -3237,7 +3237,7 @@ class TextClause(Executable, ClauseElement): def _copy_internals(self, clone=_clone, **kw): self.bindparams = dict((b.key, clone(b, **kw)) - for b in list(self.bindparams.values())) + for b in self.bindparams.values()) def get_children(self, **kwargs): return list(self.bindparams.values()) @@ -3751,7 +3751,7 @@ class BinaryExpression(ColumnElement): negate=None, modifiers=None): # allow compatibility with libraries that # refer to BinaryExpression directly and pass strings - if isinstance(operator, str): + if isinstance(operator, util.string_types): operator = operators.custom_op(operator) self._orig = (left, right) self.left = _literal_as_text(left).self_group(against=operator) @@ -3770,6 +3770,7 @@ class BinaryExpression(ColumnElement): return self.operator(hash(self._orig[0]), hash(self._orig[1])) else: raise TypeError("Boolean value of this clause is not defined") + __nonzero__ = __bool__ @property def is_comparison(self): @@ -4058,12 +4059,10 @@ class Alias(FromClause): @property def description(self): -# start Py3K - return self.name -# end Py3K -# start Py2K -# return self.name.encode('ascii', 'backslashreplace') -# end Py2K + if util.py3k: + return self.name + else: + return self.name.encode('ascii', 'backslashreplace') def as_scalar(self): try: @@ -4473,12 +4472,10 @@ class ColumnClause(Immutable, ColumnElement): @util.memoized_property def description(self): -# start Py3K - return self.name -# end Py3K -# start Py2K -# return self.name.encode('ascii', 'backslashreplace') -# end Py2K + if util.py3k: + return self.name + else: + return self.name.encode('ascii', 'backslashreplace') @_memoized_property def _key_label(self): @@ -4605,12 +4602,10 @@ class TableClause(Immutable, FromClause): @util.memoized_property def description(self): -# start Py3K - return self.name -# end Py3K -# start Py2K -# return self.name.encode('ascii', 'backslashreplace') -# end Py2K + if util.py3k: + return self.name + else: + return self.name.encode('ascii', 'backslashreplace') def append_column(self, c): self._columns[c.key] = c diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index cf1c484d0..4afb3db48 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -9,16 +9,19 @@ """Defines operators used in SQL expressions.""" +from .. import util + + from operator import ( and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg, getitem, lshift, rshift ) -# start Py2K -#from operator import (div,) -# end Py2K +if util.py2k: + from operator import div +else: + div = truediv -from ..util import symbol class Operators(object): @@ -781,17 +784,15 @@ parenthesize (a op b). """ -_smallest = symbol('_smallest', canonical=-100) -_largest = symbol('_largest', canonical=100) +_smallest = util.symbol('_smallest', canonical=-100) +_largest = util.symbol('_largest', canonical=100) _PRECEDENCE = { from_: 15, getitem: 15, mul: 8, truediv: 8, -# start Py2K -# div: 8, -# end Py2K + div: 8, mod: 8, neg: 8, add: 7, diff --git a/lib/sqlalchemy/testing/assertions.py b/lib/sqlalchemy/testing/assertions.py index e01948f9c..c04153961 100644 --- a/lib/sqlalchemy/testing/assertions.py +++ b/lib/sqlalchemy/testing/assertions.py @@ -1,4 +1,4 @@ - +from __future__ import absolute_import from . import util as testutil from sqlalchemy import pool, orm, util @@ -63,7 +63,7 @@ def emits_warning_on(db, *warnings): @decorator def decorate(fn, *args, **kw): - if isinstance(db, str): + if isinstance(db, util.string_types): if not spec(config.db): return fn(*args, **kw) else: @@ -172,8 +172,8 @@ def assert_raises_message(except_cls, msg, callable_, *args, **kwargs): callable_(*args, **kwargs) assert False, "Callable did not raise an exception" except except_cls as e: - assert re.search(msg, str(e), re.UNICODE), "%r !~ %s" % (msg, e) - print(str(e).encode('utf-8')) + assert re.search(msg, util.text_type(e), re.UNICODE), "%r !~ %s" % (msg, e) + print(util.text_type(e).encode('utf-8')) class AssertsCompiledSQL(object): @@ -190,12 +190,12 @@ class AssertsCompiledSQL(object): dialect = default.DefaultDialect() elif dialect is None: dialect = config.db.dialect - elif isinstance(dialect, str): + elif isinstance(dialect, util.string_types): dialect = create_engine("%s://" % dialect).dialect kw = {} if params is not None: - kw['column_keys'] = list(params.keys()) + kw['column_keys'] = list(params) if isinstance(clause, orm.Query): context = clause._compile_context() @@ -205,13 +205,13 @@ class AssertsCompiledSQL(object): c = clause.compile(dialect=dialect, **kw) param_str = repr(getattr(c, 'params', {})) -# start Py3K - param_str = param_str.encode('utf-8').decode('ascii', 'ignore') -# end Py3K - print("\nSQL String:\n" + str(c) + param_str) + if util.py3k: + param_str = param_str.encode('utf-8').decode('ascii', 'ignore') + + print("\nSQL String:\n" + util.text_type(c) + param_str) - cc = re.sub(r'[\n\t]', '', str(c)) + cc = re.sub(r'[\n\t]', '', util.text_type(c)) eq_(cc, result, "%r != %r on dialect %r" % (cc, result, dialect)) @@ -301,7 +301,7 @@ class AssertsExecutionResults(object): found = util.IdentitySet(result) expected = set([immutabledict(e) for e in expected]) - for wrong in itertools.filterfalse(lambda o: type(o) == cls, found): + for wrong in util.itertools_filterfalse(lambda o: type(o) == cls, found): fail('Unexpected type "%s", expected "%s"' % ( type(wrong).__name__, cls.__name__)) diff --git a/lib/sqlalchemy/testing/fixtures.py b/lib/sqlalchemy/testing/fixtures.py index 08b2361f2..daa779ae3 100644 --- a/lib/sqlalchemy/testing/fixtures.py +++ b/lib/sqlalchemy/testing/fixtures.py @@ -1,6 +1,7 @@ from . import config from . import assertions, schema from .util import adict +from .. import util from .engines import drop_all_tables from .entities import BasicEntity, ComparableEntity import sys @@ -126,8 +127,9 @@ class TablesTest(TestBase): try: table.delete().execute().close() except sa.exc.DBAPIError as ex: - print("Error emptying table %s: %r" % ( - table, ex), file=sys.stderr) + util.print_( + ("Error emptying table %s: %r" % (table, ex)), + file=sys.stderr) def setup(self): self._setup_each_tables() @@ -190,7 +192,7 @@ class TablesTest(TestBase): for table, data in cls.fixtures().items(): if len(data) < 2: continue - if isinstance(table, str): + if isinstance(table, util.string_types): table = cls.tables[table] headers[table] = data[0] rows[table] = data[1:] @@ -199,7 +201,7 @@ class TablesTest(TestBase): continue cls.bind.execute( table.insert(), - [dict(list(zip(headers[table], column_values))) + [dict(zip(headers[table], column_values)) for column_values in rows[table]]) @@ -284,7 +286,7 @@ class MappedTest(_ORMTest, TablesTest, assertions.AssertsExecutionResults): cls_registry[classname] = cls return type.__init__(cls, classname, bases, dict_) - class _Base(object, metaclass=FindFixture): + class _Base(util.with_metaclass(FindFixture, object)): pass class Basic(BasicEntity, _Base): diff --git a/lib/sqlalchemy/testing/plugin/noseplugin.py b/lib/sqlalchemy/testing/plugin/noseplugin.py index 7ad61c7b9..b3cd3a4e3 100644 --- a/lib/sqlalchemy/testing/plugin/noseplugin.py +++ b/lib/sqlalchemy/testing/plugin/noseplugin.py @@ -10,13 +10,19 @@ normally as "from sqlalchemy.testing.plugin import noseplugin". """ +from __future__ import absolute_import import os -import configparser +import sys +py3k = sys.version_info >= (3, 0) + +if py3k: + import configparser +else: + import ConfigParser as configparser from nose.plugins import Plugin from nose import SkipTest -import time import sys import re diff --git a/lib/sqlalchemy/testing/warnings.py b/lib/sqlalchemy/testing/warnings.py index 9546945eb..6193acd88 100644 --- a/lib/sqlalchemy/testing/warnings.py +++ b/lib/sqlalchemy/testing/warnings.py @@ -1,4 +1,4 @@ - +from __future__ import absolute_import import warnings from .. import exc as sa_exc @@ -10,7 +10,7 @@ def testing_warn(msg, stacklevel=3): filename = "sqlalchemy.testing.warnings" lineno = 1 - if isinstance(msg, str): + if isinstance(msg, util.string_types): warnings.warn_explicit(msg, sa_exc.SAWarning, filename, lineno) else: warnings.warn_explicit(msg, filename, lineno) diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 9e562402d..25dcce335 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -8,7 +8,7 @@ from .compat import callable, cmp, reduce, \ threading, py3k, py2k, jython, pypy, cpython, win32, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ raise_from_cause, text_type, string_types, int_types, binary_type, \ - quote_plus, with_metaclass + quote_plus, with_metaclass, print_, itertools_filterfalse, u, b from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ Properties, OrderedProperties, ImmutableProperties, OrderedDict, \ diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index bdeb69d1e..bc7a0fe21 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -33,6 +33,8 @@ else: import pickle if py3k: + import builtins + from inspect import getfullargspec as inspect_getfullargspec from urllib.parse import quote_plus, unquote_plus, parse_qsl string_types = str, @@ -41,6 +43,9 @@ if py3k: int_types = int, iterbytes = iter + def u(s): + return s + def b(s): return s.encode("latin-1") @@ -55,6 +60,13 @@ if py3k: from functools import reduce + print_ = getattr(builtins, "print") + + import_ = getattr(builtins, '__import__') + + import itertools + itertools_filterfalse = itertools.filterfalse + itertools_imap = map else: from inspect import getargspec as inspect_getfullargspec from urllib import quote_plus, unquote_plus @@ -66,13 +78,35 @@ else: def iterbytes(buf): return (ord(byte) for byte in buf) + def u(s): + return unicode(s, "unicode_escape") + def b(s): return s + def import_(*args): + if len(args) == 4: + args = args[0:3] + ([str(arg) for arg in args[3]],) + return __import__(*args) + callable = callable cmp = cmp reduce = reduce + def print_(*args, **kwargs): + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + for arg in enumerate(args): + if not isinstance(arg, basestring): + arg = str(arg) + fp.write(arg) + + import itertools + itertools_filterfalse = itertools.ifilterfalse + itertools_imap = itertools.imap + + try: from weakref import WeakSet @@ -131,6 +165,12 @@ else: exc_type, exc_value, exc_tb = exc_info reraise(type(exception), exception, tb=exc_tb) +if py3k: + exec_ = getattr(builtins, 'exec') +else: + def exec_(func_text, globals_, lcl): + exec('exec func_text in globals_, lcl') + def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index f65803dc6..8a6af3758 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -15,18 +15,14 @@ import re import sys import types import warnings -from .compat import threading, \ - callable, inspect_getfullargspec, py3k from functools import update_wrapper from .. import exc import hashlib from . import compat -import collections def md5_hex(x): -# start Py3K - x = x.encode('utf-8') -# end Py3K + if compat.py3k: + x = x.encode('utf-8') m = hashlib.md5() m.update(x) return m.hexdigest() @@ -79,7 +75,7 @@ def _unique_symbols(used, *bases): used = set(used) for base in bases: pool = itertools.chain((base,), - map(lambda i: base + str(i), + compat.itertools_imap(lambda i: base + str(i), range(1000))) for sym in pool: if sym not in used: @@ -96,7 +92,7 @@ def decorator(target): def decorate(fn): if not inspect.isfunction(fn): raise Exception("not a decoratable function") - spec = inspect_getfullargspec(fn) + spec = compat.inspect_getfullargspec(fn) names = tuple(spec[0]) + spec[1:3] + (fn.__name__,) targ_name, fn_name = _unique_symbols(names, 'target', 'fn') @@ -145,7 +141,7 @@ class PluginLoader(object): def register(self, name, modulepath, objname): def load(): - mod = __import__(modulepath) + mod = compat.import_(modulepath) for token in modulepath.split(".")[1:]: mod = getattr(mod, token) return getattr(mod, objname) @@ -252,8 +248,8 @@ def format_argspec_plus(fn, grouped=True): 'apply_pos': '(self, a, b, c, **d)'} """ - if isinstance(fn, collections.Callable): - spec = inspect_getfullargspec(fn) + if compat.callable(fn): + spec = compat.inspect_getfullargspec(fn) else: # we accept an existing argspec... spec = fn @@ -265,7 +261,7 @@ def format_argspec_plus(fn, grouped=True): else: self_arg = None - if py3k: + if compat.py3k: apply_pos = inspect.formatargspec(spec[0], spec[1], spec[2], None, spec[4]) num_defaults = 0 @@ -420,34 +416,33 @@ def class_hierarchy(cls): will not be descended. """ -# start Py2K -# if isinstance(cls, types.ClassType): -# return list() -# end Py2K + if compat.py2k: + if isinstance(cls, types.ClassType): + return list() + hier = set([cls]) process = list(cls.__mro__) while process: c = process.pop() -# start Py2K -# if isinstance(c, types.ClassType): -# continue -# for b in (_ for _ in c.__bases__ -# if _ not in hier and not isinstance(_, types.ClassType)): -# end Py2K -# start Py3K - for b in (_ for _ in c.__bases__ - if _ not in hier): -# end Py3K + if compat.py2k: + if isinstance(c, types.ClassType): + continue + bases = (_ for _ in c.__bases__ + if _ not in hier and not isinstance(_, types.ClassType)) + else: + bases = (_ for _ in c.__bases__ if _ not in hier) + + for b in bases: process.append(b) hier.add(b) -# start Py3K - if c.__module__ == 'builtins' or not hasattr(c, '__subclasses__'): - continue -# end Py3K -# start Py2K -# if c.__module__ == '__builtin__' or not hasattr(c, '__subclasses__'): -# continue -# end Py2K + + if compat.py3k: + if c.__module__ == 'builtins' or not hasattr(c, '__subclasses__'): + continue + else: + if c.__module__ == '__builtin__' or not hasattr(c, '__subclasses__'): + continue + for s in [_ for _ in c.__subclasses__() if _ not in hier]: process.append(s) hier.add(s) @@ -504,7 +499,7 @@ def monkeypatch_proxied_specials(into_cls, from_cls, skip=None, only=None, "return %(name)s.%(method)s%(d_args)s" % locals()) env = from_instance is not None and {name: from_instance} or {} - exec(py, env) + compat.exec_(py, env, {}) try: env[method].__defaults__ = fn.__defaults__ except AttributeError: @@ -593,7 +588,7 @@ def as_interface(obj, cls=None, methods=None, required=None): for method, impl in dictlike_iteritems(obj): if method not in interface: raise TypeError("%r: unknown in this interface" % method) - if not isinstance(impl, collections.Callable): + if not compat.callable(impl): raise TypeError("%r=%r is not callable" % (method, impl)) setattr(AnonymousInterface, method, staticmethod(impl)) found.add(method) @@ -734,11 +729,11 @@ class importlater(object): def _resolve(self): importlater._unresolved.discard(self) if self._il_addtl: - self._initial_import = __import__( + self._initial_import = compat.import_( self._il_path, globals(), locals(), [self._il_addtl]) else: - self._initial_import = __import__(self._il_path) + self._initial_import = compat.import_(self._il_path) def __getattr__(self, key): if key == 'module': @@ -757,7 +752,7 @@ class importlater(object): # from paste.deploy.converters def asbool(obj): - if isinstance(obj, str): + if isinstance(obj, compat.string_types): obj = obj.strip().lower() if obj in ['true', 'yes', 'on', 'y', 't', '1']: return True @@ -817,7 +812,7 @@ def constructor_copy(obj, cls, **kw): def counter(): """Return a threadsafe counter function.""" - lock = threading.Lock() + lock = compat.threading.Lock() counter = itertools.count(1) # avoid the 2to3 "next" transformation... @@ -880,16 +875,14 @@ def assert_arg_type(arg, argtype, name): def dictlike_iteritems(dictlike): """Return a (key, value) iterator for almost any dict-like object.""" -# start Py3K - if hasattr(dictlike, 'items'): - return list(dictlike.items()) -# end Py3K -# start Py2K -# if hasattr(dictlike, 'iteritems'): -# return dictlike.iteritems() -# elif hasattr(dictlike, 'items'): -# return iter(dictlike.items()) -# end Py2K + if compat.py3k: + if hasattr(dictlike, 'items'): + return list(dictlike.items()) + else: + if hasattr(dictlike, 'iteritems'): + return dictlike.iteritems() + elif hasattr(dictlike, 'items'): + return iter(dictlike.items()) getter = getattr(dictlike, '__getitem__', getattr(dictlike, 'get', None)) if getter is None: @@ -902,7 +895,7 @@ def dictlike_iteritems(dictlike): yield key, getter(key) return iterator() elif hasattr(dictlike, 'keys'): - return iter((key, getter(key)) for key in list(dictlike.keys())) + return iter((key, getter(key)) for key in dictlike.keys()) else: raise TypeError( "Object '%r' is not dict-like" % dictlike) @@ -942,7 +935,7 @@ class hybridmethod(object): class _symbol(int): def __new__(self, name, doc=None, canonical=None): """Construct a new named symbol.""" - assert isinstance(name, str) + assert isinstance(name, compat.string_types) if canonical is None: canonical = hash(name) v = int.__new__(_symbol, canonical) @@ -985,7 +978,7 @@ class symbol(object): """ symbols = {} - _lock = threading.Lock() + _lock = compat.threading.Lock() def __new__(cls, name, doc=None, canonical=None): cls._lock.acquire() @@ -1039,7 +1032,7 @@ def warn(msg, stacklevel=3): be controlled. """ - if isinstance(msg, str): + if isinstance(msg, compat.string_types): warnings.warn(msg, exc.SAWarning, stacklevel=stacklevel) else: warnings.warn(msg, stacklevel=stacklevel) -- cgit v1.2.1 From fc624dcfa40bf765bbfffa2fd964f73422e4dbe8 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 28 Apr 2013 14:44:21 -0400 Subject: - test_types, test_compiler, with sqlite at least --- lib/sqlalchemy/engine/base.py | 4 +++- lib/sqlalchemy/sql/expression.py | 3 +-- lib/sqlalchemy/types.py | 31 ++++++++++++++----------------- 3 files changed, 18 insertions(+), 20 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index dbc1ff820..d4ced4cca 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -734,7 +734,9 @@ class Connection(Connectable): distilled_params = _distill_params(multiparams, params) if distilled_params: - keys = list(distilled_params[0]) + # need list() + keys() here to suit + # both dict and RowProxy + keys = list(distilled_params[0].keys()) else: keys = [] diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index aff5512d3..2c7b91fe6 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -2204,7 +2204,7 @@ class _DefaultColumnComparator(operators.ColumnOperators): def _check_literal(self, expr, operator, other): if isinstance(other, (ColumnElement, TextClause)): if isinstance(other, BindParameter) and \ - isinstance(other.type, sqltypes.NullType): + isinstance(other.type, sqltypes.NullType): # TODO: perhaps we should not mutate the incoming # bindparam() here and instead make a copy of it. # this might be the only place that we're mutating @@ -3116,7 +3116,6 @@ class Executable(Generative): def execute(self, *multiparams, **params): """Compile and execute this :class:`.Executable`.""" - e = self.bind if e is None: label = getattr(self, 'description', self.__class__.__name__) diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index 4fbadcb0c..ffcd793c6 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -1115,12 +1115,7 @@ class String(Concatenable, TypeEngine): self.convert_unicode != 'force': if self._warn_on_bytestring: def process(value): -# start Py3K - if isinstance(value, bytes): -# end Py3K -# start Py2K -# if isinstance(value, str): -# end Py2K + if isinstance(value, util.binary_type): util.warn("Unicode type received non-unicode bind " "param value.") return value @@ -1132,7 +1127,7 @@ class String(Concatenable, TypeEngine): warn_on_bytestring = self._warn_on_bytestring def process(value): - if isinstance(value, str): + if isinstance(value, util.text_type): return encoder(value, self.unicode_error)[0] elif warn_on_bytestring and value is not None: util.warn("Unicode type received non-unicode bind " @@ -1173,7 +1168,7 @@ class String(Concatenable, TypeEngine): @property def python_type(self): if self.convert_unicode: - return str + return util.text_type else: return str @@ -1744,7 +1739,7 @@ class _Binary(TypeEngine): def coerce_compared_value(self, op, value): """See :meth:`.TypeEngine.coerce_compared_value` for a description.""" - if isinstance(value, str): + if isinstance(value, util.string_types): return self else: return super(_Binary, self).coerce_compared_value(op, value) @@ -2001,7 +1996,7 @@ class Enum(String, SchemaType): convert_unicode = kw.pop('convert_unicode', None) if convert_unicode is None: for e in enums: - if isinstance(e, str): + if isinstance(e, util.string_types): convert_unicode = True break else: @@ -2454,13 +2449,6 @@ BOOLEANTYPE = Boolean() STRINGTYPE = String() _type_map = { - str: String(), -# start Py3K - bytes: LargeBinary(), -# end Py3K -# start Py2K -# unicode: Unicode(), -# end Py2K int: Integer(), float: Numeric(), bool: BOOLEANTYPE, @@ -2471,3 +2459,12 @@ _type_map = { dt.timedelta: Interval(), NoneType: NULLTYPE } + +if util.py3k: + _type_map[bytes] = LargeBinary() + _type_map[str] = Unicode() +else: + _type_map[unicode] = Unicode() + _type_map[str] = String() + + -- cgit v1.2.1 From 734376130f01d17acc0d6c2d34c1e0f94a1cd1da Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 28 Apr 2013 16:27:23 -0400 Subject: postgresql dialect tests --- lib/sqlalchemy/dialects/postgresql/base.py | 25 ++++++++++++------------ lib/sqlalchemy/dialects/postgresql/psycopg2.py | 27 +++++++++++++------------- lib/sqlalchemy/types.py | 2 +- lib/sqlalchemy/util/__init__.py | 3 ++- 4 files changed, 28 insertions(+), 29 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 992995434..cd5d9772d 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -188,7 +188,6 @@ underlying CREATE INDEX command, so it *must* be a valid index type for your version of PostgreSQL. """ - import re from ... import sql, schema, exc, util @@ -333,7 +332,7 @@ class UUID(sqltypes.TypeEngine): if self.as_uuid: def process(value): if value is not None: - value = str(value) + value = util.text_type(value) return value return process else: @@ -1419,7 +1418,7 @@ class PGDialect(default.DefaultDialect): query, bindparams=[ sql.bindparam( - 'schema', str(schema.lower()), + 'schema', util.text_type(schema.lower()), type_=sqltypes.Unicode)] ) ) @@ -1435,7 +1434,7 @@ class PGDialect(default.DefaultDialect): "n.oid=c.relnamespace where n.nspname=current_schema() and " "relname=:name", bindparams=[ - sql.bindparam('name', str(table_name), + sql.bindparam('name', util.text_type(table_name), type_=sqltypes.Unicode)] ) ) @@ -1447,9 +1446,9 @@ class PGDialect(default.DefaultDialect): "relname=:name", bindparams=[ sql.bindparam('name', - str(table_name), type_=sqltypes.Unicode), + util.text_type(table_name), type_=sqltypes.Unicode), sql.bindparam('schema', - str(schema), type_=sqltypes.Unicode)] + util.text_type(schema), type_=sqltypes.Unicode)] ) ) return bool(cursor.first()) @@ -1463,7 +1462,7 @@ class PGDialect(default.DefaultDialect): "n.nspname=current_schema() " "and relname=:name", bindparams=[ - sql.bindparam('name', str(sequence_name), + sql.bindparam('name', util.text_type(sequence_name), type_=sqltypes.Unicode) ] ) @@ -1475,10 +1474,10 @@ class PGDialect(default.DefaultDialect): "n.oid=c.relnamespace where relkind='S' and " "n.nspname=:schema and relname=:name", bindparams=[ - sql.bindparam('name', str(sequence_name), + sql.bindparam('name', util.text_type(sequence_name), type_=sqltypes.Unicode), sql.bindparam('schema', - str(schema), type_=sqltypes.Unicode) + util.text_type(schema), type_=sqltypes.Unicode) ] ) ) @@ -1488,9 +1487,9 @@ class PGDialect(default.DefaultDialect): def has_type(self, connection, type_name, schema=None): bindparams = [ sql.bindparam('typname', - str(type_name), type_=sqltypes.Unicode), + util.text_type(type_name), type_=sqltypes.Unicode), sql.bindparam('nspname', - str(schema), type_=sqltypes.Unicode), + util.text_type(schema), type_=sqltypes.Unicode), ] if schema is not None: query = """ @@ -1546,9 +1545,9 @@ class PGDialect(default.DefaultDialect): """ % schema_where_clause # Since we're binding to unicode, table_name and schema_name must be # unicode. - table_name = str(table_name) + table_name = util.text_type(table_name) if schema is not None: - schema = str(schema) + schema = util.text_type(schema) s = sql.text(query, bindparams=[ sql.bindparam('table_name', type_=sqltypes.Unicode), sql.bindparam('schema', type_=sqltypes.Unicode) diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index 2893a3872..ce06aab05 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -142,6 +142,7 @@ type. This replaces SQLAlchemy's pure-Python HSTORE coercion which takes effect for other DBAPIs. """ +from __future__ import absolute_import import re import logging @@ -190,22 +191,20 @@ class _PGNumeric(sqltypes.Numeric): class _PGEnum(ENUM): def __init__(self, *arg, **kw): super(_PGEnum, self).__init__(*arg, **kw) -# start Py2K -# if self.convert_unicode: -# self.convert_unicode = "force" -# end Py2K + if util.py2k: + if self.convert_unicode: + self.convert_unicode = "force" class _PGArray(ARRAY): def __init__(self, *arg, **kw): super(_PGArray, self).__init__(*arg, **kw) -# start Py2K -# # FIXME: this check won't work for setups that -# # have convert_unicode only on their create_engine(). -# if isinstance(self.item_type, sqltypes.String) and \ -# self.item_type.convert_unicode: -# self.item_type.convert_unicode = "force" -# end Py2K + if util.py2k: + # FIXME: this check won't work for setups that + # have convert_unicode only on their create_engine(). + if isinstance(self.item_type, sqltypes.String) and \ + self.item_type.convert_unicode: + self.item_type.convert_unicode = "force" class _PGHStore(HSTORE): @@ -294,9 +293,9 @@ class PGIdentifierPreparer_psycopg2(PGIdentifierPreparer): class PGDialect_psycopg2(PGDialect): driver = 'psycopg2' -# start Py2K -# supports_unicode_statements = False -# end Py2K + if util.py2k: + supports_unicode_statements = False + default_paramstyle = 'pyformat' supports_sane_multi_rowcount = False execution_ctx_cls = PGExecutionContext_psycopg2 diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index ffcd793c6..c601dc306 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -1153,7 +1153,7 @@ class String(Concatenable, TypeEngine): # habits. since we will be getting back unicode # in most cases, we check for it (decode will fail). def process(value): - if isinstance(value, str): + if isinstance(value, util.text_type): return value else: return to_unicode(value) diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 25dcce335..72baa9f36 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -8,7 +8,8 @@ from .compat import callable, cmp, reduce, \ threading, py3k, py2k, jython, pypy, cpython, win32, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ raise_from_cause, text_type, string_types, int_types, binary_type, \ - quote_plus, with_metaclass, print_, itertools_filterfalse, u, b + quote_plus, with_metaclass, print_, itertools_filterfalse, u, b,\ + unquote_plus from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ Properties, OrderedProperties, ImmutableProperties, OrderedDict, \ -- cgit v1.2.1 From 6f82c320b8834761fa9606119a4c2cbc6c3312f1 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 4 May 2013 14:24:20 -0400 Subject: use logging to output exc_info here --- lib/sqlalchemy/engine/base.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index d4ced4cca..c2ba0922b 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -956,17 +956,11 @@ class Connection(Connectable): """ try: cursor.close() - except Exception as e: - try: - ex_text = str(e) - except TypeError: - ex_text = repr(e) - if not self.closed: - self.connection._logger.warn( - "Error closing cursor: %s", ex_text) - - if isinstance(e, (SystemExit, KeyboardInterrupt)): - raise + except (SystemExit, KeyboardInterrupt): + raise + except Exception: + self.connection._logger.error( + "Error closing cursor", exc_info=True) _reentrant_error = False _is_disconnect = False -- cgit v1.2.1 From 2a99b770ddf144c279ad8b42ad8593b3439cd2de Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 4 May 2013 14:59:26 -0400 Subject: - unicode literals need to just be handled differently if they have utf-8 encoded in them vs. unicode escaping. not worth figuring out how to combine these right now --- lib/sqlalchemy/dialects/sqlite/base.py | 2 +- lib/sqlalchemy/sql/compiler.py | 6 +++--- lib/sqlalchemy/util/__init__.py | 2 +- lib/sqlalchemy/util/compat.py | 10 ++++++++++ 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index d742a71b5..1ca8f4e64 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -812,7 +812,7 @@ class SQLiteDialect(default.DefaultDialect): coltype = sqltypes.NullType() if default is not None: - default = str(default) + default = util.text_type(default) return { 'name': name, diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index d51dd625a..c3aea159a 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1868,11 +1868,11 @@ class DDLCompiler(engine.Compiled): first_pk = True except exc.CompileError as ce: util.raise_from_cause( - exc.CompileError(util.u("(in table '%s', column '%s'): %s" % ( + exc.CompileError(util.u("(in table '%s', column '%s'): %s") % ( table.description, column.name, ce.args[0] - )))) + ))) const = self.create_table_constraints(table) if const: @@ -2344,7 +2344,7 @@ class IdentifierPreparer(object): lc_value = value.lower() return (lc_value in self.reserved_words or value[0] in self.illegal_initial_characters - or not self.legal_characters.match(str(value)) + or not self.legal_characters.match(util.text_type(value)) or (lc_value != value)) def quote_schema(self, schema, force): diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 72baa9f36..b1f1a2db6 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -8,7 +8,7 @@ from .compat import callable, cmp, reduce, \ threading, py3k, py2k, jython, pypy, cpython, win32, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ raise_from_cause, text_type, string_types, int_types, binary_type, \ - quote_plus, with_metaclass, print_, itertools_filterfalse, u, b,\ + quote_plus, with_metaclass, print_, itertools_filterfalse, u, ue, b,\ unquote_plus from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index bc7a0fe21..94b35f019 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -46,6 +46,9 @@ if py3k: def u(s): return s + def ue(s): + return s + def b(s): return s.encode("latin-1") @@ -79,6 +82,13 @@ else: return (ord(byte) for byte in buf) def u(s): + # this differs from what six does, which doesn't support non-ASCII + # strings - we only use u() with + # literal source strings, and all our source files with non-ascii + # in them (all are tests) are utf-8 encoded. + return unicode(s, "utf-8") + + def ue(s): return unicode(s, "unicode_escape") def b(s): -- cgit v1.2.1 From c7ce62cf65463c7ea6474d0373c56fb3edeb0e2a Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 4 May 2013 15:26:28 -0400 Subject: - OK we have -w sql passing for: sqlite, postgresql, oursql 2.7 + 3.3, mysqldb 2.7 --- lib/sqlalchemy/engine/default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index e52aac427..e9645f363 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -221,7 +221,7 @@ class DefaultDialect(interfaces.Dialect): ) row = cursor.fetchone() - return isinstance(row[0], util.string_types) + return isinstance(row[0], util.text_type) except self.dbapi.Error as de: util.warn("Exception attempting to " "detect unicode returns: %r" % de) -- cgit v1.2.1 From 920e134d53d32c644f0de487d6c40db99977ea4b Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 4 May 2013 15:29:04 -0400 Subject: test_execute up for sqlite, pg, oursql, mysql 2.7 + 3.3 --- lib/sqlalchemy/testing/engines.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/testing/engines.py b/lib/sqlalchemy/testing/engines.py index 46bf76fad..cfaacc490 100644 --- a/lib/sqlalchemy/testing/engines.py +++ b/lib/sqlalchemy/testing/engines.py @@ -1,4 +1,4 @@ - +from __future__ import absolute_import import types import weakref -- cgit v1.2.1 From 021b5143e65368bb36889dda03e5a4853621ce29 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 4 May 2013 15:57:03 -0400 Subject: that's all of engine --- lib/sqlalchemy/engine/reflection.py | 8 ++++++-- lib/sqlalchemy/util/compat.py | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index cf4a1d532..4b2987851 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -41,8 +41,12 @@ def cache(fn, self, con, *args, **kw): return fn(self, con, *args, **kw) key = ( fn.__name__, - tuple(a for a in args if isinstance(a, str)), - tuple((k, v) for k, v in kw.items() if isinstance(v, (str, int, float))) + tuple(a for a in args if isinstance(a, util.string_types)), + tuple((k, v) for k, v in kw.items() if + isinstance(v, + util.string_types + util.int_types + (float, ) + ) + ) ) ret = info_cache.get(key) if ret is None: diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 94b35f019..06bcd30dd 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -37,6 +37,9 @@ if py3k: from inspect import getfullargspec as inspect_getfullargspec from urllib.parse import quote_plus, unquote_plus, parse_qsl + import configparser + from io import StringIO + string_types = str, binary_type = bytes text_type = str @@ -74,6 +77,9 @@ else: from inspect import getargspec as inspect_getfullargspec from urllib import quote_plus, unquote_plus from urlparse import parse_qsl + import ConfigParser as configparser + from StringIO import StringIO + string_types = basestring, binary_type = str text_type = unicode -- cgit v1.2.1 From 8be6831f8be70d7946fd8e3e41b18781a1743ea7 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 4 May 2013 16:00:05 -0400 Subject: base --- lib/sqlalchemy/util/_collections.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index e505bdd5f..fddedf4f7 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -9,7 +9,7 @@ import itertools import weakref import operator -from .compat import threading +from .compat import threading, itertools_filterfalse EMPTY_SET = frozenset() @@ -470,7 +470,7 @@ class IdentitySet(object): if len(self) > len(other): return False - for m in itertools.filterfalse(other._members.__contains__, + for m in itertools_filterfalse(other._members.__contains__, iter(self._members.keys())): return False return True @@ -491,7 +491,7 @@ class IdentitySet(object): if len(self) < len(other): return False - for m in itertools.filterfalse(self._members.__contains__, + for m in itertools_filterfalse(self._members.__contains__, iter(other._members.keys())): return False return True -- cgit v1.2.1 From 220fa91337aced11789b23065289203414f2063d Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 4 May 2013 16:23:27 -0400 Subject: most of ORM passing... --- lib/sqlalchemy/event.py | 3 ++ lib/sqlalchemy/ext/associationproxy.py | 2 ++ lib/sqlalchemy/orm/attributes.py | 5 +-- lib/sqlalchemy/orm/collections.py | 57 +++++++++++++++------------------- lib/sqlalchemy/orm/instrumentation.py | 2 ++ lib/sqlalchemy/orm/query.py | 7 +---- lib/sqlalchemy/orm/util.py | 1 + lib/sqlalchemy/sql/expression.py | 1 + lib/sqlalchemy/util/compat.py | 7 +++-- lib/sqlalchemy/util/langhelpers.py | 7 +---- 10 files changed, 44 insertions(+), 48 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index 79d024f9b..33626cf2a 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -378,6 +378,8 @@ class _EmptyListener(object): def __bool__(self): return bool(self.parent_listeners) + __nonzero__ = __bool__ + class _CompoundListener(object): _exec_once = False @@ -415,6 +417,7 @@ class _CompoundListener(object): def __bool__(self): return bool(self.listeners or self.parent_listeners) + __nonzero__ = __bool__ class _ListenerCollection(_CompoundListener): """Instance-level attributes on instances of :class:`._Dispatch`. diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index ad09db831..e0a867e5a 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -478,6 +478,8 @@ class _AssociationCollection(object): def __bool__(self): return bool(self.col) + __nonzero__ = __bool__ + def __getstate__(self): return {'parent': self.parent, 'lazy_collection': self.lazy_collection} diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 691904bb3..057247047 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -386,8 +386,8 @@ def create_proxied_attribute(descriptor): return getattr(self.comparator, attribute) except AttributeError: raise AttributeError( - 'Neither %r object nor %r object associated with %s ' - 'has an attribute %r' % ( + 'Neither %r object nor %r object associated with %s ' + 'has an attribute %r' % ( type(descriptor).__name__, type(self.comparator).__name__, self, @@ -1216,6 +1216,7 @@ class History(History): def __bool__(self): return self != HISTORY_BLANK + __nonzero__ = __bool__ def empty(self): """Return True if this :class:`.History` has no changes diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index c2a2c23f0..bb7882ee9 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -657,12 +657,10 @@ class CollectionAdapter(object): if getattr(obj, '_sa_adapter', None) is not None: return getattr(obj, '_sa_adapter') elif setting_type == dict: -# start Py3K - return list(obj.values()) -# end Py3K -# start Py2K -# return getattr(obj, 'itervalues', getattr(obj, 'values'))() -# end Py2K + if util.py3k: + return obj.values() + else: + return getattr(obj, 'itervalues', getattr(obj, 'values'))() else: return iter(obj) @@ -706,8 +704,6 @@ class CollectionAdapter(object): def __iter__(self): """Iterate over entities in the collection.""" -# start Py3K -# end Py3K return iter(getattr(self._data(), '_sa_iterator')()) def __len__(self): @@ -717,6 +713,8 @@ class CollectionAdapter(object): def __bool__(self): return True + __nonzero__ = __bool__ + def fire_append_event(self, item, initiator=None): """Notify that a entity has entered the collection. @@ -1130,24 +1128,23 @@ def _list_decorators(): _tidy(__delitem__) return __delitem__ -# start Py2K -# def __setslice__(fn): -# def __setslice__(self, start, end, values): -# for value in self[start:end]: -# __del(self, value) -# values = [__set(self, value) for value in values] -# fn(self, start, end, values) -# _tidy(__setslice__) -# return __setslice__ -# -# def __delslice__(fn): -# def __delslice__(self, start, end): -# for value in self[start:end]: -# __del(self, value) -# fn(self, start, end) -# _tidy(__delslice__) -# return __delslice__ -# end Py2K + if util.py2k: + def __setslice__(fn): + def __setslice__(self, start, end, values): + for value in self[start:end]: + __del(self, value) + values = [__set(self, value) for value in values] + fn(self, start, end, values) + _tidy(__setslice__) + return __setslice__ + + def __delslice__(fn): + def __delslice__(self, start, end): + for value in self[start:end]: + __del(self, value) + fn(self, start, end) + _tidy(__delslice__) + return __delslice__ def extend(fn): def extend(self, iterable): @@ -1465,12 +1462,8 @@ __interfaces = { ), # decorators are required for dicts and object collections. -# start Py3K - dict: ({'iterator': 'values'}, _dict_decorators()), -# end Py3K -# start Py2K -# dict: ({'iterator': 'itervalues'}, _dict_decorators()), -# end Py2K + dict: ({'iterator': 'values'}, _dict_decorators()) if util.py3k + else ({'iterator': 'itervalues'}, _dict_decorators()), } diff --git a/lib/sqlalchemy/orm/instrumentation.py b/lib/sqlalchemy/orm/instrumentation.py index ce12acf20..f2d0df43f 100644 --- a/lib/sqlalchemy/orm/instrumentation.py +++ b/lib/sqlalchemy/orm/instrumentation.py @@ -329,6 +329,8 @@ class ClassManager(dict): """All ClassManagers are non-zero regardless of attribute state.""" return True + __nonzero__ = __bool__ + def __repr__(self): return '<%s of %r at %x>' % ( self.__class__.__name__, self.class_, id(self)) diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 80441b976..09f0bedd1 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -981,12 +981,7 @@ class Query(object): """Return a scalar result corresponding to the given column expression.""" try: -# start Py3K - return self.values(column).__next__()[0] -# end Py3K -# start Py2K -# return self.values(column).next()[0] -# end Py2K + return next(self.values(column))[0] except StopIteration: return None diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 30a8a8084..2a3124f4d 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -413,6 +413,7 @@ class EntityRegistry(PathRegistry, dict): def __bool__(self): return True + __nonzero__ = __bool__ def __getitem__(self, entity): if isinstance(entity, (int, slice)): diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 2c7b91fe6..f0bcd400a 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -3769,6 +3769,7 @@ class BinaryExpression(ColumnElement): return self.operator(hash(self._orig[0]), hash(self._orig[1])) else: raise TypeError("Boolean value of this clause is not defined") + __nonzero__ = __bool__ @property diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 06bcd30dd..e8404c2df 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -184,8 +184,11 @@ else: if py3k: exec_ = getattr(builtins, 'exec') else: - def exec_(func_text, globals_, lcl): - exec('exec func_text in globals_, lcl') + def exec_(func_text, globals_, lcl=None): + if lcl is None: + exec('exec func_text in globals_') + else: + exec('exec func_text in globals_, lcl') def with_metaclass(meta, *bases): diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 8a6af3758..4cb745c2b 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -499,7 +499,7 @@ def monkeypatch_proxied_specials(into_cls, from_cls, skip=None, only=None, "return %(name)s.%(method)s%(d_args)s" % locals()) env = from_instance is not None and {name: from_instance} or {} - compat.exec_(py, env, {}) + compat.exec_(py, env) try: env[method].__defaults__ = fn.__defaults__ except AttributeError: @@ -510,12 +510,7 @@ def monkeypatch_proxied_specials(into_cls, from_cls, skip=None, only=None, def methods_equivalent(meth1, meth2): """Return True if the two methods are the same implementation.""" -# start Py3K return getattr(meth1, '__func__', meth1) is getattr(meth2, '__func__', meth2) -# end Py3K -# start Py2K -# return getattr(meth1, 'im_func', meth1) is getattr(meth2, 'im_func', meth2) -# end Py2K def as_interface(obj, cls=None, methods=None, required=None): -- cgit v1.2.1 From cee8418899259e141f0059c86a32844c49f37118 Mon Sep 17 00:00:00 2001 From: diana Date: Sun, 26 May 2013 10:19:26 -0400 Subject: - fixing AbstractConcreteBase import in docstring, 0.9 branch, [ticket:2717] --- lib/sqlalchemy/ext/declarative/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py index 21fac8534..bc0c5a38c 100644 --- a/lib/sqlalchemy/ext/declarative/api.py +++ b/lib/sqlalchemy/ext/declarative/api.py @@ -308,7 +308,7 @@ class AbstractConcreteBase(ConcreteBase): Example:: - from sqlalchemy.ext.declarative import ConcreteBase + from sqlalchemy.ext.declarative import AbstractConcreteBase class Employee(AbstractConcreteBase, Base): pass -- cgit v1.2.1 From 956c144c7feae68fa957eb62ede4b21cd818c737 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 13:08:24 -0400 Subject: fix serializer tests. something is wrong with non-C pickle but for some reason py3k's pickle seems to be OK? not sure why that is, as this is all related to http://bugs.python.org/issue998998 --- lib/sqlalchemy/ext/serializer.py | 21 ++------------------- lib/sqlalchemy/util/__init__.py | 2 +- lib/sqlalchemy/util/compat.py | 17 ++++++++++++++++- 3 files changed, 19 insertions(+), 21 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/ext/serializer.py b/lib/sqlalchemy/ext/serializer.py index 759652014..8abd1fdf3 100644 --- a/lib/sqlalchemy/ext/serializer.py +++ b/lib/sqlalchemy/ext/serializer.py @@ -58,26 +58,9 @@ from ..orm.interfaces import MapperProperty from ..orm.attributes import QueryableAttribute from .. import Table, Column from ..engine import Engine -from ..util import pickle +from ..util import pickle, byte_buffer, b64encode, b64decode import re -import base64 -# start Py3K -from io import BytesIO as byte_buffer -# end Py3K -# start Py2K -#from cStringIO import StringIO as byte_buffer -# end Py2K - -# start Py3K -def b64encode(x): - return base64.b64encode(x).decode('ascii') -def b64decode(x): - return base64.b64decode(x.encode('ascii')) -# end Py3K -# start Py2K -#b64encode = base64.b64encode -#b64decode = base64.b64decode -# end Py2K + __all__ = ['Serializer', 'Deserializer', 'dumps', 'loads'] diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index b1f1a2db6..d1fc8e8e5 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -9,7 +9,7 @@ from .compat import callable, cmp, reduce, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ raise_from_cause, text_type, string_types, int_types, binary_type, \ quote_plus, with_metaclass, print_, itertools_filterfalse, u, ue, b,\ - unquote_plus + unquote_plus, b64decode, b64encode, byte_buffer from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ Properties, OrderedProperties, ImmutableProperties, OrderedDict, \ diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index e8404c2df..ea97999cf 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -28,7 +28,7 @@ if py3k: import pickle else: try: - import pickle as pickle + import cPickle as pickle except ImportError: import pickle @@ -40,6 +40,9 @@ if py3k: import configparser from io import StringIO + from io import BytesIO as byte_buffer + + string_types = str, binary_type = bytes text_type = str @@ -73,12 +76,20 @@ if py3k: import itertools itertools_filterfalse = itertools.filterfalse itertools_imap = map + + import base64 + def b64encode(x): + return base64.b64encode(x).decode('ascii') + def b64decode(x): + return base64.b64decode(x.encode('ascii')) + else: from inspect import getargspec as inspect_getfullargspec from urllib import quote_plus, unquote_plus from urlparse import parse_qsl import ConfigParser as configparser from StringIO import StringIO + from cStringIO import StringIO as byte_buffer string_types = basestring, binary_type = str @@ -109,6 +120,10 @@ else: cmp = cmp reduce = reduce + import base64 + b64encode = base64.b64encode + b64decode = base64.b64decode + def print_(*args, **kwargs): fp = kwargs.pop("file", sys.stdout) if fp is None: -- cgit v1.2.1 From 00f2b19a5589436ddd5b1ad908ed1b59e0b97825 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 13:09:05 -0400 Subject: extension tests --- lib/sqlalchemy/ext/orderinglist.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/ext/orderinglist.py b/lib/sqlalchemy/ext/orderinglist.py index 930464d7b..24d405e39 100644 --- a/lib/sqlalchemy/ext/orderinglist.py +++ b/lib/sqlalchemy/ext/orderinglist.py @@ -334,15 +334,13 @@ class OrderingList(list): super(OrderingList, self).__delitem__(index) self._reorder() -# start Py2K -# def __setslice__(self, start, end, values): -# super(OrderingList, self).__setslice__(start, end, values) -# self._reorder() -# -# def __delslice__(self, start, end): -# super(OrderingList, self).__delslice__(start, end) -# self._reorder() -# end Py2K + def __setslice__(self, start, end, values): + super(OrderingList, self).__setslice__(start, end, values) + self._reorder() + + def __delslice__(self, start, end): + super(OrderingList, self).__delslice__(start, end) + self._reorder() def __reduce__(self): return _reconstitute, (self.__class__, self.__dict__, list(self)) -- cgit v1.2.1 From 3d75ff22d3e53b7f6b5965d680157b9453fc8154 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 13:09:38 -0400 Subject: repair py3kisms in key ORM modules --- lib/sqlalchemy/orm/mapper.py | 12 ++++++------ lib/sqlalchemy/orm/query.py | 22 +++++++++++----------- lib/sqlalchemy/orm/util.py | 10 +++++----- 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 645bf86e7..285d338de 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -582,7 +582,7 @@ class Mapper(_InspectionAttr): if with_polymorphic == '*': self.with_polymorphic = ('*', None) elif isinstance(with_polymorphic, (tuple, list)): - if isinstance(with_polymorphic[0], (str, tuple, list)): + if isinstance(with_polymorphic[0], util.string_types + (tuple, list)): self.with_polymorphic = with_polymorphic else: self.with_polymorphic = (with_polymorphic, None) @@ -920,7 +920,7 @@ class Mapper(_InspectionAttr): if self.polymorphic_on is not None: setter = True - if isinstance(self.polymorphic_on, str): + if isinstance(self.polymorphic_on, util.string_types): # polymorphic_on specified as as string - link # it to mapped ColumnProperty try: @@ -1973,7 +1973,7 @@ class Mapper(_InspectionAttr): visited_states = set() prp, mpp = object(), object() - visitables = deque([(deque(list(self._props.values())), prp, + visitables = deque([(deque(self._props.values()), prp, state, state.dict)]) while visitables: @@ -1995,7 +1995,7 @@ class Mapper(_InspectionAttr): corresponding_dict = iterator.popleft() yield instance, instance_mapper, \ corresponding_state, corresponding_dict - visitables.append((deque(list(instance_mapper._props.values())), + visitables.append((deque(instance_mapper._props.values()), prp, corresponding_state, corresponding_dict)) @@ -2012,7 +2012,7 @@ class Mapper(_InspectionAttr): table_to_mapper.setdefault(t, mapper) extra_dependencies = [] - for table, mapper in list(table_to_mapper.items()): + for table, mapper in table_to_mapper.items(): super_ = mapper.inherits if super_: extra_dependencies.extend([ @@ -2041,7 +2041,7 @@ class Mapper(_InspectionAttr): return fk.parent not in cols return False - sorted_ = sql_util.sort_tables(iter(table_to_mapper.keys()), + sorted_ = sql_util.sort_tables(table_to_mapper, skip_fn=skip, extra_dependencies=extra_dependencies) diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 09f0bedd1..cb788e0a4 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -1292,7 +1292,7 @@ class Query(object): """ - if isinstance(criterion, str): + if isinstance(criterion, util.string_types): criterion = sql.text(criterion) if criterion is not None and \ @@ -1651,7 +1651,7 @@ class Query(object): kwargs.pop('from_joinpoint', False) if kwargs: raise TypeError("unknown arguments: %s" % - ','.join(iter(kwargs.keys()))) + ','.join(kwargs.keys)) return self._join(props, outerjoin=False, create_aliases=aliased, from_joinpoint=from_joinpoint) @@ -1667,7 +1667,7 @@ class Query(object): kwargs.pop('from_joinpoint', False) if kwargs: raise TypeError("unknown arguments: %s" % - ','.join(iter(kwargs.keys()))) + ','.join(kwargs)) return self._join(props, outerjoin=True, create_aliases=aliased, from_joinpoint=from_joinpoint) @@ -1717,14 +1717,14 @@ class Query(object): # is a little bit of legacy behavior still at work here # which means they might be in either order. may possibly # lock this down to (right_entity, onclause) in 0.6. - if isinstance(arg1, (interfaces.PropComparator, str)): + if isinstance(arg1, (interfaces.PropComparator, util.string_types)): right_entity, onclause = arg2, arg1 else: right_entity, onclause = arg1, arg2 left_entity = prop = None - if isinstance(onclause, str): + if isinstance(onclause, util.string_types): left_entity = self._joinpoint_zero() descriptor = _entity_descriptor(left_entity, onclause) @@ -2111,7 +2111,7 @@ class Query(object): appropriate to the entity class represented by this ``Query``. """ - if isinstance(statement, str): + if isinstance(statement, util.string_types): statement = sql.text(statement) if not isinstance(statement, @@ -2605,7 +2605,7 @@ class Query(object): use_labels=context.labels) from_clause = inner - for eager_join in list(context.eager_joins.values()): + for eager_join in context.eager_joins.values(): # EagerLoader places a 'stop_on' attribute on the join, # giving us a marker as to where the "splice point" of # the join should be @@ -2670,7 +2670,7 @@ class Query(object): subtypes are selected from the total results. """ - for (ext_info, adapter) in list(self._mapper_adapter_map.values()): + for (ext_info, adapter) in self._mapper_adapter_map.values(): if ext_info in self._join_entities: continue single_crit = ext_info.mapper._single_table_criterion @@ -2693,7 +2693,7 @@ class _QueryEntity(object): def __new__(cls, *args, **kwargs): if cls is _QueryEntity: entity = args[1] - if not isinstance(entity, str) and \ + if not isinstance(entity, util.string_types) and \ _is_mapped_class(entity): cls = _MapperEntity else: @@ -2901,7 +2901,7 @@ class _ColumnEntity(_QueryEntity): self.expr = column self.namespace = namespace - if isinstance(column, str): + if isinstance(column, util.string_types): column = sql.literal_column(column) self._label_name = column.name elif isinstance(column, ( @@ -3076,7 +3076,7 @@ class AliasOption(interfaces.MapperOption): self.alias = alias def process_query(self, query): - if isinstance(self.alias, str): + if isinstance(self.alias, util.string_types): alias = query._mapper_zero().mapped_table.alias(self.alias) else: alias = self.alias diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py index 8a26bd834..ddc0dd818 100644 --- a/lib/sqlalchemy/orm/util.py +++ b/lib/sqlalchemy/orm/util.py @@ -120,7 +120,7 @@ def polymorphic_union(table_map, typecolname, colnames = util.OrderedSet() colnamemaps = {} types = {} - for key in list(table_map.keys()): + for key in table_map: table = table_map[key] # mysql doesnt like selecting from a select; @@ -203,7 +203,7 @@ def identity_key(*args, **kwargs): "positional arguments, got %s" % len(args)) if kwargs: raise sa_exc.ArgumentError("unknown keyword arguments: %s" - % ", ".join(list(kwargs.keys()))) + % ", ".join(kwargs)) mapper = class_mapper(class_) if "ident" in locals(): return mapper.identity_key_from_primary_key(util.to_list(ident)) @@ -211,7 +211,7 @@ def identity_key(*args, **kwargs): instance = kwargs.pop("instance") if kwargs: raise sa_exc.ArgumentError("unknown keyword arguments: %s" - % ", ".join(list(kwargs.keys()))) + % ", ".join(kwargs.keys)) mapper = object_mapper(instance) return mapper.identity_key_from_instance(instance) @@ -888,7 +888,7 @@ class _ORMJoin(expression.Join): self._joined_from_info = right_info - if isinstance(onclause, str): + if isinstance(onclause, util.string_types): onclause = getattr(left_orm_info.entity, onclause) if isinstance(onclause, attributes.QueryableAttribute): @@ -1009,7 +1009,7 @@ def with_parent(instance, prop): parent/child relationship. """ - if isinstance(prop, str): + if isinstance(prop, util.string_types): mapper = object_mapper(instance) prop = getattr(mapper.class_, prop).property elif isinstance(prop, attributes.QueryableAttribute): -- cgit v1.2.1 From 62c7e0dbe64a3de27ad7631a11c813f929397c5e Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 13:10:00 -0400 Subject: sqlite tests --- lib/sqlalchemy/dialects/sqlite/pysqlite.py | 2 -- lib/sqlalchemy/sql/util.py | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py index 4a86d38d2..32ee1299f 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py @@ -267,9 +267,7 @@ class SQLiteDialect_pysqlite(SQLiteDialect): } ) -# start Py3K description_encoding = None -# end Py3K driver = 'pysqlite' diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 12edab3e1..91740dc16 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -232,7 +232,7 @@ def bind_values(clause): def _quote_ddl_expr(element): - if isinstance(element, str): + if isinstance(element, util.string_types): element = element.replace("'", "''") return "'%s'" % element else: @@ -765,7 +765,7 @@ class AliasedRow(object): return self.row[self.map[key]] def keys(self): - return list(self.row.keys()) + return self.row.keys() class ClauseAdapter(visitors.ReplacingCloningVisitor): -- cgit v1.2.1 From f939abe83034840b6c304df5ea4dfda5e9dc4633 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 16:32:55 -0400 Subject: mysql tests --- lib/sqlalchemy/dialects/mysql/base.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 0cc89149e..ad4650f6d 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -1139,14 +1139,10 @@ class SET(_StringType): # No ',' quoting issues- commas aren't allowed in SET values # The bad news: # Plenty of driver inconsistencies here. - if isinstance(value, util.set_types): + if isinstance(value, set): # ..some versions convert '' to an empty set if not value: value.add('') - # ..some return sets.Set, even for pythons - # that have __builtin__.set - if not isinstance(value, set): - value = set(value) return value # ...and some versions return strings if value is not None: -- cgit v1.2.1 From b3654ee37abe7af3d83098cd8de1980369a3fcba Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 16:39:50 -0400 Subject: postgresql tests --- lib/sqlalchemy/dialects/postgresql/base.py | 36 +++++++++++++--------------- lib/sqlalchemy/dialects/postgresql/hstore.py | 4 +++- 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index cd5d9772d..00d0acc2c 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -1569,14 +1569,13 @@ class PGDialect(default.DefaultDialect): """ rp = connection.execute(s) # what about system tables? -# start Py3K - schema_names = [row[0] for row in rp \ + + if util.py2k: + schema_names = [row[0].decode(self.encoding) for row in rp \ + if not row[0].startswith('pg_')] + else: + schema_names = [row[0] for row in rp \ if not row[0].startswith('pg_')] -# end Py3K -# start Py2K -# schema_names = [row[0].decode(self.encoding) for row in rp \ -# if not row[0].startswith('pg_')] -# end Py2K return schema_names @reflection.cache @@ -1610,13 +1609,12 @@ class PGDialect(default.DefaultDialect): AND '%(schema)s' = (select nspname from pg_namespace n where n.oid = c.relnamespace) """ % dict(schema=current_schema) -# start Py3K - view_names = [row[0] for row in connection.execute(s)] -# end Py3K -# start Py2K -# view_names = [row[0].decode(self.encoding) -# for row in connection.execute(s)] -# end Py2K + + if util.py2k: + view_names = [row[0].decode(self.encoding) + for row in connection.execute(s)] + else: + view_names = [row[0] for row in connection.execute(s)] return view_names @reflection.cache @@ -1633,12 +1631,10 @@ class PGDialect(default.DefaultDialect): rp = connection.execute(sql.text(s), view_name=view_name, schema=current_schema) if rp: -# start Py3K - view_def = rp.scalar() -# end Py3K -# start Py2K -# view_def = rp.scalar().decode(self.encoding) -# end Py2K + if util.py2k: + view_def = rp.scalar().decode(self.encoding) + else: + view_def = rp.scalar() return view_def @reflection.cache diff --git a/lib/sqlalchemy/dialects/postgresql/hstore.py b/lib/sqlalchemy/dialects/postgresql/hstore.py index d7fd34d05..adfb82da7 100644 --- a/lib/sqlalchemy/dialects/postgresql/hstore.py +++ b/lib/sqlalchemy/dialects/postgresql/hstore.py @@ -10,6 +10,8 @@ from .base import ARRAY, ischema_names from ... import types as sqltypes from ...sql import functions as sqlfunc from ...sql.operators import custom_op +from ... import util + __all__ = ('HSTORE', 'hstore') @@ -96,7 +98,7 @@ def _serialize_hstore(val): def esc(s, position): if position == 'value' and s is None: return 'NULL' - elif isinstance(s, str): + elif isinstance(s, util.string_types): return '"%s"' % s.replace('"', r'\"') else: raise ValueError("%r in %s position is not a string." % -- cgit v1.2.1 From 4e930a7f780f0997e8f7f9ef4efe5c57ad86efd0 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 16:58:37 -0400 Subject: - add a test specific to sqlite testing cursor.description encoding (should probably be one in test_query or test_unicode...) - fix up test_unitofwork --- lib/sqlalchemy/dialects/sqlite/pysqlite.py | 3 ++- lib/sqlalchemy/engine/result.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py index 32ee1299f..ad0dd5292 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py @@ -267,7 +267,8 @@ class SQLiteDialect_pysqlite(SQLiteDialect): } ) - description_encoding = None + if not util.py2k: + description_encoding = None driver = 'pysqlite' diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py index 65ce3b742..4261a5877 100644 --- a/lib/sqlalchemy/engine/result.py +++ b/lib/sqlalchemy/engine/result.py @@ -215,6 +215,8 @@ class ResultMetaData(object): processors.append(processor) rec = (processor, obj, i) +# name.encode('ascii') + # indexes as keys. This is only needed for the Python version of # RowProxy (the C version uses a faster path for integer indexes). primary_keymap[i] = rec -- cgit v1.2.1 From 46b0b14fde37ed1cacb7b33fe35d2a276a775f81 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 17:37:03 -0400 Subject: cleanup for oracle --- lib/sqlalchemy/dialects/oracle/base.py | 22 +++---- lib/sqlalchemy/dialects/oracle/cx_oracle.py | 95 ++++++++++++++--------------- 2 files changed, 57 insertions(+), 60 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index a45793367..4863b7ba1 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -437,7 +437,7 @@ class OracleCompiler(compiler.SQLCompiler): def get_select_hint_text(self, byfroms): return " ".join( - "/*+ %s */" % text for table, text in list(byfroms.items()) + "/*+ %s */" % text for table, text in byfroms.items() ) def function_argspec(self, fn, **kw): @@ -661,7 +661,7 @@ class OracleIdentifierPreparer(compiler.IdentifierPreparer): lc_value = value.lower() return (lc_value in self.reserved_words or value[0] in self.illegal_initial_characters - or not self.legal_characters.match(str(value)) + or not self.legal_characters.match(util.text_type(value)) ) def format_savepoint(self, savepoint): @@ -765,10 +765,9 @@ class OracleDialect(default.DefaultDialect): def normalize_name(self, name): if name is None: return None -# start Py2K -# if isinstance(name, str): -# name = name.decode(self.encoding) -# end Py2K + if util.py2k: + if isinstance(name, str): + name = name.decode(self.encoding) if name.upper() == name and \ not self.identifier_preparer._requires_quotes(name.lower()): return name.lower() @@ -780,12 +779,11 @@ class OracleDialect(default.DefaultDialect): return None elif name.lower() == name and not self.identifier_preparer._requires_quotes(name.lower()): name = name.upper() -# start Py2K -# if not self.supports_unicode_binds: -# name = name.encode(self.encoding) -# else: -# name = unicode(name) -# end Py2K + if util.py2k: + if not self.supports_unicode_binds: + name = name.encode(self.encoding) + else: + name = unicode(name) return name def _get_default_schema_name(self, connection): diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 10ec20dee..99a514776 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -268,21 +268,17 @@ class _LOBMixin(object): class _NativeUnicodeMixin(object): -# start Py3K - pass -# end Py3K -# start Py2K -# def bind_processor(self, dialect): -# if dialect._cx_oracle_with_unicode: -# def process(value): -# if value is None: -# return value -# else: -# return unicode(value) -# return process -# else: -# return super(_NativeUnicodeMixin, self).bind_processor(dialect) -# end Py2K + if util.py2k: + def bind_processor(self, dialect): + if dialect._cx_oracle_with_unicode: + def process(value): + if value is None: + return value + else: + return unicode(value) + return process + else: + return super(_NativeUnicodeMixin, self).bind_processor(dialect) # we apply a connection output handler that returns # unicode in all cases, so the "native_unicode" flag @@ -392,10 +388,10 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): (fromname.encode(self.dialect.encoding), toname.encode(self.dialect.encoding)) for fromname, toname in - list(quoted_bind_names.items()) + quoted_bind_names.items() ) for param in self.parameters: - for fromname, toname in list(quoted_bind_names.items()): + for fromname, toname in quoted_bind_names.items(): param[toname] = param[fromname] del param[fromname] @@ -409,7 +405,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): # if a single execute, check for outparams if len(self.compiled_parameters) == 1: - for bindparam in list(self.compiled.binds.values()): + for bindparam in self.compiled.binds.values(): if bindparam.isoutparam: dbtype = bindparam.type.dialect_impl(self.dialect).\ get_dbapi_type(self.dialect.dbapi) @@ -438,7 +434,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): if hasattr(self, 'out_parameters') and self.compiled.returning: returning_params = dict( (k, v.getvalue()) - for k, v in list(self.out_parameters.items()) + for k, v in self.out_parameters.items() ) return ReturningResultProxy(self, returning_params) @@ -457,7 +453,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): len(self.compiled_parameters) == 1: result.out_parameters = out_parameters = {} - for bind, name in list(self.compiled.bind_names.items()): + for bind, name in self.compiled.bind_names.items(): if name in self.out_parameters: type = bind.type impl_type = type.dialect_impl(self.dialect) @@ -473,7 +469,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): else: result.out_parameters = dict( (k, v.getvalue()) - for k, v in list(self.out_parameters.items()) + for k, v in self.out_parameters.items() ) return result @@ -494,11 +490,11 @@ class OracleExecutionContext_cx_oracle_with_unicode(OracleExecutionContext_cx_or """ def __init__(self, *arg, **kw): OracleExecutionContext_cx_oracle.__init__(self, *arg, **kw) - self.statement = str(self.statement) + self.statement = util.text_type(self.statement) def _execute_scalar(self, stmt): return super(OracleExecutionContext_cx_oracle_with_unicode, self).\ - _execute_scalar(str(stmt)) + _execute_scalar(util.text_type(stmt)) class ReturningResultProxy(_result.FullyBufferedResultProxy): @@ -608,19 +604,23 @@ class OracleDialect_cx_oracle(OracleDialect): self.supports_unicode_statements = True self.supports_unicode_binds = True self._cx_oracle_with_unicode = True -# start Py2K -# # There's really no reason to run with WITH_UNICODE under Python 2.x. -# # Give the user a hint. -# util.warn("cx_Oracle is compiled under Python 2.xx using the " -# "WITH_UNICODE flag. Consider recompiling cx_Oracle without " -# "this flag, which is in no way necessary for full support of Unicode. " -# "Otherwise, all string-holding bind parameters must " -# "be explicitly typed using SQLAlchemy's String type or one of its subtypes," -# "or otherwise be passed as Python unicode. Plain Python strings " -# "passed as bind parameters will be silently corrupted by cx_Oracle." -# ) -# self.execution_ctx_cls = OracleExecutionContext_cx_oracle_with_unicode -# end Py2K + + if util.py2k: + # There's really no reason to run with WITH_UNICODE under Python 2.x. + # Give the user a hint. + util.warn( + "cx_Oracle is compiled under Python 2.xx using the " + "WITH_UNICODE flag. Consider recompiling cx_Oracle " + "without this flag, which is in no way necessary for full " + "support of Unicode. Otherwise, all string-holding bind " + "parameters must be explicitly typed using SQLAlchemy's " + "String type or one of its subtypes," + "or otherwise be passed as Python unicode. " + "Plain Python strings passed as bind parameters will be " + "silently corrupted by cx_Oracle." + ) + self.execution_ctx_cls = \ + OracleExecutionContext_cx_oracle_with_unicode else: self._cx_oracle_with_unicode = False @@ -732,7 +732,7 @@ class OracleDialect_cx_oracle(OracleDialect): arraysize=cursor.arraysize) # allow all strings to come back natively as Unicode elif defaultType in (cx_Oracle.STRING, cx_Oracle.FIXED_CHAR): - return cursor.var(str, size, cursor.arraysize) + return cursor.var(util.text_type, size, cursor.arraysize) def on_connect(conn): conn.outputtypehandler = output_type_handler @@ -767,20 +767,19 @@ class OracleDialect_cx_oracle(OracleDialect): twophase=self.allow_twophase, ) -# start Py2K -# if self._cx_oracle_with_unicode: -# for k, v in opts.items(): -# if isinstance(v, str): -# opts[k] = unicode(v) -# else: -# for k, v in opts.items(): -# if isinstance(v, unicode): -# opts[k] = str(v) -# end Py2K + if util.py2k: + if self._cx_oracle_with_unicode: + for k, v in opts.items(): + if isinstance(v, str): + opts[k] = unicode(v) + else: + for k, v in opts.items(): + if isinstance(v, unicode): + opts[k] = str(v) if 'mode' in url.query: opts['mode'] = url.query['mode'] - if isinstance(opts['mode'], str): + if isinstance(opts['mode'], util.string_types): mode = opts['mode'].upper() if mode == 'SYSDBA': opts['mode'] = self.dbapi.SYSDBA -- cgit v1.2.1 From abc43312938434ca42b83f79ddb9b16a4f67bffa Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 17:39:53 -0400 Subject: a few more oracle fixes --- lib/sqlalchemy/dialects/oracle/cx_oracle.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 99a514776..5b0c3edd7 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -182,7 +182,7 @@ a period "." as the decimal character. """ - +from __future__ import absolute_import from .base import OracleCompiler, OracleDialect, OracleExecutionContext from . import base as oracle @@ -269,16 +269,16 @@ class _LOBMixin(object): class _NativeUnicodeMixin(object): if util.py2k: - def bind_processor(self, dialect): - if dialect._cx_oracle_with_unicode: - def process(value): - if value is None: - return value - else: - return unicode(value) - return process - else: - return super(_NativeUnicodeMixin, self).bind_processor(dialect) + def bind_processor(self, dialect): + if dialect._cx_oracle_with_unicode: + def process(value): + if value is None: + return value + else: + return unicode(value) + return process + else: + return super(_NativeUnicodeMixin, self).bind_processor(dialect) # we apply a connection output handler that returns # unicode in all cases, so the "native_unicode" flag -- cgit v1.2.1 From 61c796786cb222cfdca611395d8550973fc3f8d5 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 18:23:26 -0400 Subject: do a sweep of some obvious 3kisms --- lib/sqlalchemy/engine/reflection.py | 11 ++++---- lib/sqlalchemy/engine/result.py | 2 -- lib/sqlalchemy/engine/url.py | 2 +- lib/sqlalchemy/ext/associationproxy.py | 43 +++++++++++++++++++------------ lib/sqlalchemy/orm/identity.py | 46 ++++++++++++++++------------------ lib/sqlalchemy/util/__init__.py | 2 +- lib/sqlalchemy/util/compat.py | 2 ++ 7 files changed, 57 insertions(+), 51 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index 4b2987851..cf2caf679 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -389,12 +389,11 @@ class Inspector(object): del tblkw[k] tblkw[str(k)] = v -# start Py2K -# if isinstance(schema, str): -# schema = schema.decode(dialect.encoding) -# if isinstance(table_name, str): -# table_name = table_name.decode(dialect.encoding) -# end Py2K + if util.py2k: + if isinstance(schema, str): + schema = schema.decode(dialect.encoding) + if isinstance(table_name, str): + table_name = table_name.decode(dialect.encoding) # columns found_table = False diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py index 4261a5877..65ce3b742 100644 --- a/lib/sqlalchemy/engine/result.py +++ b/lib/sqlalchemy/engine/result.py @@ -215,8 +215,6 @@ class ResultMetaData(object): processors.append(processor) rec = (processor, obj, i) -# name.encode('ascii') - # indexes as keys. This is only needed for the Python version of # RowProxy (the C version uses a faster path for integer indexes). primary_keymap[i] = rec diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index b7d56374e..ed5729eea 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -149,7 +149,7 @@ def make_url(name_or_url): existing URL object is passed, just returns the object. """ - if isinstance(name_or_url, str): + if isinstance(name_or_url, util.string_types): return _parse_rfc1738_args(name_or_url) else: return name_or_url diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index e0a867e5a..39f8a7cf6 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -571,7 +571,7 @@ class _AssociationList(_AssociationCollection): def count(self, value): return sum([1 for _ in - filter(lambda v: v == value, iter(self))]) + util.itertools_filter(lambda v: v == value, iter(self))]) def extend(self, values): for v in values: @@ -740,7 +740,7 @@ class _AssociationDict(_AssociationCollection): return cmp(dict(self), other) def __repr__(self): - return repr(dict(list(self.items()))) + return repr(dict(self.items())) def get(self, key, default=None): try: @@ -756,26 +756,35 @@ class _AssociationDict(_AssociationCollection): return self[key] def keys(self): - return list(self.col.keys()) + return self.col.keys() - def iterkeys(self): - return iter(self.col.keys()) - - def values(self): - return [self._get(member) for member in list(self.col.values())] + def _iteritems(self): + for key in self.col: + yield (key, self._get(self.col[key])) + raise StopIteration - def itervalues(self): + def _itervalues(self): for key in self.col: yield self._get(self.col[key]) raise StopIteration - def items(self): - return [(k, self._get(self.col[k])) for k in self] + def _iterkeys(self): + return self.col.iterkeys() - def iteritems(self): - for key in self.col: - yield (key, self._get(self.col[key])) - raise StopIteration + + if util.py2k: + iterkeys = _iterkeys + itervalues = _itervalues + iteritems = _iteritems + + def values(self): + return [self._get(member) for member in list(self.col.values())] + + def items(self): + return [(k, self._get(self.col[k])) for k in self] + else: + values = _itervalues + items = _iteritems def pop(self, key, default=_NotProvided): if default is _NotProvided: @@ -813,7 +822,7 @@ class _AssociationDict(_AssociationCollection): self[key] = value def copy(self): - return dict(list(self.items())) + return dict(self.items()) def __hash__(self): raise TypeError("%s objects are unhashable" % type(self).__name__) @@ -846,6 +855,8 @@ class _AssociationSet(_AssociationCollection): else: return False + __nonzero__ = __bool__ + def __contains__(self, value): for member in self.col: # testlib.pragma exempt:__eq__ diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py index f010a7699..55a78066a 100644 --- a/lib/sqlalchemy/orm/identity.py +++ b/lib/sqlalchemy/orm/identity.py @@ -6,7 +6,7 @@ import weakref from . import attributes - +from .. import util class IdentityMap(dict): def __init__(self): @@ -152,32 +152,28 @@ class WeakInstanceDict(IdentityMap): return result -# start Py3K - def items(self): - return iter(self._items()) - - def values(self): - return iter(self._values()) -# end Py3K -# start Py2K -# items = _items -# -# def iteritems(self): -# return iter(self.items()) -# -# values = _values -# -# def itervalues(self): -# return iter(self.values()) -# end Py2K + if util.py2k: + items = _items + + def iteritems(self): + return iter(self.items()) + + values = _values + + def itervalues(self): + return iter(self.values()) + else: + def items(self): + return iter(self._items()) + + def values(self): + return iter(self._values()) def all_states(self): -# start Py3K - return list(dict.values(self)) -# end Py3K -# start Py2K -# return dict.values(self) -# end Py2K + if util.py2k: + return dict.values(self) + else: + return list(dict.values(self)) def discard(self, state): st = dict.get(self, state.key, None) diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index d1fc8e8e5..9e099b072 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -9,7 +9,7 @@ from .compat import callable, cmp, reduce, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ raise_from_cause, text_type, string_types, int_types, binary_type, \ quote_plus, with_metaclass, print_, itertools_filterfalse, u, ue, b,\ - unquote_plus, b64decode, b64encode, byte_buffer + unquote_plus, b64decode, b64encode, byte_buffer, itertools_filter from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ Properties, OrderedProperties, ImmutableProperties, OrderedDict, \ diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index ea97999cf..182ab1c3d 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -75,6 +75,7 @@ if py3k: import itertools itertools_filterfalse = itertools.filterfalse + itertools_filter = filter itertools_imap = map import base64 @@ -135,6 +136,7 @@ else: import itertools itertools_filterfalse = itertools.ifilterfalse + itertools_filter = itertools.ifilter itertools_imap = itertools.imap -- cgit v1.2.1 From 29689fa566ba1bd3dc08727754632c9e8074137c Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 18:25:43 -0400 Subject: fix the unicode test suite --- lib/sqlalchemy/testing/suite/test_types.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/testing/suite/test_types.py b/lib/sqlalchemy/testing/suite/test_types.py index 4dd3884ed..0d8bfdc0f 100644 --- a/lib/sqlalchemy/testing/suite/test_types.py +++ b/lib/sqlalchemy/testing/suite/test_types.py @@ -10,14 +10,15 @@ from ..schema import Table, Column from ... import testing import decimal import datetime - +from ...util import u +from ... import util class _UnicodeFixture(object): __requires__ = 'unicode_data', - data = "Alors vous imaginez ma surprise, au lever du jour, "\ + data = u("Alors vous imaginez ma surprise, au lever du jour, "\ "quand une drôle de petite voix m’a réveillé. Elle "\ - "disait: « S’il vous plaît… dessine-moi un mouton! »" + "disait: « S’il vous plaît… dessine-moi un mouton! »") @classmethod def define_tables(cls, metadata): @@ -47,7 +48,7 @@ class _UnicodeFixture(object): row, (self.data, ) ) - assert isinstance(row[0], str) + assert isinstance(row[0], util.text_type) def test_round_trip_executemany(self): unicode_table = self.tables.unicode_table @@ -72,19 +73,19 @@ class _UnicodeFixture(object): [(self.data, ) for i in range(3)] ) for row in rows: - assert isinstance(row[0], str) + assert isinstance(row[0], util.text_type) def _test_empty_strings(self): unicode_table = self.tables.unicode_table config.db.execute( unicode_table.insert(), - {"unicode_data": ''} + {"unicode_data": u('')} ) row = config.db.execute( select([unicode_table.c.unicode_data]) ).first() - eq_(row, ('',)) + eq_(row, (u(''),)) class UnicodeVarcharTest(_UnicodeFixture, fixtures.TablesTest): -- cgit v1.2.1 From 6cde27fe9161a21b075c7b8faa09d1e77169f1f2 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 19:06:13 -0400 Subject: a pass where we try to squash down as many list()/keys() combinations as possible --- lib/sqlalchemy/__init__.py | 2 +- lib/sqlalchemy/engine/default.py | 2 +- lib/sqlalchemy/event.py | 2 +- lib/sqlalchemy/ext/associationproxy.py | 2 +- lib/sqlalchemy/ext/declarative/api.py | 2 +- lib/sqlalchemy/ext/declarative/base.py | 4 ++-- lib/sqlalchemy/ext/mutable.py | 4 ++-- lib/sqlalchemy/orm/attributes.py | 2 +- lib/sqlalchemy/orm/collections.py | 12 +++++----- lib/sqlalchemy/orm/persistence.py | 2 +- lib/sqlalchemy/orm/session.py | 8 +++---- lib/sqlalchemy/orm/state.py | 2 +- lib/sqlalchemy/orm/strategies.py | 2 +- lib/sqlalchemy/orm/unitofwork.py | 4 ++-- lib/sqlalchemy/pool.py | 2 +- lib/sqlalchemy/schema.py | 2 +- lib/sqlalchemy/sql/compiler.py | 4 ++-- lib/sqlalchemy/testing/engines.py | 42 ++++++++++++++++------------------ lib/sqlalchemy/testing/entities.py | 2 +- lib/sqlalchemy/testing/schema.py | 4 ++-- lib/sqlalchemy/util/_collections.py | 6 ++--- 21 files changed, 55 insertions(+), 57 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/__init__.py b/lib/sqlalchemy/__init__.py index 5b7123b6e..21e06f548 100644 --- a/lib/sqlalchemy/__init__.py +++ b/lib/sqlalchemy/__init__.py @@ -117,7 +117,7 @@ from .inspection import inspect from .engine import create_engine, engine_from_config -__all__ = sorted(name for name, obj in list(locals().items()) +__all__ = sorted(name for name, obj in locals().items() if not (name.startswith('_') or _inspect.ismodule(obj))) __version__ = '0.8.2' diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index e9645f363..85d11ff36 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -734,7 +734,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): e, None, None, None, self) else: inputsizes = {} - for key in list(self.compiled.bind_names.values()): + for key in self.compiled.bind_names.values(): typeengine = types[key] dbtype = typeengine.dialect_impl(self.dialect).\ get_dbapi_type(self.dialect.dbapi) diff --git a/lib/sqlalchemy/event.py b/lib/sqlalchemy/event.py index 33626cf2a..d8c44dd05 100644 --- a/lib/sqlalchemy/event.py +++ b/lib/sqlalchemy/event.py @@ -300,7 +300,7 @@ class _DispatchDescriptor(object): def clear(self): """Clear all class level listeners""" - for dispatcher in list(self._clslevel.values()): + for dispatcher in self._clslevel.values(): dispatcher[:] = [] def for_modify(self, obj): diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index 39f8a7cf6..08875c3a0 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -778,7 +778,7 @@ class _AssociationDict(_AssociationCollection): iteritems = _iteritems def values(self): - return [self._get(member) for member in list(self.col.values())] + return [self._get(member) for member in self.col.values()] def items(self): return [(k, self._get(self.col[k])) for k in self] diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py index bc0c5a38c..2f222f682 100644 --- a/lib/sqlalchemy/ext/declarative/api.py +++ b/lib/sqlalchemy/ext/declarative/api.py @@ -424,7 +424,7 @@ class DeferredReflection(object): def prepare(cls, engine): """Reflect all :class:`.Table` objects for all current :class:`.DeferredReflection` subclasses""" - to_map = [m for m in list(_MapperConfig.configs.values()) + to_map = [m for m in _MapperConfig.configs.values() if issubclass(m.cls, cls)] for thingy in to_map: cls._sa_decl_prepare(thingy.local_table, engine) diff --git a/lib/sqlalchemy/ext/declarative/base.py b/lib/sqlalchemy/ext/declarative/base.py index 2099f9eb0..9187ed7f8 100644 --- a/lib/sqlalchemy/ext/declarative/base.py +++ b/lib/sqlalchemy/ext/declarative/base.py @@ -57,7 +57,7 @@ def _as_declarative(cls, classname, dict_): class_mapped = _declared_mapping_info(base) is not None - for name, obj in list(vars(base).items()): + for name, obj in vars(base).items(): if name == '__mapper_args__': if not mapper_args_fn and ( not class_mapped or @@ -129,7 +129,7 @@ def _as_declarative(cls, classname, dict_): ret.doc = obj.__doc__ # apply inherited columns as we should - for k, v in list(potential_columns.items()): + for k, v in potential_columns.items(): dict_[k] = v if inherited_table_args and not tablename: diff --git a/lib/sqlalchemy/ext/mutable.py b/lib/sqlalchemy/ext/mutable.py index 08c0bdf13..b1b851f72 100644 --- a/lib/sqlalchemy/ext/mutable.py +++ b/lib/sqlalchemy/ext/mutable.py @@ -485,7 +485,7 @@ class Mutable(MutableBase): def changed(self): """Subclasses should call this method whenever change events occur.""" - for parent, key in list(self._parents.items()): + for parent, key in self._parents.items(): flag_modified(parent, key) @classmethod @@ -579,7 +579,7 @@ class MutableComposite(MutableBase): def changed(self): """Subclasses should call this method whenever change events occur.""" - for parent, key in list(self._parents.items()): + for parent, key in self._parents.items(): prop = object_mapper(parent).get_property(key) for value, attr_name in zip( diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index 057247047..bfba695b8 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -866,7 +866,7 @@ class CollectionAttributeImpl(AttributeImpl): self.collection_factory = typecallable def __copy(self, item): - return [y for y in list(collections.collection_adapter(item))] + return [y for y in collections.collection_adapter(item)] def get_history(self, state, dict_, passive=PASSIVE_OFF): current = self.get(state, dict_, passive=passive) diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index bb7882ee9..03917d112 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -883,7 +883,7 @@ def _instrument_class(cls): # search for _sa_instrument_role-decorated methods in # method resolution order, assign to roles for supercls in cls.__mro__: - for name, method in list(vars(supercls).items()): + for name, method in vars(supercls).items(): if not util.callable(method): continue @@ -917,11 +917,11 @@ def _instrument_class(cls): collection_type = util.duck_type_collection(cls) if collection_type in __interfaces: canned_roles, decorators = __interfaces[collection_type] - for role, name in list(canned_roles.items()): + for role, name in canned_roles.items(): roles.setdefault(role, name) # apply ABC auto-decoration to methods that need it - for method, decorator in list(decorators.items()): + for method, decorator in decorators.items(): fn = getattr(cls, method, None) if (fn and method not in methods and not hasattr(fn, '_sa_instrumented')): @@ -952,12 +952,12 @@ def _instrument_class(cls): # apply ad-hoc instrumentation from decorators, class-level defaults # and implicit role declarations - for method_name, (before, argument, after) in list(methods.items()): + for method_name, (before, argument, after) in methods.items(): setattr(cls, method_name, _instrument_membership_mutator(getattr(cls, method_name), before, argument, after)) # intern the role map - for role, method_name in list(roles.items()): + for role, method_name in roles.items(): setattr(cls, '_sa_%s' % role, getattr(cls, method_name)) setattr(cls, '_sa_instrumented', id(cls)) @@ -1250,7 +1250,7 @@ def _dict_decorators(): def update(self, __other=Unspecified, **kw): if __other is not Unspecified: if hasattr(__other, 'keys'): - for key in list(__other.keys()): + for key in list(__other): if (key not in self or self[key] is not __other[key]): self[key] = __other[key] diff --git a/lib/sqlalchemy/orm/persistence.py b/lib/sqlalchemy/orm/persistence.py index 0eedea793..8ad1dbe9b 100644 --- a/lib/sqlalchemy/orm/persistence.py +++ b/lib/sqlalchemy/orm/persistence.py @@ -803,7 +803,7 @@ class BulkUD(object): raise sa_exc.ArgumentError( "Valid strategies for session synchronization " "are %s" % (", ".join(sorted(repr(x) - for x in list(lookup.keys()))))) + for x in lookup)))) else: return klass(*arg) diff --git a/lib/sqlalchemy/orm/session.py b/lib/sqlalchemy/orm/session.py index cbb508cf7..5a4486eef 100644 --- a/lib/sqlalchemy/orm/session.py +++ b/lib/sqlalchemy/orm/session.py @@ -35,7 +35,7 @@ class _SessionClassMethods(object): def close_all(cls): """Close *all* sessions in memory.""" - for sess in list(_sessions.values()): + for sess in _sessions.values(): sess.close() @classmethod @@ -250,7 +250,7 @@ class SessionTransaction(object): if s.key: del s.key - for s, (oldkey, newkey) in list(self._key_switches.items()): + for s, (oldkey, newkey) in self._key_switches.items(): self.session.identity_map.discard(s) s.key = oldkey self.session.identity_map.replace(s) @@ -2237,7 +2237,7 @@ class sessionmaker(_SessionClassMethods): session = Session() # invokes sessionmaker.__call__() """ - for k, v in list(self.kw.items()): + for k, v in self.kw.items(): local_kw.setdefault(k, v) return self.class_(**local_kw) @@ -2256,7 +2256,7 @@ class sessionmaker(_SessionClassMethods): return "%s(class_=%r%s)" % ( self.__class__.__name__, self.class_.__name__, - ", ".join("%s=%r" % (k, v) for k, v in list(self.kw.items())) + ", ".join("%s=%r" % (k, v) for k, v in self.kw.items()) ) _sessions = weakref.WeakValueDictionary() diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 8fe37e41c..6ade91b3e 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -417,7 +417,7 @@ class InstanceState(interfaces._InspectionAttr): against this set when a refresh operation occurs. """ - return set([k for k, v in list(self.callables.items()) if v is self]) + return set([k for k, v in self.callables.items() if v is self]) def _instance_dict(self): return None diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index e80745c79..4651c71b7 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -359,7 +359,7 @@ class LazyLoader(AbstractRelationshipLoader): ) if self.use_get: - for col in list(self._equated_columns.keys()): + for col in list(self._equated_columns): if col in self.mapper._equivalent_columns: for c in self.mapper._equivalent_columns[col]: self._equated_columns[c] = self._equated_columns[col] diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 54b0ebf72..aa5f7836c 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -342,7 +342,7 @@ class UOWTransaction(object): for dep in convert[edge[1]]: self.dependencies.add((edge[0], dep)) - return set([a for a in list(self.postsort_actions.values()) + return set([a for a in self.postsort_actions.values() if not a.disabled ] ).difference(cycles) @@ -461,7 +461,7 @@ class PostSortRec(object): def __repr__(self): return "%s(%s)" % ( self.__class__.__name__, - ",".join(str(x) for x in list(self.__dict__.values())) + ",".join(str(x) for x in self.__dict__.values()) ) diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 562a76163..0470e9e48 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -1004,7 +1004,7 @@ class _DBProxy(object): self._create_pool_mutex = threading.Lock() def close(self): - for key in list(self.pools.keys()): + for key in list(self.pools): del self.pools[key] def __del__(self): diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 8e5c94aba..3a74cbd59 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -1044,7 +1044,7 @@ class Column(SchemaItem, expression.ColumnClause): if self.key in table._columns: col = table._columns.get(self.key) if col is not self: - for fk in list(col.foreign_keys): + for fk in col.foreign_keys: table.foreign_keys.remove(fk) if fk.constraint in table.constraints: # this might have been removed diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index c3aea159a..b2c4a94c0 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -2073,11 +2073,11 @@ class DDLCompiler(engine.Compiled): remote_table = list(constraint._elements.values())[0].column.table text += "FOREIGN KEY(%s) REFERENCES %s (%s)" % ( ', '.join(preparer.quote(f.parent.name, f.parent.quote) - for f in list(constraint._elements.values())), + for f in constraint._elements.values()), self.define_constraint_remote_table( constraint, remote_table, preparer), ', '.join(preparer.quote(f.column.name, f.column.quote) - for f in list(constraint._elements.values())) + for f in constraint._elements.values()) ) text += self.define_constraint_match(constraint) text += self.define_constraint_cascades(constraint) diff --git a/lib/sqlalchemy/testing/engines.py b/lib/sqlalchemy/testing/engines.py index cfaacc490..efc0103f2 100644 --- a/lib/sqlalchemy/testing/engines.py +++ b/lib/sqlalchemy/testing/engines.py @@ -8,7 +8,7 @@ from .util import decorator from .. import event, pool import re import warnings - +from .. import util class ConnectionKiller(object): @@ -37,12 +37,12 @@ class ConnectionKiller(object): "rollback/close connection: %s" % e) def rollback_all(self): - for rec in list(self.proxy_refs.keys()): + for rec in list(self.proxy_refs): if rec is not None and rec.is_valid: self._safe(rec.rollback) def close_all(self): - for rec in list(self.proxy_refs.keys()): + for rec in list(self.proxy_refs): if rec is not None: self._safe(rec._close) @@ -66,7 +66,7 @@ class ConnectionKiller(object): self.conns = set() - for rec in list(self.testing_engines.keys()): + for rec in list(self.testing_engines): if rec is not config.db: rec.dispose() @@ -75,7 +75,7 @@ class ConnectionKiller(object): for conn in self.conns: self._safe(conn.close) self.conns = set() - for rec in list(self.testing_engines.keys()): + for rec in list(self.testing_engines): rec.dispose() def assert_all_closed(self): @@ -353,24 +353,22 @@ class ReplayableSession(object): Callable = object() NoAttribute = object() -# start Py3K - Natives = set([getattr(types, t) - for t in dir(types) if not t.startswith('_')]). \ - union([type(t) if not isinstance(t, type) - else t for t in list(__builtins__.values())]).\ + if util.py2k: + Natives = set([getattr(types, t) + for t in dir(types) if not t.startswith('_')]).\ difference([getattr(types, t) - for t in ('FunctionType', 'BuiltinFunctionType', - 'MethodType', 'BuiltinMethodType', - 'LambdaType', )]) -# end Py3K -# start Py2K -# Natives = set([getattr(types, t) -# for t in dir(types) if not t.startswith('_')]). \ -# difference([getattr(types, t) -# for t in ('FunctionType', 'BuiltinFunctionType', -# 'MethodType', 'BuiltinMethodType', -# 'LambdaType', 'UnboundMethodType',)]) -# end Py2K + for t in ('FunctionType', 'BuiltinFunctionType', + 'MethodType', 'BuiltinMethodType', + 'LambdaType', 'UnboundMethodType',)]) + else: + Natives = set([getattr(types, t) + for t in dir(types) if not t.startswith('_')]).\ + union([type(t) if not isinstance(t, type) + else t for t in __builtins__.values()]).\ + difference([getattr(types, t) + for t in ('FunctionType', 'BuiltinFunctionType', + 'MethodType', 'BuiltinMethodType', + 'LambdaType', )]) def __init__(self): self.buffer = deque() diff --git a/lib/sqlalchemy/testing/entities.py b/lib/sqlalchemy/testing/entities.py index 221c23c56..c0dd58650 100644 --- a/lib/sqlalchemy/testing/entities.py +++ b/lib/sqlalchemy/testing/entities.py @@ -67,7 +67,7 @@ class ComparableEntity(BasicEntity): a = self b = other - for attr in list(a.__dict__.keys()): + for attr in list(a.__dict__): if attr.startswith('_'): continue value = getattr(a, attr) diff --git a/lib/sqlalchemy/testing/schema.py b/lib/sqlalchemy/testing/schema.py index 6f3e87cc9..025bbaabe 100644 --- a/lib/sqlalchemy/testing/schema.py +++ b/lib/sqlalchemy/testing/schema.py @@ -11,7 +11,7 @@ table_options = {} def Table(*args, **kw): """A schema.Table wrapper/hook for dialect-specific tweaks.""" - test_opts = dict([(k, kw.pop(k)) for k in list(kw.keys()) + test_opts = dict([(k, kw.pop(k)) for k in list(kw) if k.startswith('test_')]) kw.update(table_options) @@ -58,7 +58,7 @@ def Table(*args, **kw): def Column(*args, **kw): """A schema.Column wrapper/hook for dialect-specific tweaks.""" - test_opts = dict([(k, kw.pop(k)) for k in list(kw.keys()) + test_opts = dict([(k, kw.pop(k)) for k in list(kw) if k.startswith('test_')]) if not config.requirements.foreign_key_ddl.enabled: diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index fddedf4f7..c10d19ea1 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -94,7 +94,7 @@ class KeyedTuple(tuple): .. versionadded:: 0.8 """ - return dict((key, self.__dict__[key]) for key in list(self.keys())) + return dict((key, self.__dict__[key]) for key in self.keys()) class ImmutableContainer(object): @@ -242,7 +242,7 @@ class OrderedDict(dict): def update(self, ____sequence=None, **kwargs): if ____sequence is not None: if hasattr(____sequence, 'keys'): - for key in list(____sequence.keys()): + for key in ____sequence.keys(): self.__setitem__(key, ____sequence[key]) else: for key, value in ____sequence: @@ -273,7 +273,7 @@ class OrderedDict(dict): return iter(list(self.keys())) def items(self): - return [(key, self[key]) for key in list(self.keys())] + return [(key, self[key]) for key in self.keys()] def iteritems(self): return iter(list(self.items())) -- cgit v1.2.1 From 3b4168875d464a141f56685f8b55dfbf70c11e5c Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 19:47:13 -0400 Subject: - zoomark tests - rewrite all profiles, we'll review the diffs to see if anything is too far out --- lib/sqlalchemy/testing/exclusions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/testing/exclusions.py b/lib/sqlalchemy/testing/exclusions.py index 93f444eb9..f580f3fde 100644 --- a/lib/sqlalchemy/testing/exclusions.py +++ b/lib/sqlalchemy/testing/exclusions.py @@ -92,7 +92,7 @@ class Predicate(object): return OrPredicate([cls.as_predicate(pred) for pred in predicate]) elif isinstance(predicate, tuple): return SpecPredicate(*predicate) - elif isinstance(predicate, str): + elif isinstance(predicate, util.string_types): return SpecPredicate(predicate, None, None) elif util.callable(predicate): return LambdaPredicate(predicate) -- cgit v1.2.1 From 2be39d5342746ea08ec5f7dcb73b6177b004de54 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 20:02:17 -0400 Subject: get profile 1a back down to 5100 calls, that one was 10% greater due to this --- lib/sqlalchemy/engine/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index c2ba0922b..2d9f3af94 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -734,9 +734,9 @@ class Connection(Connectable): distilled_params = _distill_params(multiparams, params) if distilled_params: - # need list() + keys() here to suit - # both dict and RowProxy - keys = list(distilled_params[0].keys()) + # note this is usually dict but we support RowProxy + # as well; but dict.keys() as an iterator is OK + keys = distilled_params[0].keys() else: keys = [] -- cgit v1.2.1 From a393ef6799b3ed619f91ab60bfa1299a5fe19e8f Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 20:04:54 -0400 Subject: fix an errant str check --- lib/sqlalchemy/sql/compiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index b2c4a94c0..41ef20a7a 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -2025,7 +2025,7 @@ class DDLCompiler(engine.Compiled): def get_column_default_string(self, column): if isinstance(column.server_default, schema.DefaultClause): - if isinstance(column.server_default.arg, str): + if isinstance(column.server_default.arg, util.string_types): return "'%s'" % column.server_default.arg else: return self.sql_compiler.process(column.server_default.arg) -- cgit v1.2.1 From 6abd0c4eac69ba9ca3530a9e5076d57a5b42b998 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 20:17:22 -0400 Subject: clean up some of this collection stuff --- lib/sqlalchemy/ext/associationproxy.py | 30 ++++++++++-------------- lib/sqlalchemy/orm/identity.py | 3 +-- lib/sqlalchemy/util/_collections.py | 43 +++++++++++++++++++++------------- 3 files changed, 40 insertions(+), 36 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index 08875c3a0..0482a9205 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -758,24 +758,15 @@ class _AssociationDict(_AssociationCollection): def keys(self): return self.col.keys() - def _iteritems(self): - for key in self.col: - yield (key, self._get(self.col[key])) - raise StopIteration - - def _itervalues(self): - for key in self.col: - yield self._get(self.col[key]) - raise StopIteration + if util.py2k: + def iteritems(self): + return ((key, self._get(self.col[key])) for key in self.col) - def _iterkeys(self): - return self.col.iterkeys() + def itervalues(self): + return (self._get(self.col[key]) for key in self.col) - - if util.py2k: - iterkeys = _iterkeys - itervalues = _itervalues - iteritems = _iteritems + def iterkeys(self): + return self.col.iterkeys() def values(self): return [self._get(member) for member in self.col.values()] @@ -783,8 +774,11 @@ class _AssociationDict(_AssociationCollection): def items(self): return [(k, self._get(self.col[k])) for k in self] else: - values = _itervalues - items = _iteritems + def items(self): + return ((key, self._get(self.col[key])) for key in self.col) + + def values(self): + return (self._get(self.col[key]) for key in self.col) def pop(self, key, default=_NotProvided): if default is _NotProvided: diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py index 55a78066a..d0234a1d3 100644 --- a/lib/sqlalchemy/orm/identity.py +++ b/lib/sqlalchemy/orm/identity.py @@ -154,12 +154,11 @@ class WeakInstanceDict(IdentityMap): if util.py2k: items = _items + values = _values def iteritems(self): return iter(self.items()) - values = _values - def itervalues(self): return iter(self.values()) else: diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index c10d19ea1..ed9ecfedc 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -10,6 +10,7 @@ import itertools import weakref import operator from .compat import threading, itertools_filterfalse +from . import py2k EMPTY_SET = frozenset() @@ -55,7 +56,7 @@ class KeyedTuple(tuple): t = tuple.__new__(cls, vals) t._labels = [] if labels: - t.__dict__.update(list(zip(labels, vals))) + t.__dict__.update(zip(labels, vals)) t._labels = labels return t @@ -189,13 +190,13 @@ class Properties(object): return default def keys(self): - return list(self._data.keys()) + return self._data.keys() def values(self): - return list(self._data.values()) + return self._data.values() def items(self): - return list(self._data.items()) + return self._data.items() def has_key(self, key): return key in self._data @@ -260,23 +261,33 @@ class OrderedDict(dict): def __iter__(self): return iter(self._list) - def values(self): - return [self[key] for key in self._list] + if py2k: + def values(self): + return [self[key] for key in self._list] - def itervalues(self): - return iter([self[key] for key in self._list]) + def keys(self): + return self._list - def keys(self): - return list(self._list) + def itervalues(self): + return iter([self[key] for key in self._list]) - def iterkeys(self): - return iter(list(self.keys())) + def iterkeys(self): + return iter(self) - def items(self): - return [(key, self[key]) for key in self.keys()] + def iteritems(self): + return iter(self.items()) + + def items(self): + return [(key, self[key]) for key in self._list] + else: + def values(self): + return (self[key] for key in self._list) + + def keys(self): + return iter(self._list) - def iteritems(self): - return iter(list(self.items())) + def items(self): + return ((key, self[key]) for key in self._list) def __setitem__(self, key, object): if key not in self: -- cgit v1.2.1 From 5e6d7faea688946776e0faec9cb1b716b1ff9305 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 20:24:39 -0400 Subject: clean up types.py --- lib/sqlalchemy/types.py | 99 ++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 58 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index c601dc306..bfff05362 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -392,13 +392,11 @@ class TypeEngine(AbstractType): return default.DefaultDialect() def __str__(self): -# start Py3K - return str(self.compile()) -# end Py3K -# start Py2K -# return unicode(self.compile()).\ -# encode('ascii', 'backslashreplace') -# end Py2K + if util.py2k: + return unicode(self.compile()).\ + encode('ascii', 'backslashreplace') + else: + return str(self.compile()) def __init__(self, *args, **kwargs): """Support implementations that were passing arguments""" @@ -1315,12 +1313,10 @@ class Integer(_DateAffinity, TypeEngine): Integer: self.__class__, Numeric: Numeric, }, -# start Py2K -# operators.div: { -# Integer: self.__class__, -# Numeric: Numeric, -# }, -# end Py2K + operators.div: { + Integer: self.__class__, + Numeric: Numeric, + }, operators.truediv: { Integer: self.__class__, Numeric: Numeric, @@ -1485,12 +1481,10 @@ class Numeric(_DateAffinity, TypeEngine): Numeric: self.__class__, Integer: self.__class__, }, -# start Py2K -# operators.div: { -# Numeric: self.__class__, -# Integer: self.__class__, -# }, -# end Py2K + operators.div: { + Numeric: self.__class__, + Integer: self.__class__, + }, operators.truediv: { Numeric: self.__class__, Integer: self.__class__, @@ -1555,11 +1549,9 @@ class Float(Numeric): Interval: Interval, Numeric: self.__class__, }, -# start Py2K -# operators.div: { -# Numeric: self.__class__, -# }, -# end Py2K + operators.div: { + Numeric: self.__class__, + }, operators.truediv: { Numeric: self.__class__, }, @@ -1690,12 +1682,7 @@ class _Binary(TypeEngine): @property def python_type(self): -# start Py3K - return bytes -# end Py3K -# start Py2K -# return str -# end Py2K + return util.binary_type # Python 3 - sqlite3 doesn't need the `Binary` conversion # here, though pg8000 does to indicate "bytea" @@ -1713,28 +1700,26 @@ class _Binary(TypeEngine): # Python 3 has native bytes() type # both sqlite3 and pg8000 seem to return it, # psycopg2 as of 2.5 returns 'memoryview' -# start Py3K - def result_processor(self, dialect, coltype): - def process(value): - if value is not None: - value = bytes(value) - return value - return process -# end Py3K -# start Py2K -# def result_processor(self, dialect, coltype): -# if util.jython: -# def process(value): -# if value is not None: -# if isinstance(value, array.array): -# return value.tostring() -# return str(value) -# else: -# return None -# else: -# process = processors.to_str -# return process -# end Py2K + if util.py2k: + def result_processor(self, dialect, coltype): + if util.jython: + def process(value): + if value is not None: + if isinstance(value, array.array): + return value.tostring() + return str(value) + else: + return None + else: + process = processors.to_str + return process + else: + def result_processor(self, dialect, coltype): + def process(value): + if value is not None: + value = bytes(value) + return value + return process def coerce_compared_value(self, op, value): """See :meth:`.TypeEngine.coerce_compared_value` for a description.""" @@ -1996,7 +1981,7 @@ class Enum(String, SchemaType): convert_unicode = kw.pop('convert_unicode', None) if convert_unicode is None: for e in enums: - if isinstance(e, util.string_types): + if isinstance(e, util.text_type): convert_unicode = True break else: @@ -2295,11 +2280,9 @@ class Interval(_DateAffinity, TypeDecorator): operators.truediv: { Numeric: self.__class__ }, -# start Py2K -# operators.div: { -# Numeric: self.__class__ -# } -# end Py2K + operators.div: { + Numeric: self.__class__ + } } @property -- cgit v1.2.1 From 4276049e495b543db2e6b5a15a6ea62bbe27260a Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 26 May 2013 20:44:34 -0400 Subject: fix test_execute w c extensions --- lib/sqlalchemy/util/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index 9e099b072..687abb39a 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -9,7 +9,8 @@ from .compat import callable, cmp, reduce, \ pickle, dottedgetter, parse_qsl, namedtuple, next, WeakSet, reraise, \ raise_from_cause, text_type, string_types, int_types, binary_type, \ quote_plus, with_metaclass, print_, itertools_filterfalse, u, ue, b,\ - unquote_plus, b64decode, b64encode, byte_buffer, itertools_filter + unquote_plus, b64decode, b64encode, byte_buffer, itertools_filter,\ + StringIO from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ Properties, OrderedProperties, ImmutableProperties, OrderedDict, \ -- cgit v1.2.1 From 638803eef1e5dc6e985b176b43bb9cb2a3b5010b Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 27 May 2013 13:39:24 -0400 Subject: - fix a dict while iterate mutation - illustrate how OrderedDict can catch these, but commented out to save function overhead --- lib/sqlalchemy/ext/declarative/base.py | 2 +- lib/sqlalchemy/util/_collections.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/ext/declarative/base.py b/lib/sqlalchemy/ext/declarative/base.py index 9187ed7f8..5a2b88db4 100644 --- a/lib/sqlalchemy/ext/declarative/base.py +++ b/lib/sqlalchemy/ext/declarative/base.py @@ -173,7 +173,7 @@ def _as_declarative(cls, classname, dict_): # extract columns from the class dict declared_columns = set() - for key, c in our_stuff.items(): + for key, c in list(our_stuff.items()): if isinstance(c, (ColumnProperty, CompositeProperty)): for col in c.columns: if isinstance(col, Column) and \ diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index ed9ecfedc..5991fc8a4 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -261,6 +261,14 @@ class OrderedDict(dict): def __iter__(self): return iter(self._list) + + #def __iter__(self): + # len_ = len(self._list) + # for item in self._list: + # yield item + # assert len_ == len(self._list), \ + # "Dictionary changed size during iteration" + if py2k: def values(self): return [self[key] for key in self._list] @@ -281,12 +289,15 @@ class OrderedDict(dict): return [(key, self[key]) for key in self._list] else: def values(self): + #return (self[key] for key in self) return (self[key] for key in self._list) def keys(self): + #return iter(self) return iter(self._list) def items(self): + #return ((key, self[key]) for key in self) return ((key, self[key]) for key in self._list) def __setitem__(self, key, object): -- cgit v1.2.1 From 679b3036c2d6c3715ede329aeb82aad17f5cea24 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 27 May 2013 16:34:18 -0400 Subject: - oracle py3k fix --- lib/sqlalchemy/dialects/oracle/base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index 4863b7ba1..6b6c32ae0 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -1185,7 +1185,9 @@ class OracleDialect(default.DefaultDialect): rp = connection.execute(sql.text(text), **params).scalar() if rp: - return rp.decode(self.encoding) + if util.py2k: + rp = rp.decode(self.encoding) + return rp else: return None -- cgit v1.2.1 From f9bb6c2a54ee10270a0661f938ac99b1dccfd8ef Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 27 May 2013 17:06:05 -0400 Subject: - additional oracle fixes. cx_oracle under py3k is complaining about tuples to executemany(), so just unconditionally turn this into a list - this one test segfaults only on py3k + cx_oracle --- lib/sqlalchemy/dialects/oracle/cx_oracle.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 5b0c3edd7..e013799db 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -819,6 +819,11 @@ class OracleDialect_cx_oracle(OracleDialect): id = random.randint(0, 2 ** 128) return (0x1234, "%032x" % id, "%032x" % 9) + def do_executemany(self, cursor, statement, parameters, context=None): + if isinstance(parameters, tuple): + parameters = list(parameters) + cursor.executemany(statement, parameters) + def do_begin_twophase(self, connection, xid): connection.connection.begin(*xid) -- cgit v1.2.1 From 73404e36836a0f53be9ffe28006b8492be7b0190 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 27 May 2013 17:15:30 -0400 Subject: - run the whole test suite with the "debugging" ordered dict on, find some more failures --- lib/sqlalchemy/util/_collections.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index 5991fc8a4..689a6756b 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -143,7 +143,7 @@ class Properties(object): return len(self._data) def __iter__(self): - return iter(self._data.values()) + return iter(list(self._data.values())) def __add__(self, other): return list(self) + list(other) @@ -262,13 +262,6 @@ class OrderedDict(dict): return iter(self._list) - #def __iter__(self): - # len_ = len(self._list) - # for item in self._list: - # yield item - # assert len_ == len(self._list), \ - # "Dictionary changed size during iteration" - if py2k: def values(self): return [self[key] for key in self._list] @@ -300,6 +293,24 @@ class OrderedDict(dict): #return ((key, self[key]) for key in self) return ((key, self[key]) for key in self._list) + _debug_iter = False + if _debug_iter: + # normally disabled to reduce function call + # overhead + def __iter__(self): + len_ = len(self._list) + for item in self._list: + yield item + assert len_ == len(self._list), \ + "Dictionary changed size during iteration" + def values(self): + return (self[key] for key in self) + def keys(self): + return iter(self) + def items(self): + return ((key, self[key]) for key in self) + + def __setitem__(self, key, object): if key not in self: try: -- cgit v1.2.1 From 534e05888e1ec7018c03d979df4f34074a61f12b Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 29 May 2013 18:08:28 -0400 Subject: hstores are text, and in py3k they seem to be implcitly unicode. so add unicode encoding for py2k for the non-native hstore, pullreq for native psycopg2 support coming.... --- lib/sqlalchemy/dialects/postgresql/hstore.py | 36 ++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/postgresql/hstore.py b/lib/sqlalchemy/dialects/postgresql/hstore.py index adfb82da7..b0b13eb0e 100644 --- a/lib/sqlalchemy/dialects/postgresql/hstore.py +++ b/lib/sqlalchemy/dialects/postgresql/hstore.py @@ -262,19 +262,35 @@ class HSTORE(sqltypes.Concatenable, sqltypes.TypeEngine): _adapt_expression(self, op, other_comparator) def bind_processor(self, dialect): - def process(value): - if isinstance(value, dict): - return _serialize_hstore(value) - else: - return value + if util.py2k: + encoding = dialect.encoding + def process(value): + if isinstance(value, dict): + return _serialize_hstore(value).encode(encoding) + else: + return value + else: + def process(value): + if isinstance(value, dict): + return _serialize_hstore(value) + else: + return value return process def result_processor(self, dialect, coltype): - def process(value): - if value is not None: - return _parse_hstore(value) - else: - return value + if util.py2k: + encoding = dialect.encoding + def process(value): + if value is not None: + return _parse_hstore(value.decode(encoding)) + else: + return value + else: + def process(value): + if value is not None: + return _parse_hstore(value) + else: + return value return process -- cgit v1.2.1 From d02d86a11452b67981e2c9637cedbfc902b237c5 Mon Sep 17 00:00:00 2001 From: Dmitry Mugtasimov Date: Tue, 28 May 2013 16:50:12 +0400 Subject: Unicode support for psycopg2 native hstore implementation --- lib/sqlalchemy/dialects/postgresql/psycopg2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index ce06aab05..da333e8eb 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -392,7 +392,8 @@ class PGDialect_psycopg2(PGDialect): hstore_oids = self._hstore_oids(conn) if hstore_oids is not None: oid, array_oid = hstore_oids - extras.register_hstore(conn, oid=oid, array_oid=array_oid) + extras.register_hstore(conn, oid=oid, array_oid=array_oid, + unicode=True) fns.append(on_connect) if fns: -- cgit v1.2.1 From 6c4a61b07a7aec8f6043c3e82eded27dda631cf4 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 29 May 2013 18:29:12 -0400 Subject: - repair for py3k - fix test --- lib/sqlalchemy/dialects/postgresql/psycopg2.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index da333e8eb..fcc1946ff 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -392,8 +392,13 @@ class PGDialect_psycopg2(PGDialect): hstore_oids = self._hstore_oids(conn) if hstore_oids is not None: oid, array_oid = hstore_oids - extras.register_hstore(conn, oid=oid, array_oid=array_oid, + if util.py2k: + extras.register_hstore(conn, oid=oid, + array_oid=array_oid, unicode=True) + else: + extras.register_hstore(conn, oid=oid, + array_oid=array_oid) fns.append(on_connect) if fns: -- cgit v1.2.1 From be2c145a84df5db0233f84995765d3f614776f75 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 29 May 2013 18:46:10 -0400 Subject: keep the contract for Properties as returning lists for keys, values, items. It's not the same as a dictionary as __iter__ does the values --- lib/sqlalchemy/util/_collections.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/sqlalchemy') diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index 689a6756b..86a90828a 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -190,13 +190,13 @@ class Properties(object): return default def keys(self): - return self._data.keys() + return list(self._data) def values(self): - return self._data.values() + return list(self._data.values()) def items(self): - return self._data.items() + return list(self._data.items()) def has_key(self, key): return key in self._data -- cgit v1.2.1