]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug where using a :class:`.TypeDecorator` that implemented
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 19 Dec 2014 17:14:52 +0000 (12:14 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 19 Dec 2014 17:15:10 +0000 (12:15 -0500)
a type that was also a :class:`.TypeDecorator` would fail with
Python's "Cannot create a consistent method resolution order (MRO)"
error, when any kind of SQL comparison expression were used against
an object using this type.

(cherry picked from commit d1ac6cb33af3b105db7cdb51411e10ac3bafff1f)

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/sql/type_api.py
test/sql/test_operators.py

index b2c876141ee886d5bcaf97560eaf4e0ee86520ca..4ff73c45df762dd515288f272a61a5bb4eb49a73 100644 (file)
 .. changelog::
     :version: 0.9.9
 
+    .. change::
+        :tags: bug, sql
+        :versions: 1.0.0
+        :tickets: 3278
+
+        Fixed bug where using a :class:`.TypeDecorator` that implemented
+        a type that was also a :class:`.TypeDecorator` would fail with
+        Python's "Cannot create a consistent method resolution order (MRO)"
+        error, when any kind of SQL comparison expression were used against
+        an object using this type.
+
     .. change::
         :tags: bug, mysql
         :versions: 1.0.0
index 77c6e1b1eec79431ba52a22e1743bc261335d4e8..691ef9802af73b6ca7a713739d062ace9d847b51 100644 (file)
@@ -630,9 +630,13 @@ class TypeDecorator(TypeEngine):
 
     @property
     def comparator_factory(self):
-        return type("TDComparator",
-                    (TypeDecorator.Comparator, self.impl.comparator_factory),
-                    {})
+        if TypeDecorator.Comparator in self.impl.comparator_factory.__mro__:
+            return self.impl.comparator_factory
+        else:
+            return type("TDComparator",
+                        (TypeDecorator.Comparator,
+                         self.impl.comparator_factory),
+                        {})
 
     def _gen_dialect_impl(self, dialect):
         """
index 5c401845b15a939f5efa1dc00e91d27370c84c33..ba8d1a842d16079aa641f921097a6444a21132c7 100644 (file)
@@ -392,6 +392,31 @@ class TypeDecoratorComparatorTest(_CustomComparatorTests, fixtures.TestBase):
         return MyInteger
 
 
+class TypeDecoratorTypeDecoratorComparatorTest(
+        _CustomComparatorTests, fixtures.TestBase):
+
+    def _add_override_factory(self):
+
+        class MyIntegerOne(TypeDecorator):
+            impl = Integer
+
+            class comparator_factory(TypeDecorator.Comparator):
+
+                def __init__(self, expr):
+                    self.expr = expr
+
+                def __add__(self, other):
+                    return self.expr.op("goofy")(other)
+
+                def __and__(self, other):
+                    return self.expr.op("goofy_and")(other)
+
+        class MyIntegerTwo(TypeDecorator):
+            impl = MyIntegerOne
+
+        return MyIntegerTwo
+
+
 class TypeDecoratorWVariantComparatorTest(
         _CustomComparatorTests,
         fixtures.TestBase):