PYTHON-1527 - Fix default writeConcern override

This commit is contained in:
Bernie Hackett 2018-06-03 16:31:27 -07:00
parent 8cc2f72e20
commit dbf386c18c
7 changed files with 25 additions and 13 deletions

View File

@ -263,7 +263,7 @@ class _Bulk(object):
while run:
cmd = SON([(_COMMANDS[run.op_type], self.collection.name),
('ordered', self.ordered)])
if write_concern.document:
if not write_concern.is_server_default:
cmd['writeConcern'] = write_concern.document
if self.bypass_doc_val and sock_info.max_wire_version >= 4:
cmd['bypassDocumentValidation'] = True

View File

@ -2078,7 +2078,7 @@ class Collection(common.BaseObject):
kwargs["cursor"]["batchSize"] = first_batch_size
if (sock_info.max_wire_version >= 5 and dollar_out and
self.write_concern):
not self.write_concern.is_server_default):
cmd['writeConcern'] = self.write_concern.document
cmd.update(kwargs)
@ -2403,7 +2403,8 @@ class Collection(common.BaseObject):
cmd = SON([("renameCollection", self.__full_name), ("to", new_name)])
with self._socket_for_writes() as sock_info:
with self.__database.client._tmp_session(session) as s:
if sock_info.max_wire_version >= 5 and self.write_concern:
if (sock_info.max_wire_version >= 5 and
not self.write_concern.is_server_default):
cmd['writeConcern'] = self.write_concern.document
cmd.update(kwargs)
return sock_info.command(
@ -2530,7 +2531,8 @@ class Collection(common.BaseObject):
inline = 'inline' in cmd['out']
sock_ctx, read_pref = self._socket_for_primary_reads(session)
with sock_ctx as (sock_info, slave_ok):
if (sock_info.max_wire_version >= 5 and self.write_concern and
if (sock_info.max_wire_version >= 5 and
not self.write_concern.is_server_default and
not inline):
cmd['writeConcern'] = self.write_concern.document
cmd.update(kwargs)

View File

@ -412,7 +412,9 @@ class Database(common.BaseObject):
if isinstance(command, string_type):
command = SON([(command, value)])
if sock_info.max_wire_version >= 5 and write_concern:
if (sock_info.max_wire_version >= 5 and
write_concern and
not write_concern.is_server_default):
command['writeConcern'] = write_concern.document
command.update(kwargs)

View File

@ -535,7 +535,9 @@ class SocketInfo(object):
collation is None):
raise ConfigurationError(
'Collation is unsupported for unacknowledged writes.')
if self.max_wire_version >= 5 and write_concern:
if (self.max_wire_version >= 5 and
write_concern and
not write_concern.is_server_default):
spec['writeConcern'] = write_concern.document
elif self.max_wire_version < 5 and collation is not None:
raise ConfigurationError(

View File

@ -46,7 +46,7 @@ class WriteConcern(object):
journal. Cannot be used in combination with `j`.
"""
__slots__ = ("__document", "__acknowledged")
__slots__ = ("__document", "__acknowledged", "__server_default")
def __init__(self, w=None, wtimeout=None, j=None, fsync=None):
self.__document = {}
@ -84,6 +84,13 @@ class WriteConcern(object):
raise TypeError("w must be an integer or string")
self.__document["w"] = w
self.__server_default = not self.__document
@property
def is_server_default(self):
"""Does this WriteConcern match the server default."""
return self.__server_default
@property
def document(self):
"""The document representation of this write concern.
@ -110,8 +117,3 @@ class WriteConcern(object):
def __ne__(self, other):
return self.__document != other.document
def __bool__(self):
return bool(self.__document)
__nonzero__ = __bool__ # Python 2.

View File

@ -155,6 +155,10 @@ class TestCommon(IntegrationTest):
wc = WriteConcern(w=2, wtimeout=1000)
self.assertEqual(wc, c.write_concern)
# Can we override back to the server default?
db = c.get_database('pymongo_test', write_concern=WriteConcern())
self.assertEqual(db.write_concern, WriteConcern())
db = c.pymongo_test
self.assertEqual(wc, db.write_concern)
coll = db.test

View File

@ -232,7 +232,7 @@ def create_document_test(test_case):
self.assertEqual(
concern.acknowledged, test_case['isAcknowledged'])
self.assertEqual(
not bool(concern), test_case['isServerDefault'])
concern.is_server_default, test_case['isServerDefault'])
if 'readConcern' in test_case:
# Any string for 'level' is equaly valid
concern = ReadConcern(**test_case['readConcern'])