Skip to content

Commit 92b3046

Browse files
authored
Merge branch 'master' into PYTHON-5344
2 parents 42e4b81 + 8a94de1 commit 92b3046

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+271
-458
lines changed

.evergreen/generated_configs/tasks.yml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ tasks:
118118
# Backport pr tests
119119
- name: backport-pr
120120
commands:
121+
- func: assume ec2 role
121122
- command: subprocess.exec
122123
params:
123124
binary: bash
@@ -3060,16 +3061,6 @@ tasks:
30603061
- sharded_cluster-auth-ssl
30613062
- sync
30623063

3063-
# Serverless tests
3064-
- name: test-serverless
3065-
commands:
3066-
- func: run tests
3067-
vars:
3068-
TEST_NAME: serverless
3069-
AUTH: auth
3070-
SSL: ssl
3071-
tags: [serverless]
3072-
30733064
# Standard tests
30743065
- name: test-standard-v4.0-python3.9-sync-noauth-nossl-standalone
30753066
commands:

.evergreen/generated_configs/variants.yml

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -586,26 +586,6 @@ buildvariants:
586586
- rhel87-small
587587
tags: [coverage_tag]
588588

589-
# Serverless tests
590-
- name: serverless-rhel8-python3.9
591-
tasks:
592-
- name: .serverless
593-
display_name: Serverless RHEL8 Python3.9
594-
run_on:
595-
- rhel87-small
596-
batchtime: 10080
597-
expansions:
598-
PYTHON_BINARY: /opt/python/3.9/bin/python3
599-
- name: serverless-rhel8-python3.13
600-
tasks:
601-
- name: .serverless
602-
display_name: Serverless RHEL8 Python3.13
603-
run_on:
604-
- rhel87-small
605-
batchtime: 10080
606-
expansions:
607-
PYTHON_BINARY: /opt/python/3.13/bin/python3
608-
609589
# Stable api tests
610590
- name: stable-api-require-v1-rhel8-auth
611591
tasks:

.evergreen/scripts/generate_config.py

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -352,23 +352,6 @@ def create_disable_test_commands_variants():
352352
return [create_variant(tasks, display_name, host=host, python=python, expansions=expansions)]
353353

354354

355-
def create_serverless_variants():
356-
host = DEFAULT_HOST
357-
batchtime = BATCHTIME_WEEK
358-
tasks = [".serverless"]
359-
base_name = "Serverless"
360-
return [
361-
create_variant(
362-
tasks,
363-
get_variant_name(base_name, host, python=python),
364-
host=host,
365-
python=python,
366-
batchtime=batchtime,
367-
)
368-
for python in MIN_MAX_PYTHON
369-
]
370-
371-
372355
def create_oidc_auth_variants():
373356
variants = []
374357
for host_name in ["ubuntu22", "macos", "win64"]:
@@ -920,7 +903,8 @@ def create_backport_pr_tasks():
920903
"${github_commit}",
921904
]
922905
cmd = get_subprocess_exec(args=args)
923-
return [EvgTask(name=name, commands=[cmd], allowed_requesters=["commit"])]
906+
assume_func = FunctionCall(func="assume ec2 role")
907+
return [EvgTask(name=name, commands=[assume_func, cmd], allowed_requesters=["commit"])]
924908

925909

926910
def create_ocsp_tasks():
@@ -968,14 +952,6 @@ def create_free_threading_tasks():
968952
return [EvgTask(name=task_name, tags=tags, commands=[server_func, test_func])]
969953

970954

971-
def create_serverless_tasks():
972-
vars = dict(TEST_NAME="serverless", AUTH="auth", SSL="ssl")
973-
test_func = FunctionCall(func="run tests", vars=vars)
974-
tags = ["serverless"]
975-
task_name = "test-serverless"
976-
return [EvgTask(name=task_name, tags=tags, commands=[test_func])]
977-
978-
979955
##############
980956
# Functions
981957
##############

