From fab611f63cdbe2a763c617e4ba3907a512b3e756 Mon Sep 17 00:00:00 2001 From: "A. Jesse Jiryu Davis" Date: Thu, 20 Nov 2014 23:27:17 -0500 Subject: [PATCH] PYTHON-785 Don't use requests in GridFS. --- gridfs/__init__.py | 15 ++++++--------- gridfs/grid_file.py | 29 ++++++++--------------------- test/test_grid_file.py | 10 +++++++++- test/test_gridfs.py | 15 +++++++++++++-- 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/gridfs/__init__.py b/gridfs/__init__.py index 6b1b9faa8..196479635 100644 --- a/gridfs/__init__.py +++ b/gridfs/__init__.py @@ -118,19 +118,16 @@ class GridFS(object): :Parameters: - `data`: data to be written as a file. - `**kwargs` (optional): keyword arguments for file creation + + .. versionchanged:: 3.0 + w=0 writes to GridFS are now prohibited. """ grid_file = GridIn(self.__collection, **kwargs) - - # Start a request - necessary if w=0, harmless otherwise - request = self.__collection.database.connection.start_request() try: - try: - grid_file.write(data) - finally: - grid_file.close() + grid_file.write(data) finally: - # Ensure request is ended even if close() throws error - request.end() + grid_file.close() + return grid_file._id def get(self, file_id): diff --git a/gridfs/grid_file.py b/gridfs/grid_file.py index 69e6d6fc0..993a8e788 100644 --- a/gridfs/grid_file.py +++ b/gridfs/grid_file.py @@ -27,7 +27,7 @@ from gridfs.errors import (CorruptGridFile, from pymongo import ASCENDING from pymongo.collection import Collection from pymongo.cursor import Cursor -from pymongo.errors import DuplicateKeyError +from pymongo.errors import DuplicateKeyError, InvalidOperation from pymongo.read_preferences import ReadPreference try: @@ -130,29 +130,12 @@ class GridIn(object): that is written to the file will be converted to :class:`bytes`. - If you turn off write-acknowledgment for performance reasons, it is - critical to wrap calls to :meth:`write` and :meth:`close` within a - single request: - - >>> from pymongo import MongoClient - >>> from gridfs import GridFS - >>> client = MongoClient(w=0) # turn off write acknowledgment - >>> fs = GridFS(client.database) - >>> gridin = fs.new_file() - >>> request = client.start_request() - >>> try: - ... for i in range(10): - ... gridin.write('foo') - ... gridin.close() - ... finally: - ... request.end() - - In Python 2.5 and later this code can be simplified with a - with-statement, see :doc:`/examples/requests` for more information. - :Parameters: - `root_collection`: root collection to write to - `**kwargs` (optional): file level options (see above) + + .. versionchanged:: 3.0 + w=0 writes to GridFS are now prohibited. """ if not isinstance(root_collection, Collection): raise TypeError("root_collection must be an " @@ -321,6 +304,10 @@ class GridIn(object): if self._closed: raise ValueError("cannot write to a closed file") + # With w=0, 'filemd5' might run before the final chunks are written. + if 0 == self._coll.database.connection.write_concern.get('w'): + raise InvalidOperation('Cannot write file to GridFS with w=0') + try: # file-like read = data.read diff --git a/test/test_grid_file.py b/test/test_grid_file.py index 21502175a..ed951e6c2 100644 --- a/test/test_grid_file.py +++ b/test/test_grid_file.py @@ -32,13 +32,14 @@ from gridfs.grid_file import (DEFAULT_CHUNK_SIZE, GridOutCursor) from gridfs.errors import NoFile from pymongo import MongoClient -from pymongo.errors import ConnectionFailure +from pymongo.errors import ConnectionFailure, InvalidOperation from test import (client_knobs, IntegrationTest, host, port, unittest, qcheck) +from test.utils import rs_or_single_client class TestGridFileNoConnect(unittest.TestCase): @@ -609,6 +610,13 @@ Bye""")) self.assertRaises(ConnectionFailure, infile.write, b'data') self.assertRaises(ConnectionFailure, infile.close) + def test_unacknowledged(self): + # w=0 is prohibited. + infile = GridIn(rs_or_single_client(w=0).pymongo_test.fs) + + with self.assertRaises(InvalidOperation): + infile.write(b'data') + if __name__ == "__main__": unittest.main() diff --git a/test/test_gridfs.py b/test/test_gridfs.py index b5d455bb3..3d9f70ef5 100644 --- a/test/test_gridfs.py +++ b/test/test_gridfs.py @@ -26,7 +26,7 @@ import gridfs from bson.py3compat import u, StringIO, string_type from pymongo.mongo_client import MongoClient -from pymongo.errors import ConnectionFailure +from pymongo.errors import ConnectionFailure, InvalidOperation from pymongo.read_preferences import ReadPreference from gridfs.errors import (FileExists, NoFile) @@ -37,7 +37,11 @@ from test import (client_context, host, port, IntegrationTest) -from test.utils import joinall, single_client, one, rs_client +from test.utils import (joinall, + single_client, + one, + rs_client, + rs_or_single_client) class JustWrite(threading.Thread): @@ -426,6 +430,13 @@ class TestGridfs(IntegrationTest): self.assertEqual(data, self.fs.get_version('f').read()) + def test_unacknowledged(self): + # w=0 is prohibited. + fs = gridfs.GridFS(rs_or_single_client(w=0).pymongo_test) + + with self.assertRaises(InvalidOperation): + fs.put(b'data') + class TestGridfsReplicaSet(TestReplicaSetClientBase):