Skip to content

Commit d94743b

Browse files
committed
only define topology after uri resolution
1 parent 1a3efed commit d94743b

File tree

6 files changed

+147
-109
lines changed

6 files changed

+147
-109
lines changed

pymongo/asynchronous/mongo_client.py

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
from pymongo.asynchronous.bulk import _AsyncBulk
129129
from pymongo.asynchronous.client_session import AsyncClientSession, _ServerSession
130130
from pymongo.asynchronous.cursor import _ConnectionManager
131+
from pymongo.asynchronous.encryption import _Encrypter
131132
from pymongo.asynchronous.pool import AsyncConnection
132133
from pymongo.asynchronous.server import Server
133134
from pymongo.read_concern import ReadConcern
@@ -840,26 +841,26 @@ def __init__(
840841
options.read_concern,
841842
)
842843

843-
self._topology_settings = TopologySettings(
844-
seeds=seeds,
845-
replica_set_name=options.replica_set_name,
846-
pool_class=pool_class,
847-
pool_options=options.pool_options,
848-
monitor_class=monitor_class,
849-
condition_class=condition_class,
850-
local_threshold_ms=options.local_threshold_ms,
851-
server_selection_timeout=options.server_selection_timeout,
852-
server_selector=options.server_selector,
853-
heartbeat_frequency=options.heartbeat_frequency,
854-
fqdn=fqdn,
855-
direct_connection=options.direct_connection,
856-
load_balanced=options.load_balanced,
857-
srv_service_name=srv_service_name,
858-
srv_max_hosts=srv_max_hosts,
859-
server_monitoring_mode=options.server_monitoring_mode,
860-
)
861-
862-
self._topology = Topology(self._topology_settings)
844+
# self._topology_settings = TopologySettings(
845+
# seeds=seeds,
846+
# replica_set_name=options.replica_set_name,
847+
# pool_class=pool_class,
848+
# pool_options=options.pool_options,
849+
# monitor_class=monitor_class,
850+
# condition_class=condition_class,
851+
# local_threshold_ms=options.local_threshold_ms,
852+
# server_selection_timeout=options.server_selection_timeout,
853+
# server_selector=options.server_selector,
854+
# heartbeat_frequency=options.heartbeat_frequency,
855+
# fqdn=fqdn,
856+
# direct_connection=options.direct_connection,
857+
# load_balanced=options.load_balanced,
858+
# srv_service_name=srv_service_name,
859+
# srv_max_hosts=srv_max_hosts,
860+
# server_monitoring_mode=options.server_monitoring_mode,
861+
# )
862+
#
863+
# self._topology = Topology(self._topology_settings)
863864

