From 5bd1938694df557033cee81a72614c01bd20a44f Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 25 Apr 2012 10:38:24 -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 d7b09c9ce5..67737cc3fb 100644 --- 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 diff --git a/lib/sqlalchemy/orm/properties.py b/lib/sqlalchemy/orm/properties.py index 79676642c5..9a2d057545 100644 --- a/lib/sqlalchemy/orm/properties.py +++ b/lib/sqlalchemy/orm/properties.py @@ -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. diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index b86b50db44..0c779ec433 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 be0e1c3be2..9073f10569 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -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 -- 2.47.3