diff options
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r-- | lib/sqlalchemy/sql/__init__.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 37 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/expression.py | 106 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/functions.py | 3 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/operators.py | 17 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/util.py | 14 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/visitors.py | 12 |
7 files changed, 82 insertions, 109 deletions
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 5dd7ec564..d475f54ac 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'(?<![:\w\$\x5c]):([\w\$]+)(?![:\w\$])', re.UNICODE) BIND_PARAMS_ESC = re.compile(r'\x5c(:[\w\$]+)(?![:\w\$])', re.UNICODE) @@ -83,9 +83,7 @@ OPERATORS = { operators.add: ' + ', operators.mul: ' * ', operators.sub: ' - ', - # Py2K operators.div: ' / ', - # end Py2K operators.mod: ' % ', operators.truediv: ' / ', operators.neg: '-', @@ -334,7 +332,7 @@ class SQLCompiler(engine.Compiled): if params: pd = {} - for bindparam, name in self.bind_names.iteritems(): + for bindparam, name in self.bind_names.items(): if bindparam.key in params: pd[name] = params[bindparam.key] elif name in params: @@ -488,7 +486,7 @@ class SQLCompiler(engine.Compiled): def visit_textclause(self, textclause, **kwargs): if textclause.typemap is not None: - for colname, type_ in textclause.typemap.iteritems(): + for colname, type_ in textclause.typemap.items(): self.result_map[colname if self.dialect.case_sensitive else colname.lower()] = \ @@ -862,12 +860,12 @@ class SQLCompiler(engine.Compiled): of the DBAPI. """ - if isinstance(value, basestring): + if isinstance(value, util.string_types): value = value.replace("'", "''") return "'%s'" % value elif value is None: return "NULL" - elif isinstance(value, (float, int, long)): + elif isinstance(value, (float, ) + util.int_types): return repr(value) elif isinstance(value, decimal.Decimal): return str(value) @@ -1172,7 +1170,7 @@ class SQLCompiler(engine.Compiled): self, ashint=True) }) for (from_, dialect), hinttext in - select._hints.iteritems() + select._hints.items() if dialect in ('*', self.dialect.name) ]) hint_text = self.get_select_hint_text(byfrom) @@ -1570,7 +1568,7 @@ class SQLCompiler(engine.Compiled): values = [] if stmt_parameters is not None: - for k, v in stmt_parameters.iteritems(): + for k, v in stmt_parameters.items(): colkey = sql._column_as_key(k) if colkey is not None: parameters.setdefault(colkey, v) @@ -1910,22 +1908,13 @@ class DDLCompiler(engine.Compiled): and not first_pk) if column.primary_key: first_pk = True - except exc.CompileError, ce: - # Py3K - #raise exc.CompileError("(in table '%s', column '%s'): %s" - # % ( - # table.description, - # column.name, - # ce.args[0] - # )) from ce - # Py2K - raise exc.CompileError("(in table '%s', column '%s'): %s" - % ( + except exc.CompileError as ce: + util.raise_from_cause( + exc.CompileError(util.u("(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: @@ -2078,7 +2067,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, basestring): + 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) @@ -2397,7 +2386,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(unicode(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/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 402e52272..6dc134d98 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(unicode): +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( - unicode(self) + - unicode(other)) + util.text_type(self) + + util.text_type(other)) def __radd__(self, other): return _anonymous_label( - unicode(other) + - unicode(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, basestring): + 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, basestring): + 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, basestring): - return TextClause(unicode(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, basestring): - return TextClause(unicode(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") @@ -1717,17 +1717,6 @@ class ClauseElement(Visitable): d.pop('_is_clone_of', None) return d - if util.jython: - def __hash__(self): - """Return a distinct hash code. - - ClauseElements may have special equality comparisons which - makes us rely on them having unique hash codes for use in - hash-based collections. Stock __hash__ doesn't guarantee - unique values on platforms with moving GCs. - """ - return id(self) - def _annotate(self, values): """return a copy of this ClauseElement with annotations updated by the given dictionary. @@ -1916,11 +1905,10 @@ class ClauseElement(Visitable): return dialect.statement_compiler(dialect, self, **kw) def __str__(self): - # Py3K - #return unicode(self.compile()) - # 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) @@ -1931,9 +1919,11 @@ class ClauseElement(Visitable): def __invert__(self): return self._negate() - def __nonzero__(self): + 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 @@ -2205,7 +2195,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 @@ -2525,7 +2515,7 @@ class ColumnCollection(util.OrderedProperties): return and_(*l) def __contains__(self, other): - if not isinstance(other, basestring): + if not isinstance(other, util.string_types): raise exc.ArgumentError("__contains__ requires a string argument") return util.OrderedProperties.__contains__(self, other) @@ -3117,7 +3107,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__) @@ -3186,13 +3175,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 @@ -3202,9 +3191,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 typemap.keys(): + for key in typemap: typemap[key] = sqltypes.to_instance(typemap[key]) def repl(m): @@ -3241,7 +3230,7 @@ class TextClause(Executable, ClauseElement): for b in self.bindparams.values()) def get_children(self, **kwargs): - return self.bindparams.values() + return list(self.bindparams.values()) class Null(ColumnElement): @@ -3759,7 +3748,7 @@ class BinaryExpression(ColumnElement): negate=None, modifiers=None): # allow compatibility with libraries that # refer to BinaryExpression directly and pass strings - if isinstance(operator, basestring): + 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) @@ -3773,12 +3762,14 @@ class BinaryExpression(ColumnElement): else: self.modifiers = modifiers - def __nonzero__(self): + def __bool__(self): if self.operator in (operator.eq, operator.ne): 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): return operators.is_comparison(self.operator) @@ -4066,11 +4057,10 @@ class Alias(FromClause): @property def description(self): - # Py3K - #return self.name - # 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: @@ -4484,11 +4474,10 @@ class ColumnClause(Immutable, ColumnElement): @util.memoized_property def description(self): - # Py3K - #return self.name - # 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): @@ -4615,11 +4604,10 @@ class TableClause(Immutable, FromClause): @util.memoized_property def description(self): - # Py3K - #return self.name - # 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/functions.py b/lib/sqlalchemy/sql/functions.py index c1c07dfb6..5e2d0792c 100644 --- a/lib/sqlalchemy/sql/functions.py +++ b/lib/sqlalchemy/sql/functions.py @@ -41,7 +41,7 @@ class _GenericMeta(VisitableType): super(_GenericMeta, cls).__init__(clsname, bases, clsdict) -class GenericFunction(Function): +class GenericFunction(util.with_metaclass(_GenericMeta, Function)): """Define a 'generic' function. A generic function is a pre-established :class:`.Function` @@ -112,7 +112,6 @@ class GenericFunction(Function): name is still recognized for backwards-compatibility. """ - __metaclass__ = _GenericMeta coerce_arguments = True diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index a7e6af116..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 ) -# 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, - # Py2K div: 8, - # end Py2K mod: 8, neg: 8, add: 7, diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 4aa2d7496..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, basestring): + if isinstance(element, util.string_types): element = element.replace("'", "''") return "'%s'" % element else: @@ -349,7 +349,7 @@ def join_condition(a, b, ignore_nonexistent_tables=False, continue try: col = fk.get_referent(left) - except exc.NoReferenceError, nrte: + except exc.NoReferenceError as nrte: if nrte.table_name == left.name: raise else: @@ -367,7 +367,7 @@ def join_condition(a, b, ignore_nonexistent_tables=False, continue try: col = fk.get_referent(b) - except exc.NoReferenceError, nrte: + except exc.NoReferenceError as nrte: if nrte.table_name == b.name: raise else: @@ -518,15 +518,15 @@ class AnnotatedColumnElement(Annotated): # so that the resulting objects are pickleable. annotated_classes = {} -for cls in expression.__dict__.values() + [schema.Column, schema.Table]: +for cls in list(expression.__dict__.values()) + [schema.Column, schema.Table]: if isinstance(cls, type) and issubclass(cls, expression.ClauseElement): if issubclass(cls, expression.ColumnElement): annotation_cls = "AnnotatedColumnElement" else: annotation_cls = "Annotated" - exec "class Annotated%s(%s, cls):\n" \ - " pass" % (cls.__name__, annotation_cls) in locals() - exec "annotated_classes[cls] = Annotated%s" % (cls.__name__,) + exec("class Annotated%s(%s, cls):\n" \ + " pass" % (cls.__name__, annotation_cls), locals()) + exec("annotated_classes[cls] = Annotated%s" % (cls.__name__,)) def _deep_annotate(element, annotations, exclude=None): diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index f1dbb9e32..62f46ab64 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 != 'Visitable' and \ + hasattr(cls, '__visit_name__'): + _generate_dispatch(cls) super(VisitableType, cls).__init__(clsname, bases, clsdict) @@ -87,14 +85,12 @@ def _generate_dispatch(cls): cls._compiler_dispatch = _compiler_dispatch -class Visitable(object): +class Visitable(util.with_metaclass(VisitableType, object)): """Base class for visitable objects, applies the ``VisitableType`` metaclass. """ - __metaclass__ = VisitableType - class ClauseVisitor(object): """Base class for visitor objects which can traverse using |