.evergreen/scripts/setup_tests.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,6 @@ def handle_test_env() -> None:
229229
config = read_env(f"{DRIVERS_TOOLS}/.evergreen/atlas_data_lake/secrets-export.sh")
230230
DB_USER = config["ADL_USERNAME"]
231231
DB_PASSWORD = config["ADL_PASSWORD"]
232-
elif test_name == "serverless":
233-
run_command(f"bash {DRIVERS_TOOLS}/.evergreen/serverless/setup.sh")
234-
config = read_env(f"{DRIVERS_TOOLS}/.evergreen/serverless/secrets-export.sh")
235-
DB_USER = config["SERVERLESS_ATLAS_USER"]
236-
DB_PASSWORD = config["SERVERLESS_ATLAS_PASSWORD"]
237-
write_env("MONGODB_URI", config["SERVERLESS_URI"])
238-
write_env("SINGLE_MONGOS_LB_URI", config["SERVERLESS_URI"])
239-
write_env("MULTI_MONGOS_LB_URI", config["SERVERLESS_URI"])
240232
elif test_name == "auth_oidc":
241233
DB_USER = config["OIDC_ADMIN_USER"]
242234
DB_PASSWORD = config["OIDC_ADMIN_PWD"]

.evergreen/scripts/teardown_tests.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@
3636
elif TEST_NAME == "ocsp":
3737
run_command(f"bash {DRIVERS_TOOLS}/.evergreen/ocsp/teardown.sh")
3838

39-
# Tear down serverless if applicable.
40-
elif TEST_NAME == "serverless":
41-
run_command(f"bash {DRIVERS_TOOLS}/.evergreen/serverless/teardown.sh")
42-
4339
# Tear down atlas cluster if applicable.
4440
if TEST_NAME in ["aws_lambda", "search_index"]:
4541
run_command(f"bash {DRIVERS_TOOLS}/.evergreen/atlas/teardown-atlas-cluster.sh")

.evergreen/scripts/utils.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class Distro:
4545
"mockupdb": "mockupdb",
4646
"ocsp": "ocsp",
4747
"perf": "perf",
48-
"serverless": "",
4948
}
5049

5150
# Tests that require a sub test suite.
@@ -60,7 +59,6 @@ class Distro:
6059
"aws_lambda",
6160
"data_lake",
6261
"mockupdb",
63-
"serverless",
6462
"ocsp",
6563
]
6664

.github/workflows/codeql.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646

4747
# Initializes the CodeQL tools for scanning.
4848
- name: Initialize CodeQL
49-
uses: github/codeql-action/init@fca7ace96b7d713c7035871441bd52efbe39e27e # v3
49+
uses: github/codeql-action/init@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3
5050
with:
5151
languages: ${{ matrix.language }}
5252
build-mode: ${{ matrix.build-mode }}
@@ -63,6 +63,6 @@ jobs:
6363
pip install -e .
6464
6565
- name: Perform CodeQL Analysis
66-
uses: github/codeql-action/analyze@fca7ace96b7d713c7035871441bd52efbe39e27e # v3
66+
uses: github/codeql-action/analyze@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3
6767
with:
6868
category: "/language:${{matrix.language}}"

.github/workflows/zizmor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
env:
2727
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2828
- name: Upload SARIF file
29-
uses: github/codeql-action/upload-sarif@fca7ace96b7d713c7035871441bd52efbe39e27e # v3
29+
uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3
3030
with:
3131
sarif_file: results.sarif
3232
category: zizmor

CONTRIBUTING.md

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,15 @@ just docs-serve
190190
Browse to the link provided, and then as you make changes to docstrings or narrative docs,
191191
the pages will re-render and the browser will automatically refresh.
192192

193-
194193
## Running Tests Locally
195194

