From ba67f7dbc5eb7a1ed2a3e1b56df72a837130f7bb Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 18 Oct 2012 12:29:41 -0400 Subject: [PATCH] - [bug] TypeDecorator now includes a generic repr() that works in terms of the "impl" type by default. This is a behavioral change for those TypeDecorator classes that specify a custom __init__ method; those types will need to re-define __repr__() if they need __repr__() to provide a faithful constructor representation. [ticket:2594] --- CHANGES | 8 ++++++++ lib/sqlalchemy/types.py | 3 +++ lib/sqlalchemy/util/langhelpers.py | 6 ++++-- test/sql/test_types.py | 6 ++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 97f5061c0f..084ab4eadd 100644 --- a/CHANGES +++ b/CHANGES @@ -716,6 +716,14 @@ underneath "0.7.xx". but not ForeignKeyConstraint or CheckConstraint. [ticket:2410] + - [bug] TypeDecorator now includes a generic repr() + that works in terms of the "impl" type by default. + This is a behavioral change for those TypeDecorator + classes that specify a custom __init__ method; those + types will need to re-define __repr__() if they need + __repr__() to provide a faithful constructor representation. + [ticket:2594] + - [bug] column.label(None) now produces an anonymous label, instead of returning the column object itself, consistent with the behavior diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index ebcffca6e2..e31cecfe22 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -817,6 +817,9 @@ class TypeDecorator(TypeEngine): """ return self.impl.compare_values(x, y) + def __repr__(self): + return util.generic_repr(self, to_inspect=self.impl) + class Variant(TypeDecorator): """A wrapping type that selects among a variety of diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 9761aeae9f..55b78090a5 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -281,14 +281,16 @@ def unbound_method_to_callable(func_or_cls): else: return func_or_cls -def generic_repr(obj, additional_kw=()): +def generic_repr(obj, additional_kw=(), 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 def genargs(): try: - (args, vargs, vkw, defaults) = inspect.getargspec(obj.__init__) + (args, vargs, vkw, defaults) = inspect.getargspec(to_inspect.__init__) except TypeError: return diff --git a/test/sql/test_types.py b/test/sql/test_types.py index 1d096d7c41..98bc516247 100644 --- a/test/sql/test_types.py +++ b/test/sql/test_types.py @@ -336,6 +336,12 @@ class UserDefinedTest(fixtures.TablesTest, AssertsCompiledSQL): Float().dialect_impl(pg).__class__ ) + def test_type_decorator_repr(self): + class MyType(TypeDecorator): + impl = VARCHAR + + eq_(repr(MyType(45)), "MyType(length=45)") + def test_user_defined_typedec_impl_bind(self): class TypeOne(types.TypeEngine): def bind_processor(self, dialect): -- 2.47.3