From c357769d28b2be206892ba6023020ffce9b5f9c5 Mon Sep 17 00:00:00 2001 From: Ilya Skriblovsky Date: Thu, 4 Jun 2015 22:56:05 +0300 Subject: [PATCH 1/3] Using WriteConcern from pymongo --- docs/source/NEWS.rst | 3 +- tests/test_queries.py | 2 +- tests/test_write_concern.py | 2 +- txmongo/collection.py | 2 +- txmongo/connection.py | 2 +- txmongo/write_concern.py | 115 ------------------------------------ 6 files changed, 5 insertions(+), 121 deletions(-) delete mode 100644 txmongo/write_concern.py diff --git a/docs/source/NEWS.rst b/docs/source/NEWS.rst index ce1a23b4..dd50d3b5 100644 --- a/docs/source/NEWS.rst +++ b/docs/source/NEWS.rst @@ -32,8 +32,7 @@ Features or by URI options. - Write-concern options can also be set for ``Database`` and ``Collection`` with ``write_concern`` named argument of their constructors. In this case write-concern is specified by instance of - ``txmongo.write_concern.WriteConcern`` class which is the same as - ``pymongo.write_concern.WriteConcern`` of PyMongo 3.0. + ``pymongo.write_concern.WriteConcern`` - ``txmongo.protocol.INSERT_CONTINUE_ON_ERROR`` flag defined for using with ``insert()`` - Replaced all traditional deferred callbacks (and errbacks) to use @defer.inlineCallbacks diff --git a/tests/test_queries.py b/tests/test_queries.py index 7396fd1e..da198357 100644 --- a/tests/test_queries.py +++ b/tests/test_queries.py @@ -19,11 +19,11 @@ from pymongo.results import InsertOneResult, InsertManyResult, UpdateResult, \ DeleteResult from pymongo.collection import ReturnDocument +from pymongo.write_concern import WriteConcern from twisted.internet import defer from twisted.trial import unittest import txmongo from txmongo.protocol import MongoClientProtocol -from txmongo.write_concern import WriteConcern import txmongo.filter as qf mongo_host = "localhost" diff --git a/tests/test_write_concern.py b/tests/test_write_concern.py index bd639361..9c80f177 100644 --- a/tests/test_write_concern.py +++ b/tests/test_write_concern.py @@ -15,13 +15,13 @@ from mock import Mock, patch from pymongo.errors import ConfigurationError +from pymongo.write_concern import WriteConcern from twisted.internet import defer from twisted.trial import unittest from txmongo.connection import MongoConnection, ConnectionPool from txmongo.protocol import MongoProtocol from txmongo.database import Database from txmongo.collection import Collection -from txmongo.write_concern import WriteConcern mongo_host = "localhost" mongo_port = 27017 diff --git a/txmongo/collection.py b/txmongo/collection.py index e9bec76b..520902b7 100644 --- a/txmongo/collection.py +++ b/txmongo/collection.py @@ -15,11 +15,11 @@ from pymongo.common import validate_ok_for_update, validate_ok_for_replace, \ validate_is_mapping, validate_boolean from pymongo.collection import ReturnDocument +from pymongo.write_concern import WriteConcern from txmongo import filter as qf from txmongo.protocol import DELETE_SINGLE_REMOVE, UPDATE_UPSERT, UPDATE_MULTI, \ Query, Getmore, Insert, Update, Delete, KillCursors, INSERT_CONTINUE_ON_ERROR from twisted.internet import defer -from txmongo.write_concern import WriteConcern class Collection(object): diff --git a/txmongo/connection.py b/txmongo/connection.py index 3aa7d924..4b3437ba 100755 --- a/txmongo/connection.py +++ b/txmongo/connection.py @@ -5,6 +5,7 @@ from pymongo.errors import AutoReconnect, ConfigurationError, OperationFailure from pymongo.uri_parser import parse_uri from pymongo.read_preferences import ReadPreference +from pymongo.write_concern import WriteConcern from twisted.internet import defer, reactor, task from twisted.internet.protocol import ReconnectingClientFactory @@ -12,7 +13,6 @@ from txmongo.database import Database from txmongo.protocol import MongoProtocol, Query -from txmongo.write_concern import WriteConcern # PyMongo 2.x defines ReadPreference.XXX as ints while 3.0 defines them # as objects with `mode` integer attribute diff --git a/txmongo/write_concern.py b/txmongo/write_concern.py deleted file mode 100644 index 5d3efd32..00000000 --- a/txmongo/write_concern.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2014-2015 MongoDB, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tools for working with write concerns.""" - -# TxMongo Note: -# This module is a copy of pymongo/write_concern.py from PyMongo 3.0 -# Copied for PyMongo 2.8 support - -# PyMongo 2.8 doesn't have these variables, so we hardcode them -# from bson.py3compat import integer_types, string_type -integer_types = (int, long) -string_type = basestring - -from pymongo.errors import ConfigurationError - -class WriteConcern(object): - """WriteConcern - - :Parameters: - - `w`: (integer or string) Used with replication, write operations - will block until they have been replicated to the specified number - or tagged set of servers. `w=` always includes the replica - set primary (e.g. w=3 means write to the primary and wait until - replicated to **two** secondaries). **w=0 disables acknowledgement - of write operations and can not be used with other write concern - options.** - - `wtimeout`: (integer) Used in conjunction with `w`. Specify a value - in milliseconds to control how long to wait for write propagation - to complete. If replication does not complete in the given - timeframe, a timeout exception is raised. - - `j`: If ``True`` block until write operations have been committed - to the journal. Cannot be used in combination with `fsync`. Prior - to MongoDB 2.6 this option was ignored if the server was running - without journaling. Starting with MongoDB 2.6 write operations will - fail with an exception if this option is used when the server is - running without journaling. - - `fsync`: If ``True`` and the server is running without journaling, - blocks until the server has synced all data files to disk. If the - server is running with journaling, this acts the same as the `j` - option, blocking until write operations have been committed to the - journal. Cannot be used in combination with `j`. - """ - - __slots__ = ("__document", "__acknowledged") - - def __init__(self, w=None, wtimeout=None, j=None, fsync=None): - self.__document = {} - self.__acknowledged = True - - if wtimeout is not None: - if not isinstance(wtimeout, integer_types): - raise TypeError("wtimeout must be an integer") - self.__document["wtimeout"] = wtimeout - - if j is not None: - if not isinstance(j, bool): - raise TypeError("j must be True or False") - self.__document["j"] = j - - if fsync is not None: - if not isinstance(fsync, bool): - raise TypeError("fsync must be True or False") - if j and fsync: - raise ConfigurationError("Can't set both j " - "and fsync at the same time") - self.__document["fsync"] = fsync - - if self.__document and w == 0: - raise ConfigurationError("Can not use w value " - "of 0 with other options") - if w is not None: - if isinstance(w, integer_types): - self.__acknowledged = w > 0 - elif not isinstance(w, string_type): - raise TypeError("w must be an integer or string") - self.__document["w"] = w - - @property - def document(self): - """The document representation of this write concern. - - .. note:: - :class:`WriteConcern` is immutable. Mutating the value of - :attr:`document` does not mutate this :class:`WriteConcern`. - """ - return self.__document.copy() - - @property - def acknowledged(self): - """If ``True`` write operations will wait for acknowledgement before - returning. - """ - return self.__acknowledged - - def __repr__(self): - return ("WriteConcern(%s)" % ( - ", ".join("%s=%s" % kvt for kvt in self.document.items()),)) - - def __eq__(self, other): - return self.document == other.document - - def __ne__(self, other): - return self.document != other.document From c84b7b98c7aa3962501ba081c32cfc4291a41210 Mon Sep 17 00:00:00 2001 From: Ilya Skriblovsky Date: Thu, 4 Jun 2015 22:59:27 +0300 Subject: [PATCH 2/3] workarounds for PyMongo 2.x removed --- txmongo/collection.py | 10 ++-------- txmongo/connection.py | 11 +++-------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/txmongo/collection.py b/txmongo/collection.py index 520902b7..1ec83c6f 100644 --- a/txmongo/collection.py +++ b/txmongo/collection.py @@ -189,14 +189,8 @@ def after_reply(reply, proto, fetched=0): docs_count = min(docs_count, limit - fetched) fetched += docs_count - try: - # as_class is removed from PyMongo >= 3.0 - # trying to use CodecOptions instead - options = bson.codec_options.CodecOptions(document_class=as_class) - out = [document.decode(codec_options=options) for document in documents[:docs_count]] - except AttributeError: - # Falling back to as_class for PyMongo < 3.0 - out = [document.decode(as_class=as_class) for document in documents[:docs_count]] + options = bson.codec_options.CodecOptions(document_class=as_class) + out = [document.decode(codec_options=options) for document in documents[:docs_count]] if reply.cursor_id: if limit == 0: diff --git a/txmongo/connection.py b/txmongo/connection.py index 4b3437ba..825afc28 100755 --- a/txmongo/connection.py +++ b/txmongo/connection.py @@ -14,14 +14,9 @@ from txmongo.database import Database from txmongo.protocol import MongoProtocol, Query -# PyMongo 2.x defines ReadPreference.XXX as ints while 3.0 defines them -# as objects with `mode` integer attribute -try: - _PRIMARY_READ_PREFERENCES = set([ReadPreference.PRIMARY.mode, - ReadPreference.PRIMARY_PREFERRED.mode]) -except AttributeError: - _PRIMARY_READ_PREFERENCES = set([ReadPreference.PRIMARY, - ReadPreference.PRIMARY_PREFERRED]) + +_PRIMARY_READ_PREFERENCES = set([ReadPreference.PRIMARY.mode, + ReadPreference.PRIMARY_PREFERRED.mode]) class _Connection(ReconnectingClientFactory): From d81649cb0ce51f63c69aef30c7cfe13fba10518f Mon Sep 17 00:00:00 2001 From: Ilya Skriblovsky Date: Thu, 4 Jun 2015 23:03:29 +0300 Subject: [PATCH 3/3] TestWriteConcernClass testcase removed --- tests/test_write_concern.py | 49 ------------------------------------- 1 file changed, 49 deletions(-) diff --git a/tests/test_write_concern.py b/tests/test_write_concern.py index 9c80f177..a8f18e3d 100644 --- a/tests/test_write_concern.py +++ b/tests/test_write_concern.py @@ -151,52 +151,3 @@ def test_ConnectionUrlParams(self): finally: yield coll.drop() yield conn.disconnect() - - -class TestWriteConcernClass(unittest.TestCase): - - def test_wtimeout(self): - wc = WriteConcern(wtimeout=123) - self.assertEqual(wc.document['wtimeout'], 123) - - self.assertRaises(TypeError, WriteConcern, wtimeout=123.456) - - def test_j(self): - wc = WriteConcern(j=True) - self.assertEqual(wc.document['j'], True) - - self.assertRaises(TypeError, WriteConcern, j=1) - - def test_fsync(self): - wc = WriteConcern(fsync=True) - self.assertEqual(wc.document['fsync'], True) - - self.assertRaises(TypeError, WriteConcern, fsync=1) - # Can't set both j and fsync - self.assertRaises(ConfigurationError, WriteConcern, j=True, fsync=True) - - def test_w(self): - WriteConcern(w=0) - - # Can't set w=0 with any other options - self.assertRaises(ConfigurationError, WriteConcern, w=0, j=True) - self.assertRaises(ConfigurationError, WriteConcern, w=0, wtimeout=100) - self.assertRaises(ConfigurationError, WriteConcern, w=0, fsync=True) - - self.assertRaises(TypeError, WriteConcern, w=1.5) - - def test_repr(self): - self.assertEqual(repr(WriteConcern()), "WriteConcern()") - self.assertEqual(repr(WriteConcern(w=2)), "WriteConcern(w=2)") - self.assertEqual(repr(WriteConcern(fsync=True)), "WriteConcern(fsync=True)") - - multiopt = repr(WriteConcern(w=2, wtimeout=500, fsync=True)) - self.assertTrue(multiopt.startswith("WriteConcern(")) - self.assertTrue(multiopt.endswith(')')) - inner = multiopt[13:-1] - self.assertEqual(set(inner.split(", ")), set(["w=2", "wtimeout=500", "fsync=True"])) - - def test_cmp(self): - self.assertEqual(WriteConcern(w=2, wtimeout=500), WriteConcern(wtimeout=500, w=2)) - self.assertNotEqual(WriteConcern(w=2, wtimeout=500), - WriteConcern(wtimeout=500, w=2, j=True))