Skip to content

Commit 7bcc7b6

Browse files
committed
Merge branch 'master' of github.com:mongodb/mongo-python-driver
2 parents a3d983c + 8ff9c82 commit 7bcc7b6

File tree

7 files changed

+85
-18
lines changed

7 files changed

+85
-18
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ the pages will re-render and the browser will automatically refresh.
200200
- Append `test/<mod_name>.py::<class_name>::<test_name>` to run
201201
specific tests. You can omit the `<test_name>` to test a full class
202202
and the `<class_name>` to test a full module. For example:
203-
`tox -m test test/test_change_stream.py::TestUnifiedChangeStreamsErrors::test_change_stream_errors_on_ElectionInProgress`.
203+
`tox -m test -- test/test_change_stream.py::TestUnifiedChangeStreamsErrors::test_change_stream_errors_on_ElectionInProgress`.
204204
- Use the `-k` argument to select tests by pattern.
205205

206206
## Running Load Balancer Tests Locally

doc/changelog.rst

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ Unavoidable breaking changes
8585

8686
- The "aws" extra now requires minimum version of ``1.1.0`` for ``pymongo_auth_aws``.
8787

88+
Changes in Version 4.6.3
89+
------------------------
90+
91+
PyMongo 4.6.3 fixes the following bug:
92+
93+
- Fixed a potential memory access violation when decoding invalid bson.
94+
95+
Issues Resolved
96+
...............
97+
98+
See the `PyMongo 4.6.3 release notes in JIRA`_ for the list of resolved issues
99+
in this release.
100+
101+
.. _PyMongo 4.6.3 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=38360
102+
88103
Changes in Version 4.6.2
89104
------------------------
90105

@@ -93,13 +108,29 @@ PyMongo 4.6.2 fixes the following bug:
93108
- Fixed a bug appearing in Python 3.12 where "RuntimeError: can't create new thread at interpreter shutdown"
94109
could be written to stderr when a MongoClient's thread starts as the python interpreter is shutting down.
95110

111+
Issues Resolved
112+
...............
113+
114+
See the `PyMongo 4.6.2 release notes in JIRA`_ for the list of resolved issues
115+
in this release.
116+
117+
.. _PyMongo 4.6.2 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=37906
118+
96119
Changes in Version 4.6.1
97120
------------------------
98121

99122
PyMongo 4.6.1 fixes the following bug:
100123

101124
- Ensure retryable read ``OperationFailure`` errors re-raise exception when 0 or NoneType error code is provided.
102125

126+
Issues Resolved
127+
...............
128+
129+
See the `PyMongo 4.6.1 release notes in JIRA`_ for the list of resolved issues
130+
in this release.
131+
132+
.. _PyMongo 4.6.1 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=37138
133+
103134
Changes in Version 4.6
104135
----------------------
105136

@@ -132,6 +163,14 @@ PyMongo 4.6 brings a number of improvements including:
132163
- Added the :ref:`network-compression-example` documentation page.
133164
- Added more timeout information to network errors.
134165

166+
Issues Resolved
167+
...............
168+
169+
See the `PyMongo 4.6 release notes in JIRA`_ for the list of resolved issues
170+
in this release.
171+
172+
.. _PyMongo 4.6 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=36542
173+
135174
Changes in Version 4.5
136175
----------------------
137176

