Skip to content
This repository
Browse code

Negation was not being cloned properly on Q() objects. Additionally I

decided to add parens around negated Q() expressions.
  • Loading branch information...
commit cdc3fbc7f69f04f0a9f64f8662fadb11198c31dd 1 parent 50728f2
Charles Leifer authored

Showing 2 changed files with 17 additions and 6 deletions. Show diff stats Hide diff stats

  1. 10  peewee.py
  2. 13  tests.py
10  peewee.py
@@ -168,11 +168,11 @@ def __invert__(self):
168 168
 
169 169
 class Q(Leaf):
170 170
     def __init__(self, lhs, op, rhs, negated=False):
  171
+        super(Q, self).__init__()
171 172
         self.lhs = lhs
172 173
         self.op = op
173 174
         self.rhs = rhs
174 175
         self.negated = negated
175  
-        super(Q, self).__init__()
176 176
 
177 177
     def clone(self):
178 178
         return Q(self.lhs, self.op, self.rhs, self.negated)
@@ -180,8 +180,8 @@ def clone(self):
180 180
 
181 181
 class DQ(Leaf):
182 182
     def __init__(self, **query):
183  
-        self.query = query
184 183
         super(DQ, self).__init__()
  184
+        self.query = query
185 185
 
186 186
     def clone(self):
187 187
         return DQ(**self.query)
@@ -707,8 +707,10 @@ def parse_expr(self, expr, alias_map=None):
707 707
     def parse_q(self, q, alias_map=None):
708 708
         lhs_expr, lparams = self.parse_expr(q.lhs, alias_map)
709 709
         rhs_expr, rparams = self.parse_expr(q.rhs, alias_map)
710  
-        not_expr = q.negated and 'NOT ' or ''
711  
-        return '%s%s %s %s' % (not_expr, lhs_expr, self.get_op(q.op), rhs_expr), lparams + rparams
  710
+        parsed = '%s %s %s' % (lhs_expr, self.get_op(q.op), rhs_expr)
  711
+        if q.negated:
  712
+            parsed = '(NOT %s)' % parsed
  713
+        return parsed, lparams + rparams
712 714
 
713 715
     def parse_node(self, n, alias_map=None):
714 716
         query = []
13  tests.py
@@ -401,7 +401,7 @@ def test_where_fk(self):
401 401
 
402 402
     def test_where_negation(self):
403 403
         sq = SelectQuery(Blog).where(~(Blog.title == 'foo'))
404  
-        self.assertWhere(sq, 'NOT blog."title" = ?', ['foo'])
  404
+        self.assertWhere(sq, '(NOT blog."title" = ?)', ['foo'])
405 405
 
406 406
         sq = SelectQuery(Blog).where(~((Blog.title == 'foo') | (Blog.title == 'bar')))
407 407
         self.assertWhere(sq, '(NOT (blog."title" = ? OR blog."title" = ?))', ['foo', 'bar'])
@@ -429,7 +429,7 @@ def test_where_chaining_collapsing(self):
429 429
         self.assertWhere(sq, '(users."id" = ?) AND (users."id" = ? OR users."id" = ?)', [1, 2, 3])
430 430
 
431 431
         sq = SelectQuery(User).where(~(User.id == 1)).where(User.id == 2).where(~(User.id == 3))
432  
-        self.assertWhere(sq, '(users."id" = ? AND users."id" = ?) AND NOT users."id" = ?', [1, 2, 3])
  432
+        self.assertWhere(sq, '((NOT users."id" = ?) AND users."id" = ?) AND (NOT users."id" = ?)', [1, 2, 3])
433 433
 
434 434
     def test_grouping(self):
435 435
         sq = SelectQuery(User).group_by(User.id)
@@ -1130,6 +1130,15 @@ def assertNM(self, q, exp):
1130 1130
         query = NullModel.select().where(q).order_by(NullModel.id)
1131 1131
         self.assertEqual([nm.char_field for nm in query], exp)
1132 1132
 
  1133
+    def test_null_query(self):
  1134
+        NullModel.delete().execute()
  1135
+        nm1 = NullModel.create(char_field='nm1')
  1136
+        nm2 = NullModel.create(char_field='nm2', int_field=1)
  1137
+        nm3 = NullModel.create(char_field='nm3', int_field=2, float_field=3.0)
  1138
+
  1139
+        q = ~(NullModel.int_field >> None)
  1140
+        self.assertNM(q, ['nm2', 'nm3'])
  1141
+
1133 1142
     def test_field_types(self):
1134 1143
         for field, values in self.field_data.items():
1135 1144
             field_obj = getattr(NullModel, field)

0 notes on commit cdc3fbc

Please sign in to comment.
Something went wrong with that request. Please try again.