864865
self._opened = False
865866
self._closed = False
@@ -878,7 +879,7 @@ def __init__(
878879
if _IS_SYNC and connect:
879880
self._get_topology() # type: ignore[unused-coroutine]
880881

881-
self._encrypter = None
882+
self._encrypter: Optional[_Encrypter] = None
882883
self._timeout = self._options.timeout
883884

884885
def _resolve_uri(self) -> None:
@@ -1018,7 +1019,6 @@ async def aconnect(self) -> None:
10181019
await self._get_topology()
10191020

10201021
def _init_background(self, old_pid: Optional[int] = None) -> None:
1021-
self._topology = Topology(self._topology_settings)
10221022
# Seed the topology with the old one's pid so we can detect clients
10231023
# that are opened before a fork and used after.
10241024
self._topology._pid = old_pid
@@ -1235,14 +1235,20 @@ def options(self) -> ClientOptions:
12351235

12361236
def __eq__(self, other: Any) -> bool:
12371237
if isinstance(other, self.__class__):
1238-
return self._topology == other._topology
1238+
if hasattr(self, "_topology"):
1239+
return self._topology == other._topology
1240+
else:
1241+
raise InvalidOperation("Cannot perform operation until client is connected")
12391242
return NotImplemented
12401243

12411244
def __ne__(self, other: Any) -> bool:
12421245
return not self == other
12431246

12441247
def __hash__(self) -> int:
1245-
return hash(self._topology)
1248+
if hasattr(self, "_topology"):
1249+
return hash(self._topology)
1250+
else:
1251+
raise InvalidOperation("Cannot perform operation until client is connected")
12461252

12471253
def _repr_helper(self) -> str:
12481254
def option_repr(option: str, value: Any) -> str:
@@ -1278,7 +1284,9 @@ def option_repr(option: str, value: Any) -> str:
12781284
return ", ".join(options)
12791285

12801286
def __repr__(self) -> str:
1281-
return f"{type(self).__name__}({self._repr_helper()})"
1287+
if hasattr(self, "_topology"):
1288+
return f"{type(self).__name__}({self._repr_helper()})"
1289+
raise InvalidOperation("Cannot perform operation until client is connected")
12821290

12831291
def __getattr__(self, name: str) -> database.AsyncDatabase[_DocumentType]:
12841292
"""Get a database by name.
@@ -1670,12 +1678,12 @@ async def close(self) -> None:
16701678
.. versionchanged:: 3.6
16711679
End all server sessions created by this client.
16721680
"""
1673-
session_ids = self._topology.pop_all_sessions()
1674-
if session_ids:
1675-
await self._end_sessions(session_ids)
1676-
# Stop the periodic task thread and then send pending killCursor
1677-
# requests before closing the topology.
16781681
if self._opened:
1682+
session_ids = self._topology.pop_all_sessions()
1683+
if session_ids:
1684+
await self._end_sessions(session_ids)
1685+
# Stop the periodic task thread and then send pending killCursor
1686+
# requests before closing the topology.
16791687
self._kill_cursors_executor.close()
16801688
await self._process_kill_cursors()
16811689
await self._topology.close()

pymongo/synchronous/mongo_client.py

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
from pymongo.synchronous.bulk import _Bulk
131131
from pymongo.synchronous.client_session import ClientSession, _ServerSession
132132
from pymongo.synchronous.cursor import _ConnectionManager
133+
from pymongo.synchronous.encryption import _Encrypter
133134
from pymongo.synchronous.pool import Connection
134135
from pymongo.synchronous.server import Server
135136

@@ -838,26 +839,26 @@ def __init__(
838839
options.read_concern,
839840
)
840841

841-
self._topology_settings = TopologySettings(
842-
seeds=seeds,
843-
replica_set_name=options.replica_set_name,
844-
pool_class=pool_class,
845-
pool_options=options.pool_options,
846-
monitor_class=monitor_class,
847-
condition_class=condition_class,
848-
local_threshold_ms=options.local_threshold_ms,
849-
server_selection_timeout=options.server_selection_timeout,
850-
server_selector=options.server_selector,
851-
heartbeat_frequency=options.heartbeat_frequency,
852-
fqdn=fqdn,
853-
direct_connection=options.direct_connection,
854-
load_balanced=options.load_balanced,
855-
srv_service_name=srv_service_name,
856-
srv_max_hosts=srv_max_hosts,
857-
server_monitoring_mode=options.server_monitoring_mode,
858-
)
859-
860-
self._topology = Topology(self._topology_settings)
842+
# self._topology_settings = TopologySettings(
843+
# seeds=seeds,
844+
# replica_set_name=options.replica_set_name,
845+
# pool_class=pool_class,
846+
# pool_options=options.pool_options,
847+
# monitor_class=monitor_class,
848+
# condition_class=condition_class,
849+
# local_threshold_ms=options.local_threshold_ms,
850+
# server_selection_timeout=options.server_selection_timeout,
851+
# server_selector=options.server_selector,
852+
# heartbeat_frequency=options.heartbeat_frequency,
853+
# fqdn=fqdn,
854+
# direct_connection=options.direct_connection,
855+
# load_balanced=options.load_balanced,
856+
# srv_service_name=srv_service_name,
857+
# srv_max_hosts=srv_max_hosts,
858+
# server_monitoring_mode=options.server_monitoring_mode,
859+
# )
860+
#
861+
# self._topology = Topology(self._topology_settings)
861862

862863
self._opened = False
863864
self._closed = False
@@ -876,7 +877,7 @@ def __init__(
876877
if _IS_SYNC and connect:
877878
self._get_topology() # type: ignore[unused-coroutine]
878879

879-
self._encrypter = None
880+
self._encrypter: Optional[_Encrypter] = None
880881
self._timeout = self._options.timeout
881882

882883
def _resolve_uri(self) -> None:
@@ -1016,7 +1017,6 @@ def _connect(self) -> None:
10161017
self._get_topology()
10171018

10181019
def _init_background(self, old_pid: Optional[int] = None) -> None:
1019-
self._topology = Topology(self._topology_settings)
10201020
# Seed the topology with the old one's pid so we can detect clients
10211021
# that are opened before a fork and used after.
10221022
self._topology._pid = old_pid
@@ -1233,14 +1233,20 @@ def options(self) -> ClientOptions:
12331233

12341234
def __eq__(self, other: Any) -> bool:
12351235
if isinstance(other, self.__class__):
1236-
return self._topology == other._topology
1236+
if hasattr(self, "_topology"):
1237+
return self._topology == other._topology
1238+
else:
1239+
raise InvalidOperation("Cannot perform operation until client is connected")
12371240
return NotImplemented
12381241

12391242
def __ne__(self, other: Any) -> bool:
12401243
return not self == other
12411244

12421245
def __hash__(self) -> int:
1243-
return hash(self._topology)
1246+
if hasattr(self, "_topology"):
1247+
return hash(self._topology)
1248+
else:
1249+
raise InvalidOperation("Cannot perform operation until client is connected")
12441250

12451251
def _repr_helper(self) -> str:
12461252
def option_repr(option: str, value: Any) -> str:
@@ -1276,7 +1282,9 @@ def option_repr(option: str, value: Any) -> str:
12761282
return ", ".join(options)
12771283

12781284
def __repr__(self) -> str:
1279-
return f"{type(self).__name__}({self._repr_helper()})"
1285+
if hasattr(self, "_topology"):
1286+
return f"{type(self).__name__}({self._repr_helper()})"
1287+
raise InvalidOperation("Cannot perform operation until client is connected")
12801288

12811289
def __getattr__(self, name: str) -> database.Database[_DocumentType]:
12821290
"""Get a database by name.
@@ -1664,12 +1672,12 @@ def close(self) -> None:
16641672
.. versionchanged:: 3.6
16651673
End all server sessions created by this client.
16661674
"""
1667-
session_ids = self._topology.pop_all_sessions()
1668-
if session_ids:
1669-
self._end_sessions(session_ids)
1670-
# Stop the periodic task thread and then send pending killCursor
1671-
# requests before closing the topology.
16721675
if self._opened:
1676+
session_ids = self._topology.pop_all_sessions()
1677+
if session_ids:
1678+
self._end_sessions(session_ids)
1679+
# Stop the periodic task thread and then send pending killCursor
1680+
# requests before closing the topology.
16731681
self._kill_cursors_executor.close()
16741682
self._process_kill_cursors()
16751683
self._topology.close()

0 commit comments

Comments
 (0)