196-
- Ensure you have started the appropriate Mongo Server(s).
197195
- Run `just install` to set a local virtual environment, or you can manually
198196
create a virtual environment and run `pytest` directly. If you want to use a specific
199197
version of Python, remove the `.venv` folder and set `PYTHON_BINARY` before running `just install`.
198+
- Ensure you have started the appropriate Mongo Server(s). You can run `just run-server` with optional args
199+
to set up the server. All given options will be passed to
200+
[`run-orchestration.sh`](https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/run-orchestration.sh). Run `$DRIVERS_TOOLS/evergreen/run-orchestration.sh -h`
201+
for a full list of options.
200202
- Run `just test` or `pytest` to run all of the tests.
201203
- Append `test/<mod_name>.py::<class_name>::<test_name>` to run
202204
specific tests. You can omit the `<test_name>` to test a full class
@@ -213,18 +215,36 @@ the pages will re-render and the browser will automatically refresh.
213215
`git clone [email protected]:mongodb-labs/drivers-evergreen-tools.git`.
214216
- Run `export DRIVERS_TOOLS=$PWD/drivers-evergreen-tools`. This can be put into a `.bashrc` file
215217
for convenience.
216-
- Set up access to [Drivers test secrets](https://github.com/mongodb-labs/drivers-evergreen-tools/tree/master/.evergreen/secrets_handling#secrets-handling).
218+
- Some tests require access to [Drivers test secrets](https://github.com/mongodb-labs/drivers-evergreen-tools/tree/master/.evergreen/secrets_handling#secrets-handling).
217219

218220
### Usage
219221

220-
- Run `just run-server` with optional args to set up the server. All given options will be passed to
221-
`run-orchestration.sh` in `$DRIVERS_TOOLS`. See `$DRIVERS_TOOLS/evergreen/run-orchestration.sh -h`
222-
for a full list of options.
222+
- Run `just run-server` with optional args to set up the server.
223223
- Run `just setup-tests` with optional args to set up the test environment, secrets, etc.
224224
See `just setup-tests -h` for a full list of available options.
225225
- Run `just run-tests` to run the tests in an appropriate Python environment.
226226
- When done, run `just teardown-tests` to clean up and `just stop-server` to stop the server.
227227

228+
### SSL tests
229+
230+
- Run `just run-server --ssl` to start the server with TLS enabled.
231+
- Run `just setup-tests --ssl`.
232+
- Run `just run-tests`.
233+
234+
Note: for general testing purposes with an TLS-enabled server, you can use the following (this should ONLY be used
235+
for local testing):
236+
237+
```python
238+
from pymongo import MongoClient
239+
240+
client = MongoClient(
241+
"mongodb://localhost:27017?tls=true&tlsAllowInvalidCertificates=true"
242+
)
243+
```
244+
245+
If you want to use the actual certificate file then set `tlsCertificateKeyFile` to the local path
246+
to `<repo_roo>/test/certificates/client.pem` and `tlsCAFile` to the local path to `<repo_roo>/test/certificates/ca.pem`.
247+
228248
### Encryption tests
229249

230250
- Run `just run-server` to start the server.
@@ -434,6 +454,7 @@ run `pre-commit run --all-files --hook-stage manual ruff` and fix all reported e
434454
hook again.
435455

436456
## Converting a test to async
457+
437458
The `tools/convert_test_to_async.py` script takes in an existing synchronous test file and outputs a
438459
partially-converted asynchronous version of the same name to the `test/asynchronous` directory.
439460
Use this generated file as a starting point for the completed conversion.

doc/changelog.rst

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,39 @@ PyMongo 4.14 brings a number of changes including:
88
- Added :attr:`bson.codec_options.TypeRegistry.codecs` and :attr:`bson.codec_options.TypeRegistry.fallback_encoder` properties
99
to allow users to directly access the type codecs and fallback encoder for a given :class:`bson.codec_options.TypeRegistry`.
1010

11+
Changes in Version 4.13.2 (2025/06/17)
12+
--------------------------------------
13+
14+
Version 4.13.2 is a bug fix release.
15+
16+
- Fixed a bug where ``AsyncMongoClient`` would block the event loop while creating new connections,
17+
potentially significantly increasing latency for ongoing operations.
18+
19+
Issues Resolved
20+
...............
21+
22+
See the `PyMongo 4.13.2 release notes in JIRA`_ for the list of resolved issues
23+
in this release.
24+
25+
.. _PyMongo 4.13.2 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=43937
26+
27+
28+
Changes in Version 4.13.1 (2025/06/10)
29+
--------------------------------------
30+
31+
Version 4.13.1 is a bug fix release.
32+
33+
- Fixed a bug that could raise ``ServerSelectionTimeoutError`` when using timeouts with ``AsyncMongoClient``.
34+
- Fixed a bug that could raise ``NetworkTimeout`` errors on Windows.
35+
36+
Issues Resolved
37+
...............
38+
39+
See the `PyMongo 4.13.1 release notes in JIRA`_ for the list of resolved issues
40+
in this release.
41+
42+
.. _PyMongo 4.13.1 release notes in JIRA: https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=10004&version=43924
43+
1144
Changes in Version 4.13.0 (2025/05/14)
1245
--------------------------------------
1346

@@ -1700,8 +1733,7 @@ Changes in Version 3.8.0 (2019/04/22)
17001733
-------------------------------------
17011734

17021735
.. warning:: PyMongo no longer supports Python 2.6. RHEL 6 users should install
1703-
Python 2.7 or newer from `Red Hat Software Collections
1704-
<https://developers.redhat.com/products/softwarecollections/overview>`_.
1736+
Python 2.7 or newer from Red Hat Software Collections.
17051737
CentOS 6 users should install Python 2.7 or newer from `SCL
17061738
<https://wiki.centos.org/AdditionalResources/Repositories/SCL>`_
17071739

doc/conf.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
# Options for link checking
8383
# The anchors on the rendered markdown page are created after the fact,
8484
# so those link results in a 404.
85-
# wiki.centos.org has been flakey.
85+
# wiki.centos.org has been flaky.
8686
# sourceforge.net is giving a 403 error, but is still accessible from the browser.
8787
linkcheck_ignore = [
8888
"https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-monitoring.md#requesting-an-immediate-check",
@@ -91,6 +91,9 @@
9191
r"https://sourceforge.net/",
9292
]
9393

94+
# Allow for flaky links.
95+
linkcheck_retries = 3
96+
9497
# -- Options for extensions ----------------------------------------------------
9598
autoclass_content = "init"
9699

pymongo/network_layer.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ async def _async_socket_receive(
286286

287287

288288
_PYPY = "PyPy" in sys.version
289+
_WINDOWS = sys.platform == "win32"
289290

290291

291292
def wait_for_read(conn: Connection, deadline: Optional[float]) -> None:
@@ -337,7 +338,8 @@ def receive_data(conn: Connection, length: int, deadline: Optional[float]) -> me
337338
while bytes_read < length:
338339
try:
339340
# Use the legacy wait_for_read cancellation approach on PyPy due to PYTHON-5011.
340-
if _PYPY:
341+
# also use it on Windows due to PYTHON-5405
342+
if _PYPY or _WINDOWS:
341343
wait_for_read(conn, deadline)
342344
if _csot.get_timeout() and deadline is not None:
343345
conn.set_conn_timeout(max(deadline - time.monotonic(), 0))
@@ -359,6 +361,7 @@ def receive_data(conn: Connection, length: int, deadline: Optional[float]) -> me
359361
raise _OperationCancelled("operation cancelled") from None
360362
if (
361363
_PYPY
364+
or _WINDOWS
362365
or not conn.is_sdam
363366
and deadline is not None
364367
and deadline - time.monotonic() < 0

pymongo/pool_shared.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ async def _async_create_connection(address: _Address, options: PoolOptions) -> s
206206
# SOCK_CLOEXEC not supported for Unix sockets.
207207
_set_non_inheritable_non_atomic(sock.fileno())
208208
try:
209-
sock.connect(host)
209+
sock.setblocking(False)
210+
await asyncio.get_running_loop().sock_connect(sock, host)
210211
return sock
211212
except OSError:
212213
sock.close()
@@ -241,14 +242,22 @@ async def _async_create_connection(address: _Address, options: PoolOptions) -> s
241242
timeout = options.connect_timeout
242243
elif timeout <= 0:
243244
raise socket.timeout("timed out")
244-
sock.settimeout(timeout)
245245
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True)
246246
_set_keepalive_times(sock)
247-
sock.connect(sa)
247+
# Socket needs to be non-blocking during connection to not block the event loop
248+
sock.setblocking(False)
249+
await asyncio.wait_for(
250+
asyncio.get_running_loop().sock_connect(sock, sa), timeout=timeout
251+
)
252+
sock.settimeout(timeout)
248253
return sock
254+
except asyncio.TimeoutError as e:
255+
sock.close()
256+
err = socket.timeout("timed out")
257+
err.__cause__ = e
249258
except OSError as e:
250-
err = e
251259
sock.close()
260+
err = e # type: ignore[assignment]
252261

253262
if err is not None:
254263
raise err

pymongo/pyopenssl_context.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,9 @@ def wrap_socket(
420420
pyopenssl.verify_ip_address(ssl_conn, server_hostname)
421421
else:
422422
pyopenssl.verify_hostname(ssl_conn, server_hostname)
423-
except ( # type:ignore[misc]
424-
service_identity.SICertificateError,
425-
service_identity.SIVerificationError,
423+
except (
424+
service_identity.CertificateError,
425+
service_identity.VerificationError,
426426
) as exc:
427427
raise _CertificateError(str(exc)) from None
428428
return ssl_conn

0 commit comments

Comments
 (0)