From: Mike Bayer Date: Sat, 11 Feb 2006 19:35:50 +0000 (+0000) Subject: fixes to TypeDecorator, including A. Houghton's patch X-Git-Tag: rel_0_1_0~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c73d40fd34f48afde1cc5eef4e77d4c86659db4;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git fixes to TypeDecorator, including A. Houghton's patch --- diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index 2301075542..ce4831ff8f 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -35,8 +35,8 @@ class TypeEngine(object): """returns the class that should be sent to the adapt() method. This class will be used to lookup an approprate database-specific subclass.""" return self.__class__ - def __repr__(self): - return util.generic_repr(self) +# def __repr__(self): + # return util.generic_repr(self) def adapt_type(typeobj, colspecs): """given a generic type from this package, and a dictionary of @@ -46,7 +46,7 @@ def adapt_type(typeobj, colspecs): typeobj = typeobj() # if the type is not a base type, i.e. not from our module, or its Null, # we return the type as is - if typeobj.__module__ != 'sqlalchemy.types' or typeobj.__class__==NullTypeEngine: + if (typeobj.__module__ != 'sqlalchemy.types' or typeobj.__class__ is NullTypeEngine) and not isinstance(typeobj, TypeDecorator): return typeobj typeobj = typeobj.adapt_args() t = typeobj.class_to_adapt() @@ -71,7 +71,11 @@ class TypeDecorator(object): def get_col_spec(self): return self.extended.get_col_spec() def adapt(self, typeobj): - self.extended = self.extended.adapt(typeobj) + if self.extended is self: + t = self.__class__.__mro__[2] + self.extended = t.adapt(self, typeobj) + else: + self.extended = self.extended.adapt(typeobj) return self def adapt_args(self): t = self.__class__.__mro__[2] diff --git a/test/engines.py b/test/engines.py index 3d9bd956e9..75ac894a35 100644 --- a/test/engines.py +++ b/test/engines.py @@ -139,7 +139,7 @@ class EngineTest(PersistTest): print repr(table) self.assert_(isinstance(table.c.col1.type, Integer)) - self.assert_(table.c.col2.type.is_unicode) + self.assert_(isinstance(table.c.col2.type, Unicode)) self.assert_(isinstance(table.c.col4.type, String)) finally: table.drop() diff --git a/test/types.py b/test/types.py index 4de4daa421..77452e51b1 100644 --- a/test/types.py +++ b/test/types.py @@ -6,6 +6,7 @@ import testbase db = testbase.db class OverrideTest(PersistTest): + """tests user-defined types, including a full type as well as a TypeDecorator""" def testprocessing(self): class MyType(types.TypeEngine): @@ -20,25 +21,35 @@ class OverrideTest(PersistTest): def adapt_args(self): return self + class MyDecoratedType(types.TypeDecorator, types.String): + def convert_bind_param(self, value, engine): + return "BIND_IN"+ value + def convert_result_value(self, value, engine): + return value + "BIND_OUT" + global users users = Table('users', db, Column('user_id', Integer, primary_key = True), - Column('goofy', MyType, nullable = False) + # totall custom type + Column('goofy', MyType, nullable = False), + + # decorated type with an argument, so its a String + Column('goofy2', MyDecoratedType(50), nullable = False), + + # decorated type without an argument, it will adapt_args to TEXT + Column('goofy3', MyDecoratedType, nullable = False), ) users.create() - users.insert().execute(user_id = 2, goofy = 'jack') - users.insert().execute(user_id = 3, goofy = 'lala') - users.insert().execute(user_id = 4, goofy = 'fred') + users.insert().execute(user_id = 2, goofy = 'jack', goofy2='jack', goofy3='jack') + users.insert().execute(user_id = 3, goofy = 'lala', goofy2='lala', goofy3='lala') + users.insert().execute(user_id = 4, goofy = 'fred', goofy2='fred', goofy3='fred') l = users.select().execute().fetchall() print repr(l) - self.assert_(l == [(2, u'BIND_INjackBIND_OUT'), (3, u'BIND_INlalaBIND_OUT'), (4, u'BIND_INfredBIND_OUT')]) + self.assert_(l == [(2, 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT', 'BIND_INjackBIND_OUT'), (3, 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT', 'BIND_INlalaBIND_OUT'), (4, 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT', 'BIND_INfredBIND_OUT')]) - l = users.select(use_labels=True).execute().fetchall() - print repr(l) - self.assert_(l == [(2, u'BIND_INjackBIND_OUT'), (3, u'BIND_INlalaBIND_OUT'), (4, u'BIND_INfredBIND_OUT')]) def tearDownAll(self): global users @@ -71,11 +82,12 @@ class ColumnsTest(AssertMixin): self.assertEquals(expectedResults[aCol.name], db.schemagenerator(None).get_column_specification(aCol)) class UnicodeTest(AssertMixin): + """tests the Unicode type. also tests the TypeDecorator with instances in the types package.""" def setUpAll(self): global unicode_table unicode_table = Table('unicode_table', db, Column('id', Integer, primary_key=True), - Column('unicode_data', Unicode), + Column('unicode_data', Unicode(50)), Column('plain_data', String) ) unicode_table.create()