summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sqlalchemy/dialects/drizzle/base.py7
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py9
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py4
-rw-r--r--lib/sqlalchemy/types.py49
-rw-r--r--lib/sqlalchemy/util/langhelpers.py23
-rw-r--r--test/sql/test_types.py29
6 files changed, 107 insertions, 14 deletions
diff --git a/lib/sqlalchemy/dialects/drizzle/base.py b/lib/sqlalchemy/dialects/drizzle/base.py
index efad13549..3966c7dde 100644
--- a/lib/sqlalchemy/dialects/drizzle/base.py
+++ b/lib/sqlalchemy/dialects/drizzle/base.py
@@ -263,6 +263,13 @@ class CHAR(_StringType, sqltypes.CHAR):
class ENUM(mysql_dialect.ENUM):
"""Drizzle ENUM type."""
+ __kwargs_signature__ = (
+ ('strict', False),
+ ('collation', None),
+ ('binary', False),
+ ('quoting', 'unquoted'),
+ )
+
def __init__(self, *enums, **kw):
"""Construct an ENUM.
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index d5e33c802..61b7c1b17 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -977,6 +977,15 @@ class ENUM(sqltypes.Enum, _StringType):
"""MySQL ENUM type."""
__visit_name__ = 'ENUM'
+ __kwargs_signature__ = (
+ ('strict', False),
+ ('charset', None),
+ ('collation', None),
+ ('ascii', False),
+ ('unicode', False),
+ ('binary', False),
+ ('quoting', 'unquoted'),
+ )
def __init__(self, *enums, **kw):
"""Construct an ENUM.
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index dc6e30b81..8fd5e411a 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -763,6 +763,10 @@ class ENUM(sqltypes.Enum):
"""
+ __kwargs_signature__ = (
+ ('create_type', True),
+ )
+
def __init__(self, *enums, **kw):
"""Construct an :class:`~.postgresql.ENUM`.
diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py
index bfff05362..a087ddae6 100644
--- a/lib/sqlalchemy/types.py
+++ b/lib/sqlalchemy/types.py
@@ -878,7 +878,7 @@ class Variant(TypeDecorator):
"""
- def __init__(self, base, mapping):
+ def __init__(self, base, mapping, active_dialect=None):
"""Construct a new :class:`.Variant`.
:param base: the base 'fallback' type
@@ -888,6 +888,15 @@ class Variant(TypeDecorator):
"""
self.impl = base
self.mapping = mapping
+ if not active_dialect:
+ if len(self.mapping) > 1:
+ raise exc.ArgumentError(
+ 'If a mapping has multiple dialects, an active_dialect '
+ 'must be specified.')
+ else:
+ self.active_dialect = self.mapping.keys()[0]
+ else:
+ self.active_dialect = active_dialect
def load_dialect_impl(self, dialect):
if dialect.name in self.mapping:
@@ -914,7 +923,15 @@ class Variant(TypeDecorator):
"the mapping for this Variant" % dialect_name)
mapping = self.mapping.copy()
mapping[dialect_name] = type_
- return Variant(self.impl, mapping)
+ active_dialect = dialect_name if len(mapping.keys()) > 1 else None
+ return Variant(self.impl, mapping, active_dialect)
+
+ def __repr__(self):
+ dialect = __import__('sqlalchemy.dialects.%s' %
+ (self.active_dialect, ),
+ fromlist=['base']).dialect
+ obj = self.load_dialect_impl(dialect)
+ return util.generic_repr(obj, to_inspect=super(obj.__class__, obj))
def to_instance(typeobj, *arg, **kw):
@@ -1243,6 +1260,13 @@ class Unicode(String):
"""
__visit_name__ = 'unicode'
+ __kwargs_signature__ = (
+ ('length', None),
+ ('collation', None),
+ ('convert_unicode', True),
+ ('unicode_error', None),
+ ('_warn_on_bytestring', True),
+ )
def __init__(self, length=None, **kwargs):
"""
@@ -1271,6 +1295,13 @@ class UnicodeText(Text):
"""
__visit_name__ = 'unicode_text'
+ __kwargs_signature__ = (
+ ('length', None),
+ ('collation', None),
+ ('convert_unicode', True),
+ ('unicode_error', None),
+ ('_warn_on_bytestring', True),
+ )
def __init__(self, length=None, **kwargs):
"""
@@ -1916,6 +1947,15 @@ class Enum(String, SchemaType):
"""
__visit_name__ = 'enum'
+ __kwargs_signature__ = (
+ ('convert_unicode', None),
+ ('metadata', None),
+ ('name', None),
+ ('native_enum', True),
+ ('schema', None),
+ ('quote', None),
+ ('inherit_schema', None),
+ )
def __init__(self, *enums, **kw):
"""Construct an enum.
@@ -1998,10 +2038,7 @@ class Enum(String, SchemaType):
SchemaType.__init__(self, **kw)
def __repr__(self):
- return util.generic_repr(self, [
- ("native_enum", True),
- ("name", None)
- ])
+ return util.generic_repr(self)
def _should_create_constraint(self, compiler):
return not self.native_enum or \
diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py
index 1ff868e01..191474576 100644
--- a/lib/sqlalchemy/util/langhelpers.py
+++ b/lib/sqlalchemy/util/langhelpers.py
@@ -342,16 +342,22 @@ def unbound_method_to_callable(func_or_cls):
return func_or_cls
-def generic_repr(obj, additional_kw=(), to_inspect=None):
+def generic_repr(obj, to_inspect=None):
"""Produce a __repr__() based on direct association of the __init__()
specification vs. same-named attributes present.
"""
- if to_inspect is None:
- to_inspect = obj
-
missing = object()
+ # if a type uses **kwargs, it should give tuples of its expected
+ # argument names and default values in __kwargs_signature__
+ additional_kw = getattr(obj, "__kwargs_signature__", ())
+ if to_inspect:
+ if hasattr(to_inspect, "__kwargs_signature__"):
+ additional_kw += getattr(to_inspect, "__kwargs_signature__")
+ else:
+ to_inspect = obj
+
def genargs():
try:
(args, vargs, vkw, defaults) = \
@@ -364,8 +370,6 @@ def generic_repr(obj, additional_kw=(), to_inspect=None):
if not default_len:
for arg in args[1:]:
yield repr(getattr(obj, arg, None))
- if vargs is not None and hasattr(obj, vargs):
- yield ', '.join(repr(val) for val in getattr(obj, vargs))
else:
for arg in args[1:-default_len]:
yield repr(getattr(obj, arg, None))
@@ -376,7 +380,10 @@ def generic_repr(obj, additional_kw=(), to_inspect=None):
yield '%s=%r' % (arg, val)
except:
pass
- if additional_kw:
+ if vargs is not None:
+ if hasattr(obj, vargs):
+ yield ', '.join(repr(val) for val in getattr(obj, vargs))
+ if len(additional_kw):
for arg, defval in additional_kw:
try:
val = getattr(obj, arg, missing)
@@ -384,7 +391,7 @@ def generic_repr(obj, additional_kw=(), to_inspect=None):
yield '%s=%r' % (arg, val)
except:
pass
-
+
return "%s(%s)" % (obj.__class__.__name__, ", ".join(genargs()))
diff --git a/test/sql/test_types.py b/test/sql/test_types.py
index dbb475b98..268acd205 100644
--- a/test/sql/test_types.py
+++ b/test/sql/test_types.py
@@ -655,6 +655,35 @@ class VariantTest(fixtures.TestBase, AssertsCompiledSQL):
'fooUTWO'
)
+ def test_repr(self):
+ test_objects = (
+ (types.String().with_variant(
+ dialects.mysql.VARCHAR(32, collation='foo', ascii=True),
+ 'mysql'),
+ "VARCHAR(collation='foo', ascii=True)"),
+ (types.Enum('red', 'green', 'blue').with_variant(
+ dialects.postgresql.ENUM(
+ 'red', 'green', 'blue', name="rgb_enum", create_type=False),
+ 'postgresql'),
+ "ENUM('red', 'green', 'blue', create_type=False, convert_unicode="
+ "False, name='rgb_enum', inherit_schema=False)"),
+ (types.Enum('red', 'green', 'blue').with_variant(
+ dialects.drizzle.ENUM('red', 'green', 'blue', unicode=True),
+ 'drizzle'),
+ "ENUM('red', 'green', 'blue', unicode=True)"),
+ (types.Integer().with_variant(
+ dialects.mssql.TINYINT(),
+ 'mssql'),
+ "TINYINT()"),
+ (types.Numeric().with_variant(
+ dialects.oracle.NUMBER(precision='10', scale='4'),
+ 'oracle'),
+ "NUMBER(precision='10', scale='4')")
+ )
+ for obj, result in test_objects:
+ eq_(repr(obj), result)
+
+
class UnicodeTest(fixtures.TestBase):
"""Exercise the Unicode and related types.