PYTHON-2164 Add MongoClient.options, remove redundant properties (#772)

This commit is contained in:
Shane Harvey 2021-11-03 11:21:33 -07:00 committed by GitHub
parent 9f6c6a3061
commit b342990934
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 159 additions and 149 deletions

View File

@ -0,0 +1,7 @@
:mod:`client_options` -- Read only configuration options for a MongoClient.
===========================================================================
.. automodule:: pymongo.client_options
.. autoclass:: pymongo.client_options.ClientOptions()
:members:

View File

@ -29,6 +29,7 @@ Sub-modules:
bulk
change_stream
client_options
client_session
collation
collection

View File

@ -14,7 +14,6 @@
Raises :class:`~pymongo.errors.InvalidName` if an invalid database name is used.
.. autoattribute:: event_listeners
.. autoattribute:: topology_description
.. autoattribute:: address
.. autoattribute:: primary
@ -22,16 +21,12 @@
.. autoattribute:: arbiters
.. autoattribute:: is_primary
.. autoattribute:: is_mongos
.. autoattribute:: max_pool_size
.. autoattribute:: min_pool_size
.. autoattribute:: max_idle_time_ms
.. autoattribute:: nodes
.. autoattribute:: local_threshold_ms
.. autoattribute:: server_selection_timeout
.. autoattribute:: codec_options
.. autoattribute:: read_preference
.. autoattribute:: write_concern
.. autoattribute:: read_concern
.. autoattribute:: options
.. automethod:: start_session
.. automethod:: list_databases
.. automethod:: list_database_names

View File

@ -2,5 +2,6 @@
==============================================================
.. automodule:: pymongo.pool
:synopsis: Pool module for use with a MongoDB client.
:members:
.. autoclass:: pymongo.pool.PoolOptions()
:members:

View File

@ -36,6 +36,13 @@ Breaking Changes in 4.0
- Removed :attr:`pymongo.mongo_client.MongoClient.max_bson_size`.
- Removed :attr:`pymongo.mongo_client.MongoClient.max_message_size`.
- Removed :attr:`pymongo.mongo_client.MongoClient.max_write_batch_size`.
- Removed :attr:`pymongo.mongo_client.MongoClient.event_listeners`.
- Removed :attr:`pymongo.mongo_client.MongoClient.max_pool_size`.
- Removed :attr:`pymongo.mongo_client.MongoClient.max_idle_time_ms`.
- Removed :attr:`pymongo.mongo_client.MongoClient.local_threshold_ms`.
- Removed :attr:`pymongo.mongo_client.MongoClient.server_selection_timeout`.
- Removed :attr:`pymongo.mongo_client.MongoClient.retry_writes`.
- Removed :attr:`pymongo.mongo_client.MongoClient.retry_reads`.
- Removed :meth:`pymongo.database.Database.eval`,
:data:`pymongo.database.Database.system_js` and
:class:`pymongo.database.SystemJS`.
@ -180,6 +187,8 @@ Notable improvements
will connect to. More specifically, when a mongodb+srv:// connection string
resolves to more than `srvMaxHosts` number of hosts, the client will randomly
choose a `srvMaxHosts` sized subset of hosts.
- Added :attr:`pymongo.mongo_client.MongoClient.options` for read-only access
to a client's configuration options.
Issues Resolved
...............
@ -2121,7 +2130,7 @@ Important new features:
- The ``max_pool_size`` option for :class:`~pymongo.mongo_client.MongoClient`
and :class:`~pymongo.mongo_replica_set_client.MongoReplicaSetClient` now
actually caps the number of sockets the pool will open concurrently.
Once the pool has reached :attr:`~pymongo.mongo_client.MongoClient.max_pool_size`
Once the pool has reaches max_pool_size
operations will block waiting for a socket to become available. If
``waitQueueTimeoutMS`` is set, an operation that blocks waiting for a socket
will raise :exc:`~pymongo.errors.ConnectionFailure` after the timeout. By

View File

@ -196,6 +196,37 @@ can be changed to this::
.. _hello command: https://docs.mongodb.com/manual/reference/command/hello/
MongoClient.event_listeners and other configuration option helpers are removed
..............................................................................
The following client configuration option helpers are removed:
- :attr:`pymongo.mongo_client.MongoClient.event_listeners`.
- :attr:`pymongo.mongo_client.MongoClient.max_pool_size`.
- :attr:`pymongo.mongo_client.MongoClient.max_idle_time_ms`.
- :attr:`pymongo.mongo_client.MongoClient.local_threshold_ms`.
- :attr:`pymongo.mongo_client.MongoClient.server_selection_timeout`.
- :attr:`pymongo.mongo_client.MongoClient.retry_writes`.
- :attr:`pymongo.mongo_client.MongoClient.retry_reads`.
These helpers have been replaced by
:attr:`pymongo.mongo_client.MongoClient.options`. Code like this::
client.event_listeners
client.local_threshold_ms
client.server_selection_timeout
client.max_pool_size
client.min_pool_size
client.max_idle_time_ms
can be changed to this::
client.options.event_listeners
client.options.local_threshold_ms
client.options.server_selection_timeout
client.options.pool_options.max_pool_size
client.options.pool_options.min_pool_size
client.options.pool_options.max_idle_time_seconds
``tz_aware`` defaults to ``False``
..................................

View File

@ -153,8 +153,12 @@ def _parse_pool_options(options):
class ClientOptions(object):
"""Read only configuration options for a MongoClient.
"""ClientOptions"""
Should not be instantiated directly by application developers. Access
a client's options via :attr:`pymongo.mongo_client.MongoClient.options`
instead.
"""
def __init__(self, username, password, database, options):
self.__options = options
@ -200,7 +204,7 @@ class ClientOptions(object):
return self.__codec_options
@property
def credentials(self):
def _credentials(self):
"""A :class:`~pymongo.auth.MongoCredentials` instance or None."""
return self.__credentials
@ -272,3 +276,13 @@ class ClientOptions(object):
def load_balanced(self):
"""True if the client was configured to connect to a load balancer."""
return self.__load_balanced
@property
def event_listeners(self):
"""The event listeners registered for this client.
See :mod:`~pymongo.monitoring` for details.
.. versionadded:: 4.0
"""
return self.__pool_options._event_listeners.event_listeners()

View File

@ -261,7 +261,7 @@ class _Encrypter(object):
self._internal_client = None
def _get_internal_client(encrypter, mongo_client):
if mongo_client.max_pool_size is None:
if mongo_client.options.pool_options.max_pool_size is None:
# Unlimited pool size, use the same client.
return mongo_client
# Else - limited pool size, use an internal client.

View File

@ -722,14 +722,14 @@ class MongoClient(common.BaseObject):
self.__lock = threading.Lock()
self.__kill_cursors_queue = []
self._event_listeners = options.pool_options.event_listeners
self._event_listeners = options.pool_options._event_listeners
super(MongoClient, self).__init__(options.codec_options,
options.read_preference,
options.write_concern,
options.read_concern)
self.__all_credentials = {}
creds = options.credentials
creds = options._credentials
if creds:
self.__all_credentials[creds.source] = creds
@ -893,14 +893,6 @@ class MongoClient(common.BaseObject):
batch_size, collation, start_at_operation_time, session,
start_after)
@property
def event_listeners(self):
"""The event listeners registered for this client.
See :mod:`~pymongo.monitoring` for details.
"""
return self._event_listeners.event_listeners()
@property
def topology_description(self):
"""The description of the connected MongoDB deployment.
@ -1005,40 +997,6 @@ class MongoClient(common.BaseObject):
"""
return self._server_property('server_type') == SERVER_TYPE.Mongos
@property
def max_pool_size(self):
"""The maximum allowable number of concurrent connections to each
connected server. Requests to a server will block if there are
`maxPoolSize` outstanding connections to the requested server.
Defaults to 100. Can be either 0 or None, in which case there is no
limit on the number of concurrent connections.
When a server's pool has reached `max_pool_size`, operations for that
server block waiting for a socket to be returned to the pool. If
``waitQueueTimeoutMS`` is set, a blocked operation will raise
:exc:`~pymongo.errors.ConnectionFailure` after a timeout.
By default ``waitQueueTimeoutMS`` is not set.
"""
return self.__options.pool_options.max_pool_size
@property
def min_pool_size(self):
"""The minimum required number of concurrent connections that the pool
will maintain to each connected server. Default is 0.
"""
return self.__options.pool_options.min_pool_size
@property
def max_idle_time_ms(self):
"""The maximum number of milliseconds that a connection can remain
idle in the pool before being removed and replaced. Defaults to
`None` (no limit).
"""
seconds = self.__options.pool_options.max_idle_time_seconds
if seconds is None:
return None
return 1000 * seconds
@property
def nodes(self):
"""Set of all currently connected servers.
@ -1054,38 +1012,15 @@ class MongoClient(common.BaseObject):
return frozenset(s.address for s in description.known_servers)
@property
def local_threshold_ms(self):
"""The local threshold for this instance."""
return self.__options.local_threshold_ms
def options(self):
"""The configuration options for this client.
@property
def server_selection_timeout(self):
"""The server selection timeout for this instance in seconds."""
return self.__options.server_selection_timeout
:Returns:
An instance of :class:`~pymongo.client_options.ClientOptions`.
@property
def retry_writes(self):
"""If this instance should retry supported write operations."""
return self.__options.retry_writes
@property
def retry_reads(self):
"""If this instance should retry supported write operations."""
return self.__options.retry_reads
def _is_writable(self):
"""Attempt to connect to a writable server, or return False.
.. versionadded:: 4.0
"""
topology = self._get_topology() # Starts monitors if necessary.
try:
svr = topology.select_server(writable_server_selector)
# When directly connected to a secondary, arbiter, etc.,
# select_server returns it, whatever the selector. Check
# again if the server is writable.
return svr.description.is_writable
except ConnectionFailure:
return False
return self.__options
def _end_sessions(self, session_ids):
"""Send endSessions command(s) with the given session ids."""
@ -1282,7 +1217,7 @@ class MongoClient(common.BaseObject):
Re-raises any exception thrown by func().
"""
retryable = (retryable and self.retry_writes
retryable = (retryable and self.options.retry_writes
and session and not session.in_transaction)
return self._retry_internal(retryable, func, session, bulk)
@ -1353,7 +1288,7 @@ class MongoClient(common.BaseObject):
Re-raises any exception thrown by func().
"""
retryable = (retryable and
self.retry_reads
self.options.retry_reads
and not (session and session.in_transaction))
last_error = None
retrying = False

