Repository: MongoEngine/mongoengine

Issue:
queryset transform tries to update query dictionary with regex pattern
> > > ResultRecord.objects(Q( defects__number__iexact='FFF-10219') & Q(defects__number__exists=True))
> > > Traceback (most recent call last):
> > >   File "<stdin>", line 1, in <module>
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/queryset.py", line 58, in **repr**
> > >     self._populate_cache()
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/queryset.py", line 93, in _populate_cache
> > >     self._result_cache.append(self.next())
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/base.py", line 1137, in next
> > >     raw_doc = self._cursor.next()
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/base.py", line 1182, in _cursor
> > >     self._cursor_obj = self._collection.find(self._query,
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/base.py", line 1215, in _query
> > >     self._mongo_query = self._query_obj.to_query(self._document)
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/visitor.py", line 92, in to_query
> > >     query = query.accept(QueryCompilerVisitor(document))
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/visitor.py", line 157, in accept
> > >     return visitor.visit_query(self)
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/visitor.py", line 80, in visit_query
> > >     return transform.query(self.document, **query.query)
> > >   File "/usr/local/lib/python2.7/dist-packages/mongoengine/queryset/transform.py", line 116, in query
> > >     mongo_query[key].update(value)
> > > TypeError: '_sre.SRE_Pattern' object is not iterable



Discussion:
@aeroeng, could you please provide a test that reproduces this error?


Resolving patch:
diff --git a/mongoengine/queryset/transform.py b/mongoengine/queryset/transform.py
--- a/mongoengine/queryset/transform.py
+++ b/mongoengine/queryset/transform.py
@@ -147,7 +147,7 @@ def query(_doc_cls=None, **kwargs):
         if op is None or key not in mongo_query:
             mongo_query[key] = value
         elif key in mongo_query:
-            if isinstance(mongo_query[key], dict):
+            if isinstance(mongo_query[key], dict) and isinstance(value, dict):
                 mongo_query[key].update(value)
                 # $max/minDistance needs to come last - convert to SON
                 value_dict = mongo_query[key]


Test patch:
diff --git a/tests/queryset/queryset.py b/tests/queryset/queryset.py
--- a/tests/queryset/queryset.py
+++ b/tests/queryset/queryset.py
@@ -1202,6 +1202,14 @@ def published(doc_cls, queryset):
         BlogPost.drop_collection()
         Blog.drop_collection()
 
+    def test_filter_chaining_with_regex(self):
+        person = self.Person(name='Guido van Rossum')
+        person.save()
+
+        people = self.Person.objects
+        people = people.filter(name__startswith='Gui').filter(name__not__endswith='tum')
+        self.assertEqual(people.count(), 1)
+
     def assertSequence(self, qs, expected):
         qs = list(qs)
         expected = list(expected)