From 56dc90f11e51b0621d736fda6b582fe6ff64d5da Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Mon, 31 Aug 2026 14:32:53 -0400 Subject: [PATCH] PYTHON-6014 Move internal pool classes into pool_shared.py --- pymongo/asynchronous/pool.py | 47 ++----------------- pymongo/pool_shared.py | 45 ++++++++++++++++++ pymongo/synchronous/pool.py | 47 ++----------------- .../test_connection_monitoring.py | 2 +- test/asynchronous/test_transactions.py | 2 +- test/asynchronous/utils.py | 3 +- test/test_connection_monitoring.py | 2 +- test/test_transactions.py | 2 +- test/utils.py | 3 +- test/utils_shared.py | 2 +- 10 files changed, 60 insertions(+), 95 deletions(-) diff --git a/pymongo/asynchronous/pool.py b/pymongo/asynchronous/pool.py index eb9cb215eb..d236f00f55 100644 --- a/pymongo/asynchronous/pool.py +++ b/pymongo/asynchronous/pool.py @@ -51,7 +51,6 @@ NetworkTimeout, NotPrimaryError, OperationFailure, - PyMongoError, WaitQueueTimeoutError, _CertificateError, ) @@ -70,10 +69,13 @@ from pymongo.network_layer import AsyncNetworkingInterface, async_receive_message, async_sendall from pymongo.pool_options import PoolOptions from pymongo.pool_shared import ( + PoolState, SSLErrors, _CancellationContext, _configured_protocol_interface, _ConnectionTelemetryInfo, + _PoolClosedError, + _PoolGeneration, _raise_connection_failure, ) from pymongo.read_preferences import ReadPreference @@ -583,49 +585,6 @@ def __repr__(self) -> str: ) -class _PoolClosedError(PyMongoError): - """Internal error raised when a thread tries to get a connection from a - closed pool. - """ - - -class _PoolGeneration: - def __init__(self) -> None: - # Maps service_id to generation. - self._generations: dict[ObjectId, int] = collections.defaultdict(int) - # Overall pool generation. - self._generation = 0 - - def get(self, service_id: Optional[ObjectId]) -> int: - """Get the generation for the given service_id.""" - if service_id is None: - return self._generation - return self._generations[service_id] - - def get_overall(self) -> int: - """Get the Pool's overall generation.""" - return self._generation - - def inc(self, service_id: Optional[ObjectId]) -> None: - """Increment the generation for the given service_id.""" - self._generation += 1 - if service_id is None: - for service_id in self._generations: - self._generations[service_id] += 1 - else: - self._generations[service_id] += 1 - - def stale(self, gen: int, service_id: Optional[ObjectId]) -> bool: - """Return if the given generation for a given service_id is stale.""" - return gen != self.get(service_id) - - -class PoolState: - PAUSED = 1 - READY = 2 - CLOSED = 3 - - class Pool: def __init__( self, diff --git a/pymongo/pool_shared.py b/pymongo/pool_shared.py index 410ffd8189..8cd546bda6 100644 --- a/pymongo/pool_shared.py +++ b/pymongo/pool_shared.py @@ -17,6 +17,7 @@ from __future__ import annotations import asyncio +import collections import functools import socket import ssl @@ -36,6 +37,7 @@ AutoReconnect, ConnectionFailure, NetworkTimeout, + PyMongoError, _CertificateError, ) from pymongo.helpers_shared import _get_timeout_details, format_timeout_details @@ -180,6 +182,49 @@ def cancelled(self) -> bool: return self._cancelled +class _PoolClosedError(PyMongoError): + """Internal error raised when a thread tries to get a connection from a + closed pool. + """ + + +class _PoolGeneration: + def __init__(self) -> None: + # Maps service_id to generation. + self._generations: dict[ObjectId, int] = collections.defaultdict(int) + # Overall pool generation. + self._generation = 0 + + def get(self, service_id: Optional[ObjectId]) -> int: + """Get the generation for the given service_id.""" + if service_id is None: + return self._generation + return self._generations[service_id] + + def get_overall(self) -> int: + """Get the Pool's overall generation.""" + return self._generation + + def inc(self, service_id: Optional[ObjectId]) -> None: + """Increment the generation for the given service_id.""" + self._generation += 1 + if service_id is None: + for service_id in self._generations: + self._generations[service_id] += 1 + else: + self._generations[service_id] += 1 + + def stale(self, gen: int, service_id: Optional[ObjectId]) -> bool: + """Return if the given generation for a given service_id is stale.""" + return gen != self.get(service_id) + + +class PoolState: + PAUSED = 1 + READY = 2 + CLOSED = 3 + + async def _async_create_connection(address: _Address, options: PoolOptions) -> socket.socket: """Given (host, port) and PoolOptions, connect and return a raw socket object. diff --git a/pymongo/synchronous/pool.py b/pymongo/synchronous/pool.py index 64ff4210a5..be20f522c0 100644 --- a/pymongo/synchronous/pool.py +++ b/pymongo/synchronous/pool.py @@ -48,7 +48,6 @@ NetworkTimeout, NotPrimaryError, OperationFailure, - PyMongoError, WaitQueueTimeoutError, _CertificateError, ) @@ -67,10 +66,13 @@ from pymongo.network_layer import NetworkingInterface, receive_message, sendall from pymongo.pool_options import PoolOptions from pymongo.pool_shared import ( + PoolState, SSLErrors, _CancellationContext, _configured_socket_interface, _ConnectionTelemetryInfo, + _PoolClosedError, + _PoolGeneration, _raise_connection_failure, ) from pymongo.read_preferences import ReadPreference @@ -581,49 +583,6 @@ def __repr__(self) -> str: ) -class _PoolClosedError(PyMongoError): - """Internal error raised when a thread tries to get a connection from a - closed pool. - """ - - -class _PoolGeneration: - def __init__(self) -> None: - # Maps service_id to generation. - self._generations: dict[ObjectId, int] = collections.defaultdict(int) - # Overall pool generation. - self._generation = 0 - - def get(self, service_id: Optional[ObjectId]) -> int: - """Get the generation for the given service_id.""" - if service_id is None: - return self._generation - return self._generations[service_id] - - def get_overall(self) -> int: - """Get the Pool's overall generation.""" - return self._generation - - def inc(self, service_id: Optional[ObjectId]) -> None: - """Increment the generation for the given service_id.""" - self._generation += 1 - if service_id is None: - for service_id in self._generations: - self._generations[service_id] += 1 - else: - self._generations[service_id] += 1 - - def stale(self, gen: int, service_id: Optional[ObjectId]) -> bool: - """Return if the given generation for a given service_id is stale.""" - return gen != self.get(service_id) - - -class PoolState: - PAUSED = 1 - READY = 2 - CLOSED = 3 - - class Pool: def __init__( self, diff --git a/test/asynchronous/test_connection_monitoring.py b/test/asynchronous/test_connection_monitoring.py index fda78fb560..c9399be48e 100644 --- a/test/asynchronous/test_connection_monitoring.py +++ b/test/asynchronous/test_connection_monitoring.py @@ -29,7 +29,6 @@ from bson.objectid import ObjectId from bson.son import SON -from pymongo.asynchronous.pool import PoolState, _PoolClosedError from pymongo.errors import ( ConnectionFailure, OperationFailure, @@ -51,6 +50,7 @@ PoolCreatedEvent, PoolReadyEvent, ) +from pymongo.pool_shared import PoolState, _PoolClosedError from pymongo.read_preferences import ReadPreference from pymongo.topology_description import updated_topology_description from test.asynchronous import AsyncIntegrationTest, async_client_context, client_knobs, unittest diff --git a/test/asynchronous/test_transactions.py b/test/asynchronous/test_transactions.py index 186dc4fee2..760443e5bd 100644 --- a/test/asynchronous/test_transactions.py +++ b/test/asynchronous/test_transactions.py @@ -27,7 +27,7 @@ import pymongo from gridfs.asynchronous.grid_file import AsyncGridFS, AsyncGridFSBucket -from pymongo.asynchronous.pool import PoolState +from pymongo.pool_shared import PoolState from pymongo.server_selectors import writable_server_selector sys.path[0:0] = [""] diff --git a/test/asynchronous/utils.py b/test/asynchronous/utils.py index 1407e38d91..3e6669a753 100644 --- a/test/asynchronous/utils.py +++ b/test/asynchronous/utils.py @@ -30,11 +30,12 @@ from bson.son import SON from pymongo import AsyncMongoClient -from pymongo.asynchronous.pool import Pool, _CancellationContext, _PoolGeneration +from pymongo.asynchronous.pool import Pool from pymongo.errors import ConfigurationError from pymongo.hello import HelloCompat from pymongo.lock import _async_create_lock from pymongo.operations import _Op +from pymongo.pool_shared import _CancellationContext, _PoolGeneration from pymongo.read_preferences import ReadPreference from pymongo.server_selectors import any_server_selector, writable_server_selector diff --git a/test/test_connection_monitoring.py b/test/test_connection_monitoring.py index bca173cc4d..58f2fe80cb 100644 --- a/test/test_connection_monitoring.py +++ b/test/test_connection_monitoring.py @@ -50,8 +50,8 @@ PoolCreatedEvent, PoolReadyEvent, ) +from pymongo.pool_shared import PoolState, _PoolClosedError from pymongo.read_preferences import ReadPreference -from pymongo.synchronous.pool import PoolState, _PoolClosedError from pymongo.topology_description import updated_topology_description from test import IntegrationTest, client_context, client_knobs, unittest from test.pymongo_mocks import DummyMonitor diff --git a/test/test_transactions.py b/test/test_transactions.py index 76163c3c12..cd05e2f933 100644 --- a/test/test_transactions.py +++ b/test/test_transactions.py @@ -27,8 +27,8 @@ import pymongo from gridfs.synchronous.grid_file import GridFS, GridFSBucket +from pymongo.pool_shared import PoolState from pymongo.server_selectors import writable_server_selector -from pymongo.synchronous.pool import PoolState sys.path[0:0] = [""] diff --git a/test/utils.py b/test/utils.py index 55af404c32..e52fd336e2 100644 --- a/test/utils.py +++ b/test/utils.py @@ -34,9 +34,10 @@ from pymongo.hello import HelloCompat from pymongo.lock import _create_lock from pymongo.operations import _Op +from pymongo.pool_shared import _CancellationContext, _PoolGeneration from pymongo.read_preferences import ReadPreference from pymongo.server_selectors import any_server_selector, writable_server_selector -from pymongo.synchronous.pool import Pool, _CancellationContext, _PoolGeneration +from pymongo.synchronous.pool import Pool _IS_SYNC = True diff --git a/test/utils_shared.py b/test/utils_shared.py index fa1e044048..65627956c0 100644 --- a/test/utils_shared.py +++ b/test/utils_shared.py @@ -51,10 +51,10 @@ PoolCreatedEvent, PoolReadyEvent, ) +from pymongo.pool_shared import _CancellationContext, _PoolGeneration from pymongo.read_concern import ReadConcern from pymongo.server_type import SERVER_TYPE from pymongo.synchronous.collection import ReturnDocument -from pymongo.synchronous.pool import _CancellationContext, _PoolGeneration from pymongo.write_concern import WriteConcern from test import client_context from test.asynchronous.utils import async_wait_until