View File

@ -123,7 +123,7 @@ class Monitor(MonitorBase):
self._server_description = server_description
self._pool = pool
self._settings = topology_settings
self._listeners = self._settings._pool_options.event_listeners
self._listeners = self._settings._pool_options._event_listeners
pub = self._listeners is not None
self._publish = pub and self._listeners.enabled_for_server_heartbeat
self._cancel_context = None

View File

@ -1318,10 +1318,10 @@ class _EventListeners(object):
def event_listeners(self):
"""List of registered event listeners."""
return (self.__command_listeners[:] +
self.__server_heartbeat_listeners[:] +
self.__server_listeners[:] +
self.__topology_listeners[:] +
return (self.__command_listeners +
self.__server_heartbeat_listeners +
self.__server_listeners +
self.__topology_listeners +
self.__cmap_listeners)
def publish_command_start(self, command, database_name,

View File

@ -256,6 +256,17 @@ def _cond_wait(condition, deadline):
class PoolOptions(object):
"""Read only connection pool options for a MongoClient.
Should not be instantiated directly by application developers. Access
a client's pool options via
:attr:`~pymongo.client_options.ClientOptions.pool_options` instead::
pool_opts = client.options.pool_options
pool_opts.max_pool_size
pool_opts.min_pool_size
"""
__slots__ = ('__max_pool_size', '__min_pool_size',
'__max_idle_time_seconds',
@ -394,7 +405,7 @@ class PoolOptions(object):
return self.__wait_queue_timeout
@property
def ssl_context(self):
def _ssl_context(self):
"""An SSLContext instance or None.
"""
return self.__ssl_context
@ -406,7 +417,7 @@ class PoolOptions(object):
return self.__tls_allow_invalid_hostnames
@property
def event_listeners(self):
def _event_listeners(self):
"""An instance of pymongo.monitoring._EventListeners.
"""
return self.__event_listeners
@ -424,7 +435,7 @@ class PoolOptions(object):
return self.__driver
@property
def compression_settings(self):
def _compression_settings(self):
return self.__compression_settings
@property
@ -506,9 +517,9 @@ class SocketInfo(object):
self.hello_ok = None
self.is_mongos = False
self.op_msg_enabled = False
self.listeners = pool.opts.event_listeners
self.listeners = pool.opts._event_listeners
self.enabled_for_cmap = pool.enabled_for_cmap
self.compression_settings = pool.opts.compression_settings
self.compression_settings = pool.opts._compression_settings
self.compression_context = None
self.socket_checker = SocketChecker()
# Support for mechanism negotiation on the initial handshake.
@ -1000,7 +1011,7 @@ def _configured_socket(address, options):
Sets socket's SSL and timeout options.
"""
sock = _create_connection(address, options)
ssl_context = options.ssl_context
ssl_context = options._ssl_context
if ssl_context is not None:
host = address[0]
@ -1123,8 +1134,8 @@ class Pool:
# Don't publish events in Monitor pools.
self.enabled_for_cmap = (
self.handshake and
self.opts.event_listeners is not None and
self.opts.event_listeners.enabled_for_cmap)
self.opts._event_listeners is not None and
self.opts._event_listeners.enabled_for_cmap)
# The first portion of the wait queue.
# Enforces: maxPoolSize
@ -1141,7 +1152,7 @@ class Pool:
self._max_connecting = self.opts.max_connecting
self._pending = 0
if self.enabled_for_cmap:
self.opts.event_listeners.publish_pool_created(
self.opts._event_listeners.publish_pool_created(
self.address, self.opts.non_default_options)
# Similar to active_sockets but includes threads in the wait queue.
self.operation_count = 0
@ -1158,7 +1169,7 @@ class Pool:
if self.state != PoolState.READY:
self.state = PoolState.READY
if self.enabled_for_cmap:
self.opts.event_listeners.publish_pool_ready(self.address)
self.opts._event_listeners.publish_pool_ready(self.address)
@property
def closed(self):
@ -1197,7 +1208,7 @@ class Pool:
self._max_connecting_cond.notify_all()
self.size_cond.notify_all()
listeners = self.opts.event_listeners
listeners = self.opts._event_listeners
# CMAP spec says that close() MUST close sockets before publishing the
# PoolClosedEvent but that reset() SHOULD close sockets *after*
# publishing the PoolClearedEvent.
@ -1301,7 +1312,7 @@ class Pool:
conn_id = self.next_connection_id
self.next_connection_id += 1
listeners = self.opts.event_listeners
listeners = self.opts._event_listeners
if self.enabled_for_cmap:
listeners.publish_connection_created(self.address, conn_id)
@ -1353,7 +1364,7 @@ class Pool:
- `all_credentials`: dict, maps auth source to MongoCredential.
- `handler` (optional): A _MongoClientErrorHandler.
"""
listeners = self.opts.event_listeners
listeners = self.opts._event_listeners
if self.enabled_for_cmap:
listeners.publish_connection_check_out_started(self.address)
@ -1391,7 +1402,7 @@ class Pool:
def _raise_if_not_ready(self, emit_event):
if self.state != PoolState.READY:
if self.enabled_for_cmap and emit_event:
self.opts.event_listeners.publish_connection_check_out_failed(
self.opts._event_listeners.publish_connection_check_out_failed(
self.address, ConnectionCheckOutFailedReason.CONN_ERROR)
_raise_connection_failure(
self.address, AutoReconnect('connection pool paused'))
@ -1406,7 +1417,7 @@ class Pool:
if self.closed:
if self.enabled_for_cmap:
self.opts.event_listeners.publish_connection_check_out_failed(
self.opts._event_listeners.publish_connection_check_out_failed(
self.address, ConnectionCheckOutFailedReason.POOL_CLOSED)
raise _PoolClosedError(
'Attempted to check out a connection from closed connection '
@ -1486,7 +1497,7 @@ class Pool:
self.size_cond.notify()
if self.enabled_for_cmap and not emitted_event:
self.opts.event_listeners.publish_connection_check_out_failed(
self.opts._event_listeners.publish_connection_check_out_failed(
self.address, ConnectionCheckOutFailedReason.CONN_ERROR)
raise
@ -1505,7 +1516,7 @@ class Pool:
sock_info.pinned_txn = False
sock_info.pinned_cursor = False
self.__pinned_sockets.discard(sock_info)
listeners = self.opts.event_listeners
listeners = self.opts._event_listeners
if self.enabled_for_cmap:
listeners.publish_connection_checked_in(self.address, sock_info.id)
if self.pid != os.getpid():
@ -1578,7 +1589,7 @@ class Pool:
return False
def _raise_wait_queue_timeout(self):
listeners = self.opts.event_listeners
listeners = self.opts._event_listeners
if self.enabled_for_cmap:
listeners.publish_connection_check_out_failed(
self.address, ConnectionCheckOutFailedReason.TIMEOUT)

View File

@ -73,7 +73,7 @@ class Topology(object):
"""Monitor a topology of one or more servers."""
def __init__(self, topology_settings):
self._topology_id = topology_settings._topology_id
self._listeners = topology_settings._pool_options.event_listeners
self._listeners = topology_settings._pool_options._event_listeners
pub = self._listeners is not None
self._publish_server = pub and self._listeners.enabled_for_server
self._publish_tp = pub and self._listeners.enabled_for_topology
@ -728,9 +728,9 @@ class Topology(object):
monitor_pool_options = PoolOptions(
connect_timeout=options.connect_timeout,
socket_timeout=options.connect_timeout,
ssl_context=options.ssl_context,
ssl_context=options._ssl_context,
tls_allow_invalid_hostnames=options.tls_allow_invalid_hostnames,
event_listeners=options.event_listeners,
event_listeners=options._event_listeners,
appname=options.appname,
driver=options.driver,
pause_enabled=False,

View File

@ -44,7 +44,7 @@ def create_test(test_case):
self.assertRaises(Exception, MongoClient, uri, connect=False)
else:
client = MongoClient(uri, connect=False)
credentials = client._MongoClient__options.credentials
credentials = client._MongoClient__options._credentials
if credential is None:
self.assertIsNone(credentials)
else:

View File

@ -36,6 +36,7 @@ from bson.son import SON
from bson.tz_util import utc
import pymongo
from pymongo import event_loggers, message, monitoring
from pymongo.client_options import ClientOptions
from pymongo.command_cursor import CommandCursor
from pymongo.common import CONNECT_TIMEOUT, _UUID_REPRESENTATIONS
from pymongo.compression_support import _HAVE_SNAPPY, _HAVE_ZSTD
@ -56,7 +57,7 @@ from pymongo.hello import HelloCompat
from pymongo.mongo_client import MongoClient
from pymongo.monitoring import (ServerHeartbeatListener,
ServerHeartbeatStartedEvent)
from pymongo.pool import SocketInfo, _METADATA
from pymongo.pool import SocketInfo, _METADATA, PoolOptions
from pymongo.read_preferences import ReadPreference
from pymongo.server_description import ServerDescription
from pymongo.server_selectors import (readable_server_selector,
@ -128,10 +129,10 @@ class ClientUnitTest(unittest.TestCase):
# socket.Socket.settimeout takes a float in seconds
self.assertEqual(20.0, pool_opts.connect_timeout)
self.assertEqual(None, pool_opts.wait_queue_timeout)
self.assertEqual(None, pool_opts.ssl_context)
self.assertEqual(None, pool_opts._ssl_context)
self.assertEqual(None, options.replica_set_name)
self.assertEqual(ReadPreference.PRIMARY, client.read_preference)
self.assertAlmostEqual(12, client.server_selection_timeout)
self.assertAlmostEqual(12, client.options.server_selection_timeout)
def test_connect_timeout(self):
client = MongoClient(connect=False, connectTimeoutMS=None,
@ -465,14 +466,23 @@ class ClientUnitTest(unittest.TestCase):
def test_event_listeners(self):
c = MongoClient(event_listeners=[], connect=False)
self.assertEqual(c.event_listeners, [])
self.assertEqual(c.options.event_listeners, [])
listeners = [event_loggers.CommandLogger(),
event_loggers.HeartbeatLogger(),
event_loggers.ServerLogger(),
event_loggers.TopologyLogger(),
event_loggers.ConnectionPoolLogger()]
c = MongoClient(event_listeners=listeners, connect=False)
self.assertEqual(c.event_listeners, listeners)
self.assertEqual(c.options.event_listeners, listeners)
def test_client_options(self):
c = MongoClient(connect=False)
self.assertIsInstance(c.options, ClientOptions)
self.assertIsInstance(c.options.pool_options, PoolOptions)
self.assertEqual(c.options.server_selection_timeout, 30)
self.assertEqual(c.options.pool_options.max_idle_time_seconds, None)
self.assertIsInstance(c.options.retry_writes, bool)
self.assertIsInstance(c.options.retry_reads, bool)
class TestClient(IntegrationTest):
@ -635,7 +645,7 @@ class TestClient(IntegrationTest):
c = rs_or_single_client(connect=False)
self.assertIsInstance(c.is_mongos, bool)
c = rs_or_single_client(connect=False)
self.assertIsInstance(c.max_pool_size, int)
self.assertIsInstance(c.options.pool_options.max_pool_size, int)
self.assertIsInstance(c.nodes, frozenset)
c = rs_or_single_client(connect=False)
@ -1003,8 +1013,8 @@ class TestClient(IntegrationTest):
self.assertEqual(10.5, get_pool(client).opts.connect_timeout)
self.assertEqual(10.5, get_pool(client).opts.socket_timeout)
self.assertEqual(10.5, get_pool(client).opts.max_idle_time_seconds)
self.assertEqual(10500, client.max_idle_time_ms)
self.assertEqual(10.5, client.server_selection_timeout)
self.assertEqual(10.5, client.options.pool_options.max_idle_time_seconds)
self.assertEqual(10.5, client.options.server_selection_timeout)
def test_socket_timeout_ms_validation(self):
c = rs_or_single_client(socketTimeoutMS=10 * 1000)
@ -1044,10 +1054,10 @@ class TestClient(IntegrationTest):
def test_server_selection_timeout(self):
client = MongoClient(serverSelectionTimeoutMS=100, connect=False)
self.assertAlmostEqual(0.1, client.server_selection_timeout)
self.assertAlmostEqual(0.1, client.options.server_selection_timeout)
client = MongoClient(serverSelectionTimeoutMS=0, connect=False)
self.assertAlmostEqual(0, client.server_selection_timeout)
self.assertAlmostEqual(0, client.options.server_selection_timeout)
self.assertRaises(ValueError, MongoClient,
serverSelectionTimeoutMS="foo", connect=False)
@ -1058,20 +1068,20 @@ class TestClient(IntegrationTest):
client = MongoClient(
'mongodb://localhost/?serverSelectionTimeoutMS=100', connect=False)
self.assertAlmostEqual(0.1, client.server_selection_timeout)
self.assertAlmostEqual(0.1, client.options.server_selection_timeout)
client = MongoClient(
'mongodb://localhost/?serverSelectionTimeoutMS=0', connect=False)
self.assertAlmostEqual(0, client.server_selection_timeout)
self.assertAlmostEqual(0, client.options.server_selection_timeout)
# Test invalid timeout in URI ignored and set to default.
client = MongoClient(
'mongodb://localhost/?serverSelectionTimeoutMS=-1', connect=False)
self.assertAlmostEqual(30, client.server_selection_timeout)
self.assertAlmostEqual(30, client.options.server_selection_timeout)
client = MongoClient(
'mongodb://localhost/?serverSelectionTimeoutMS=', connect=False)
self.assertAlmostEqual(30, client.server_selection_timeout)
self.assertAlmostEqual(30, client.options.server_selection_timeout)
def test_waitQueueTimeoutMS(self):
client = rs_or_single_client(waitQueueTimeoutMS=2000)
@ -1379,7 +1389,7 @@ class TestClient(IntegrationTest):
def test_compression(self):
def compression_settings(client):
pool_options = client._MongoClient__options.pool_options
return pool_options.compression_settings
return pool_options._compression_settings
uri = "mongodb://localhost:27017/?compressors=zlib"
client = MongoClient(uri, connect=False)

View File

@ -127,7 +127,7 @@ class TestMongosLoadBalancing(MockClientTest):
def test_local_threshold(self):
client = connected(self.mock_client(localThresholdMS=30))
self.assertEqual(30, client.local_threshold_ms)
self.assertEqual(30, client.options.local_threshold_ms)
wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')
topology = client._topology
@ -139,7 +139,7 @@ class TestMongosLoadBalancing(MockClientTest):
client.admin.command('ping')
client = connected(self.mock_client(localThresholdMS=0))
self.assertEqual(0, client.local_threshold_ms)
self.assertEqual(0, client.options.local_threshold_ms)
# No error
client.db.command('ping')
# Our chosen mongos goes down.

View File

@ -169,7 +169,7 @@ class _TestPoolingBase(IntegrationTest):
**kwargs):
# Start the pool with the correct ssl options.
pool_options = client_context.client._topology_settings.pool_options
kwargs['ssl_context'] = pool_options.ssl_context
kwargs['ssl_context'] = pool_options._ssl_context
kwargs['tls_allow_invalid_hostnames'] = pool_options.tls_allow_invalid_hostnames
kwargs['server_api'] = pool_options.server_api
pool = Pool(pair, PoolOptions(*args, **kwargs))
@ -187,7 +187,7 @@ class TestPooling(_TestPoolingBase):
ValueError, MongoClient, host=host, port=port, maxPoolSize='foo')
c = MongoClient(host=host, port=port, maxPoolSize=100, connect=False)
self.assertEqual(c.max_pool_size, 100)
self.assertEqual(c.options.pool_options.max_pool_size, 100)
def test_no_disconnect(self):
run_cases(self.c, [NonUnique, Unique, InsertOneAndFind])

View File

@ -209,20 +209,16 @@ class TestReadPreferences(TestReadPreferencesBase):
def test_threshold_validation(self):
self.assertEqual(17, rs_client(
localThresholdMS=17
).local_threshold_ms)
localThresholdMS=17, connect=False).options.local_threshold_ms)
self.assertEqual(42, rs_client(
localThresholdMS=42
).local_threshold_ms)
localThresholdMS=42, connect=False).options.local_threshold_ms)
self.assertEqual(666, rs_client(
localthresholdms=666
).local_threshold_ms)
localThresholdMS=666, connect=False).options.local_threshold_ms)
self.assertEqual(0, rs_client(
localthresholdms=0
).local_threshold_ms)
localThresholdMS=0, connect=False).options.local_threshold_ms)
self.assertRaises(ValueError,
rs_client,

View File

@ -48,19 +48,19 @@ _TEST_PATH = os.path.join(
class TestClientOptions(PyMongoTestCase):
def test_default(self):
client = MongoClient(connect=False)
self.assertEqual(client.retry_reads, True)
self.assertEqual(client.options.retry_reads, True)
def test_kwargs(self):
client = MongoClient(retryReads=True, connect=False)
self.assertEqual(client.retry_reads, True)
self.assertEqual(client.options.retry_reads, True)
client = MongoClient(retryReads=False, connect=False)
self.assertEqual(client.retry_reads, False)
self.assertEqual(client.options.retry_reads, False)
def test_uri(self):
client = MongoClient('mongodb://h/?retryReads=true', connect=False)
self.assertEqual(client.retry_reads, True)
self.assertEqual(client.options.retry_reads, True)
client = MongoClient('mongodb://h/?retryReads=false', connect=False)
self.assertEqual(client.retry_reads, False)
self.assertEqual(client.options.retry_reads, False)
class TestSpec(SpecRunner):

View File

@ -290,7 +290,7 @@ class TestSdamMonitoring(IntegrationTest):
'data': data,
}
with self.fail_point(fail_insert):
if self.test_client.retry_writes:
if self.test_client.options.retry_writes:
self.coll.insert_one({})
else:
with self.assertRaises(expected_error):

View File

@ -104,7 +104,7 @@ class TestSession(IntegrationTest):
self.assertLessEqual(used_lsids, current_lsids)
def _test_ops(self, client, *ops):
listener = client.event_listeners[0]
listener = client.options.event_listeners[0]
for f, args, kw in ops:
with client.start_session() as s:
@ -626,7 +626,7 @@ class TestSession(IntegrationTest):
lambda cursor: list(cursor))
def _test_unacknowledged_ops(self, client, *ops):
listener = client.event_listeners[0]
listener = client.options.event_listeners[0]
for f, args, kw in ops:
with client.start_session() as s: