From: Mike Bayer Date: Sun, 28 Apr 2013 00:38:53 +0000 (-0400) Subject: plugging away X-Git-Tag: rel_0_9_0b1~304^2~13^2~66 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c926f0a9d8910c67554f053ed0f7902542679f0d;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git plugging away --- diff --git a/09notes.txt b/09notes.txt new file mode 100644 index 0000000000..6b6295c4f1 --- /dev/null +++ b/09notes.txt @@ -0,0 +1,6 @@ +-- temporary notes -- + + +- make sure input() function in dogpile example works in py2 +- we want to get rid of any support for sets.Set entirely; check to see what +impact this has diff --git a/lib/sqlalchemy/dialects/informix/base.py b/lib/sqlalchemy/dialects/informix/base.py index a5a6917af4..e13ea8819a 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 c5b86b887a..d463b379d5 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 61403271f0..a7628f213d 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 c0497b14fa..1857c9a460 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 6fcbc2307c..deb2de449d 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 b97afe9331..77370f91d0 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 9eb3d61280..dbc1ff8206 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 56f475e302..6daa9be6b6 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 9dda6d81e5..e52aac427c 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 de054b0fd2..316161fdf7 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 030c400a79..b53eb88872 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 2ff7750cab..6efce504a7 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 2fcfabefd5..9e562402db 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 d00e3ab232..5042d505bb 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 26dd975490..f65803dc63 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