]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [bug] Fixed bug in relationship comparisons
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 25 Apr 2012 14:38:24 +0000 (10:38 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 25 Apr 2012 14:38:24 +0000 (10:38 -0400)
whereby calling unimplemented methods like
SomeClass.somerelationship.like() would
produce a recursion overflow, instead
of NotImplementedError.

CHANGES
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/sql/operators.py
test/orm/test_query.py

diff --git a/CHANGES b/CHANGES
index d7b09c9ce5d23bbce10b421bbc55fe404650ebf6..67737cc3fb4f174cf26d36615b196eefc5503fba 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -71,6 +71,12 @@ CHANGES
     set of objects that weren't modified in 
     that sub-transaction.  [ticket:2452]
 
+  - [bug] Fixed bug in relationship comparisons
+    whereby calling unimplemented methods like
+    SomeClass.somerelationship.like() would
+    produce a recursion overflow, instead
+    of NotImplementedError.
+
   - [bug] The "passive" flag on Session.is_modified()
     no longer has any effect. is_modified() in 
     all cases looks only at local in-memory
index 79676642c5f78cbf5eb2af7fccb9b902f94f91c8..9a2d057545929c43640882684bb09750020c660b 100644 (file)
@@ -329,12 +329,6 @@ class RelationshipProperty(StrategizedProperty):
             else:
                 return elem
 
-        def operate(self, op, *other, **kwargs):
-            return op(self, *other, **kwargs)
-
-        def reverse_operate(self, op, other, **kwargs):
-            return op(self, *other, **kwargs)
-
         def of_type(self, cls):
             """Produce a construct that represents a particular 'subtype' of
             attribute for the parent class.
index b86b50db445daadad4b41c863a1f73b802c033cb..0c779ec4331147058bf2a8960cf910b88529eb7e 100644 (file)
@@ -469,13 +469,13 @@ def like_op(a, b, escape=None):
     return a.like(b, escape=escape)
 
 def notlike_op(a, b, escape=None):
-    raise NotImplementedError()
+    return ~a.like(b, escape=escape)
 
 def ilike_op(a, b, escape=None):
     return a.ilike(b, escape=escape)
 
 def notilike_op(a, b, escape=None):
-    raise NotImplementedError()
+    return ~a.ilike(b, escape=escape)
 
 def between_op(a, b, c):
     return a.between(b, c)
@@ -484,7 +484,7 @@ def in_op(a, b):
     return a.in_(b)
 
 def notin_op(a, b):
-    raise NotImplementedError()
+    return ~a.in_(b)
 
 def distinct_op(a):
     return a.distinct()
index be0e1c3be267168276cbcb9cf4266fe3b1a1b509..9073f105698aecf040bab19cdf55549fe8e00a89 100644 (file)
@@ -565,6 +565,16 @@ class OperatorTest(QueryTest, AssertsCompiledSQL):
         self._test(None == Address.user, "addresses.user_id IS NULL")
         self._test(~(None == Address.user), "addresses.user_id IS NOT NULL")
 
+    def test_relationship_unimplemented(self):
+        User, Address = self.classes.User, self.classes.Address
+        for op in [
+            User.addresses.like,
+            User.addresses.ilike,
+            User.addresses.__le__,
+            User.addresses.__gt__,
+        ]:
+            assert_raises(NotImplementedError, op, "x")
+
     def test_relationship(self):
         User, Address = self.classes.User, self.classes.Address