summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-04-28 14:08:28 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-04-28 14:08:28 -0400
commit18370ac032a84da539c54640a425c0fca7613dc9 (patch)
tree588c35d5fd126c7438bc49374f657e7edd9c055b
parentd37431d7a5f7c930527ad9418756d102adebffdb (diff)
downloadsqlalchemy-18370ac032a84da539c54640a425c0fca7613dc9.tar.gz
- endless isinstance(x, str)s....
-rw-r--r--lib/sqlalchemy/schema.py66
-rw-r--r--lib/sqlalchemy/sql/compiler.py22
-rw-r--r--lib/sqlalchemy/sql/expression.py95
-rw-r--r--lib/sqlalchemy/sql/operators.py19
-rw-r--r--lib/sqlalchemy/testing/assertions.py24
-rw-r--r--lib/sqlalchemy/testing/fixtures.py12
-rw-r--r--lib/sqlalchemy/testing/plugin/noseplugin.py10
-rw-r--r--lib/sqlalchemy/testing/warnings.py4
-rw-r--r--lib/sqlalchemy/util/__init__.py2
-rw-r--r--lib/sqlalchemy/util/compat.py40
-rw-r--r--lib/sqlalchemy/util/langhelpers.py101
11 files changed, 212 insertions, 183 deletions
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)