From 93bcbff92840fbf83746309bce39290c86988d17 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 26 Apr 2012 11:58:54 -0400 Subject: [PATCH] - [bug] Fixed bug in relationship comparisons whereby calling unimplemented methods like SomeClass.somerelationship.like() would produce a recursion overflow, instead of NotImplementedError. --- CHANGES | 6 ++++++ lib/sqlalchemy/orm/properties.py | 6 ------ lib/sqlalchemy/sql/operators.py | 6 +++--- test/orm/test_query.py | 10 ++++++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 7dc9e8300f..354120a420 100644 --- a/CHANGES +++ b/CHANGES @@ -41,6 +41,12 @@ CHANGES OrderingList from being pickleable [ticket:2454]. Courtesy Jeff Dairiki + - [bug] Fixed bug in relationship comparisons + whereby calling unimplemented methods like + SomeClass.somerelationship.like() would + produce a recursion overflow, instead + of NotImplementedError. + - sql - [bug] Removed warning when Index is created with no columns; while this might not be what diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 74ccf0157f..f2186df511 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -323,12 +323,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. diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index 89f0aaee13..3fcbf7cf97 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -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() diff --git a/test/orm/test_query.py b/test/orm/test_query.py index bcc9768165..3f1035599d 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -603,6 +603,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 -- 2.47.2