Repository: TurboGears/Ming

Issue:
mim Cursor needs close() method
A couple errors like this from the Allura test suite, when going from pymongo 3.7.2 to pymongo 3.8 (on ming master):
```
  File "/Users/brondsem/sf/allura/Allura/allura/ext/admin/admin_main.py", line 412, in update
    c.project.save_icon(icon.filename, icon.file, content_type=icon.type)
  File "/Users/brondsem/sf/allura/Allura/allura/model/project.py", line 376, in save_icon
    icon_orig_img = PIL.Image.open(icon_orig.rfile())
  File "/Users/brondsem/sf/env-allura/lib/python2.7/site-packages/PIL/Image.py", line 2804, in open
    im = _open_core(fp, filename, prefix)
  File "/Users/brondsem/sf/env-allura/lib/python2.7/site-packages/PIL/Image.py", line 2789, in _open_core
    fp.seek(0)
  File "/Users/brondsem/sf/env-allura/lib/python2.7/site-packages/gridfs/grid_file.py", line 643, in seek
    self.__chunk_iter.close()
  File "/Users/brondsem/sf/env-allura/lib/python2.7/site-packages/gridfs/grid_file.py", line 778, in close
    self._cursor.close()
AttributeError: 'Cursor' object has no attribute 'close'
```

Discussion:

Patch:
diff --git a/ming/mim.py b/ming/mim.py
index ef553f6..2c4aaa8 100644
--- a/ming/mim.py
+++ b/ming/mim.py
@@ -822,6 +822,9 @@ class Cursor(object):
         # Adding options to MIM does nothing.
         pass
 
+    def close(self):
+        self._iterator_gen = lambda: iter(())
+
 
 def cursor_comparator(keys):
     def comparator(a, b):


Test patch:
diff --git a/ming/tests/test_mim.py b/ming/tests/test_mim.py
index edb8a9d..bb7cf2b 100644
--- a/ming/tests/test_mim.py
+++ b/ming/tests/test_mim.py
@@ -159,6 +159,13 @@ class TestDatastore(TestCase):
         cursor.rewind()
         assert cursor.next() == doc
 
+    def test_close(self):
+        collection = self.bind.db.coll
+        collection.insert({'a': 'b'})
+        cursor = collection.find()
+        cursor.close()
+        self.assertRaises(StopIteration, cursor.next)
+
     def test_search(self):
         conn = mim.Connection().get()
         coll = conn.searchdatabase.coll