pymongo/mongo_client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -879,8 +879,11 @@ def __init__(
879879
# This will be used later if we fork.
880880
MongoClient._clients[self._topology._topology_id] = self
881881

882-
def _init_background(self) -> None:
882+
def _init_background(self, old_pid: Optional[int] = None) -> None:
883883
self._topology = Topology(self._topology_settings)
884+
# Seed the topology with the old one's pid so we can detect clients
885+
# that are opened before a fork and used after.
886+
self._topology._pid = old_pid
884887

885888
def target() -> bool:
886889
client = self_ref()
@@ -903,7 +906,7 @@ def target() -> bool:
903906

904907
def _after_fork(self) -> None:
905908
"""Resets topology in a child after successfully forking."""
906-
self._init_background()
909+
self._init_background(self._topology._pid)
907910

908911
def _duplicate(self, **kwargs: Any) -> MongoClient:
909912
args = self.__init_kwargs.copy()
@@ -921,7 +924,7 @@ def _server_property(self, attr_name: str) -> Any:
921924
the server may change. In such cases, store a local reference to a
922925
ServerDescription first, then use its properties.
923926
"""
924-
server = self._topology.select_server(writable_server_selector, _Op.TEST)
927+
server = self._get_topology().select_server(writable_server_selector, _Op.TEST)
925928

926929
return getattr(server.description, attr_name)
927930

pymongo/topology.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import os
2121
import queue
2222
import random
23+
import sys
2324
import time
2425
import warnings
2526
import weakref
27+
from pathlib import Path
2628
from typing import TYPE_CHECKING, Any, Callable, Mapping, Optional, cast
2729

2830
from pymongo import _csot, common, helpers, periodic_executor
@@ -70,6 +72,9 @@
7072
from pymongo.typings import ClusterTime, _Address
7173

7274

75+
_pymongo_dir = str(Path(__file__).parent)
76+
77+
7378
def process_events_queue(queue_ref: weakref.ReferenceType[queue.Queue]) -> bool:
7479
q = queue_ref()
7580
if not q:
@@ -187,12 +192,17 @@ def open(self) -> None:
187192
self._pid = pid
188193
elif pid != self._pid:
189194
self._pid = pid
190-
warnings.warn(
195+
if sys.version_info[:2] >= (3, 12):
196+
kwargs = {"skip_file_prefixes": (_pymongo_dir,)}
197+
else:
198+
kwargs = {"stacklevel": 6}
199+
# Ignore B028 warning for missing stacklevel.
200+
warnings.warn( # type: ignore[call-overload] # noqa: B028
191201
"MongoClient opened before fork. May not be entirely fork-safe, "
192202
"proceed with caution. See PyMongo's documentation for details: "
193203
"https://pymongo.readthedocs.io/en/stable/faq.html#"
194204
"is-pymongo-fork-safe",
195-
stacklevel=2,
205+
**kwargs,
196206
)
197207
with self._lock:
198208
# Close servers and clear the pools.

test/test_discovery_and_monitoring.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import sys
2121
import threading
2222

23-
from pymongo.monitoring import ServerHeartbeatFailedEvent, ServerHeartbeatStartedEvent
24-
2523
sys.path[0:0] = [""]
2624

2725
from test import IntegrationTest, unittest
@@ -52,6 +50,7 @@
5250
)
5351
from pymongo.hello import Hello, HelloCompat
5452
from pymongo.helpers import _check_command_response, _check_write_command_response
53+
from pymongo.monitoring import ServerHeartbeatFailedEvent, ServerHeartbeatStartedEvent
5554
from pymongo.server_description import SERVER_TYPE, ServerDescription
5655
from pymongo.settings import TopologySettings
5756
from pymongo.topology import Topology, _ErrorContext
@@ -408,17 +407,21 @@ def handle(self):
408407
self.request.close()
409408

410409

411-
class TestHeartbeatStartOrdering(unittest.TestCase):
412-
def start_server(self, events):
413-
server = socketserver.TCPServer(("localhost", 9999), MockTCPHandler)
414-
server.events = events
415-
server.handle_request()
416-
server.server_close()
410+
class TCPServer(socketserver.TCPServer):
411+
allow_reuse_address = True
417412

413+
def handle_request_and_shutdown(self):
414+
self.handle_request()
415+
self.server_close()
416+
417+
418+
class TestHeartbeatStartOrdering(unittest.TestCase):
418419
def test_heartbeat_start_ordering(self):
419420
events = []
420421
listener = HeartbeatEventsListListener(events)
421-
server_thread = threading.Thread(target=self.start_server, args=(events,))
422+
server = TCPServer(("localhost", 9999), MockTCPHandler)
423+
server.events = events
424+
server_thread = threading.Thread(target=server.handle_request_and_shutdown)
422425
server_thread.start()
423426
_c = MongoClient(
424427
"mongodb://localhost:9999", serverSelectionTimeoutMS=500, event_listeners=(listener,)

test/test_encryption.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import textwrap
2727
import traceback
2828
import uuid
29+
import warnings
2930
from threading import Thread
3031
from typing import Any, Dict, Mapping
3132

@@ -348,7 +349,9 @@ def test_fork(self):
348349
self.addCleanup(client.close)
349350

350351
def target():
351-
client.admin.command("ping")
352+
with warnings.catch_warnings():
353+
warnings.simplefilter("ignore")
354+
client.admin.command("ping")
352355

353356
with self.fork(target):
354357
target()

test/test_fork.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import os
1919
import sys
2020
import unittest
21+
import warnings
2122
from multiprocessing import Pipe
2223

2324
sys.path[0:0] = [""]
@@ -43,7 +44,9 @@ def test_lock_client(self):
4344
with self.client._MongoClient__lock:
4445

4546
def target():
46-
self.client.admin.command("ping")
47+
with warnings.catch_warnings():
48+
warnings.simplefilter("ignore")
49+
self.client.admin.command("ping")
4750

4851
with self.fork(target):
4952
pass
@@ -72,7 +75,11 @@ def test_topology_reset(self):
7275
parent_cursor_exc = self.client._kill_cursors_executor
7376

7477
def target():
75-
self.client.admin.command("ping")
78+
# Catch the fork warning and send to the parent for assertion.
79+
with warnings.catch_warnings(record=True) as ctx:
80+
warnings.simplefilter("always")
81+
self.client.admin.command("ping")
82+
child_conn.send(str(ctx[0]))
7683
child_conn.send(self.client._topology._pid)
7784
child_conn.send(
7885
(
@@ -83,6 +90,8 @@ def target():
8390

8491
with self.fork(target):
8592
self.assertEqual(self.client._topology._pid, init_id)
93+
fork_warning = parent_conn.recv()
94+
self.assertIn("MongoClient opened before fork", fork_warning)
8695
child_id = parent_conn.recv()
8796
self.assertNotEqual(child_id, init_id)
8897
passed, msg = parent_conn.recv()

0 commit comments

Comments
 (0)