summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/__init__.py2
-rw-r--r--lib/sqlalchemy/sql/compiler.py37
-rw-r--r--lib/sqlalchemy/sql/expression.py106
-rw-r--r--lib/sqlalchemy/sql/functions.py3
-rw-r--r--lib/sqlalchemy/sql/operators.py17
-rw-r--r--lib/sqlalchemy/sql/util.py14
-rw-r--r--lib/sqlalchemy/sql/visitors.py12
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