Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
8c0f314
PYTHON-5846 Consolidate CMAP, heartbeat, and SDAM telemetry into _tel…
blink1073 Jun 30, 2026
bb7a81f
PYTHON-5900 - Clarify Cursor and CommandCursor docstrings to indicate…
NoahStapp Jun 30, 2026
265971c
PYTHON-5846 Refine _CmapTelemetry and _HeartbeatTelemetry API
blink1073 Jun 30, 2026
bde775e
PYTHON-5911 - Mark test.test_server_selection_in_window.TestProse.tes…
NoahStapp Jun 30, 2026
55b21ec
PYTHON-5846 Move duration tracking into telemetry classes
blink1073 Jun 30, 2026
a30d380
PYTHON-5846 Fix awaited value in heartbeat succeeded APM event
blink1073 Jun 30, 2026
577b594
PYTHON-5846 Add _emit_log helpers to _HeartbeatTelemetry and _SdamTel…
blink1073 Jun 30, 2026
fc143ff
PYTHON-5846 Fix durationMS unit in CMAP log entries (seconds -> milli…
blink1073 Jun 30, 2026
4ea5205
PYTHON-5846 Replace cached telemetry flags with dynamic properties
blink1073 Jul 1, 2026
553dc31
PYTHON-5846 Drop publish param from _HeartbeatTelemetry, derive from …
blink1073 Jul 1, 2026
0f33a1c
PYTHON-5846 Decompose Hello response in _HeartbeatTelemetry.succeeded
blink1073 Jul 1, 2026
3eefcf7
PYTHON-5846 Fix typing: use Hello type in _HeartbeatTelemetry.succeeded
blink1073 Jul 1, 2026
d844557
PYTHON-5846 Consolidate server selection logging and retry logging in…
blink1073 Jul 1, 2026
57f4e50
PYTHON-5846 Move _should_log check to call site in all telemetry classes
blink1073 Jul 1, 2026
d51f38b
PYTHON-5846 Cache _should_log/_should_publish in short-lived telemetr…
blink1073 Jul 1, 2026
de14677
PYTHON-5846 Cache _should_log/_should_publish locally and guard durat…
blink1073 Jul 1, 2026
1ccf555
PYTHON-5875 - Call setParameter on each mongos for test_connection_po…
NoahStapp Jul 1, 2026
488c750
PYTHON-5846 Add comments explaining unconditional start time recordin…
blink1073 Jul 1, 2026
ef09fdd
PYTHON-5889 - Clean up AGENTS.md instructions (#2909)
NoahStapp Jul 1, 2026
58e966b
PYTHON-5846 Only record heartbeat start time when logging or publishi…
blink1073 Jul 1, 2026
f7611d1
PYTHON-5912 - Skip substringPreview on server 9.0+ (#2910)
NoahStapp Jul 1, 2026
2746386
Update pymongo/asynchronous/mongo_client.py
blink1073 Jul 1, 2026
ed81f02
PYTHON-5913 - Remove synchro converted_tests and associated CONTRIBUT…
NoahStapp Jul 1, 2026
012c143
PYTHON-5846 Address PR review comments on telemetry refactor
blink1073 Jul 1, 2026
9cca32b
PYTHON-5846 Address further PR review comments
blink1073 Jul 1, 2026
9fab1db
PYTHON-5846 Fix test callers to unpack (servers, ss) tuple from selec…
blink1073 Jul 1, 2026
a9cb8b2
PYTHON-5846 Pass live topology description to ss.succeeded()
blink1073 Jul 2, 2026
ed6991a
PYTHON-5781 Coverage increase for `network_layer.py` (#2774)
aclark4life Jul 2, 2026
45ebb6b
Fix docstring
blink1073 Jul 6, 2026
4eb4d6d
Bump the actions group across 1 directory with 2 updates (#2914)
dependabot[bot] Jul 6, 2026
339ab4c
Bump ruff from 0.15.18 to 0.15.20 (#2912)
dependabot[bot] Jul 6, 2026
a09a6bb
Bump pyright from 1.1.410 to 1.1.411 (#2913)
dependabot[bot] Jul 6, 2026
cb8a2e8
PYTHON-5846 Initialize _HeartbeatTelemetry._start in __init__
blink1073 Jul 6, 2026
bad740d
PYTHON-5846 Update async topology docstring to match sync
blink1073 Jul 6, 2026
c224067
PYTHON-5799 Skip TestExplicitTextEncryptionProse tests (#2915)
blink1073 Jul 6, 2026
ef5ec33
Merge branch 'master' into PYTHON-5846
blink1073 Jul 6, 2026
a167a86
PYTHON-5917 Fix document_class generic alias check on PyPy (#2917)
blink1073 Jul 7, 2026
f8e8cff
PYTHON-5915 - Bump cryptography version to 47.0.0 (#2911)
NoahStapp Jul 7, 2026
c9b2331
PYTHON-5920 - Use mock instead of patching for test_network_layer.py …
NoahStapp Jul 7, 2026
7ba7481
PYTHON-5921 Validate OIDC allowed hosts before authenticator reuse (#…
NguyenCong2k Jul 8, 2026
c19f936
PYTHON-5846 Replace Any with proper types in _telemetry.py
blink1073 Jul 8, 2026
6868db4
Merge branch 'PYTHON-5846' of github.com:blink1073/mongo-python-drive…
blink1073 Jul 8, 2026
f9c029e
PYTHON-5856 Move cursor execution logic into cursor class (#2894)
aclark4life Jul 8, 2026
64e24c9
PYTHON-5327 Add test for SRV hostname validation (#2863)
aclark4life Jul 8, 2026
25f718c
Merge upstream/master into PYTHON-5846
blink1073 Jul 8, 2026
d414fd6
PYTHON-5846 Compute awaited at emit time in _HeartbeatTelemetry
blink1073 Jul 8, 2026
e4a340a
PYTHON-5846 Reuse _monotonic_duration helper in _telemetry.py
blink1073 Jul 8, 2026
55a2c16
PYTHON-5846 Remove unused _topology_id attribute from Server
blink1073 Jul 8, 2026
cd702c4
PYTHON-5846 Make server selection succeeded logging a standalone func…
blink1073 Jul 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
with:
ref: ${{ inputs.ref }}
persist-credentials: false
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:

steps:
- name: Checkout pymongo
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
with:
fetch-depth: 0
persist-credentials: false
Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
name: Make SDist
runs-on: macos-latest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
fetch-depth: 0
persist-credentials: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sbom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
with:
persist-credentials: false

Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
static:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand Down Expand Up @@ -67,7 +67,7 @@ jobs:

name: Python ${{ matrix.python-version }}-${{ matrix.os }}
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand All @@ -89,7 +89,7 @@ jobs:

name: Coverage
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand Down Expand Up @@ -117,7 +117,7 @@ jobs:
runs-on: ubuntu-latest
name: DocTest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand All @@ -142,7 +142,7 @@ jobs:
name: Docs Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand All @@ -164,7 +164,7 @@ jobs:
matrix:
python: ["3.10", "3.11"]
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand All @@ -185,7 +185,7 @@ jobs:
runs-on: ubuntu-latest
name: Integration Tests
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand Down Expand Up @@ -215,7 +215,7 @@ jobs:
runs-on: ubuntu-latest
name: "Make an sdist"
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- uses: actions/setup-python@v6
Expand Down Expand Up @@ -275,7 +275,7 @@ jobs:
runs-on: ubuntu-latest
name: Test minimum dependencies and Python
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Install uv
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/zizmor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
with:
persist-credentials: false
- name: Run zizmor 🌈
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7
35 changes: 14 additions & 21 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
Official Python driver for MongoDB.

## Tech Stack
- **Build/env:** `hatch` — use `hatch run test:test` and `hatch run test:test-async`, not `pytest` directly
- **Task runner:** `just` (Justfile at repo root)
- **Linter/formatter:** `ruff` via pre-commit
- **Type checker:** `mypy` (strict)
Expand All @@ -13,37 +12,31 @@ Official Python driver for MongoDB.
> **Never** run `pip install bson`. PyMongo ships its own `bson`; the PyPI `bson` package silently breaks things.

## Project Structure
- `pymongo/synchronous/` — sync driver (MongoClient, Collection, Database, etc.) generated from `pymongo/asynchronous/` using unasync
- `pymongo/asynchronous/` — async API, mirrors `pymongo/synchronous/`
- `pymongo/asynchronous/` — async driver (AsyncMongoClient, AsyncCollection, etc.)
- `pymongo/synchronous/` — sync driver (MongoClient, Collection, etc.) generated from `pymongo/asynchronous/` using `just synchro`
- `bson/` — BSON implementation
- `gridfs/` — GridFS API
- `test/` — sync test suite
- `test/asynchronous/` — async test suite, mirrors `test/`
- `test/asynchronous/` — async test suite
- `test/` — sync test suite (generated from `test/asynchronous/` by `just synchro`) and shared test suite
- `test/unified_format/` — cross-driver spec tests (Unified Test Format)
- `tools/convert_test_to_async.py` — generates async test stubs from sync tests

Do not edit files in `pymongo/synchronous/` or mirrored files in `test/` directly: they are generated by `just synchro` from `pymongo/asynchronous/` and `test/asynchronous/`.
A file in `test/` is mirrored if a file of the same name exists in `test/asynchronous/`.

## Commands
```bash
just install # set up venv + pre-commit hook
just typing-mypy # type check
just run lint-manual # ruff linter

hatch run test:test # run sync tests
hatch run test:test-async # run async tests

MONGODB_VERSION=8.0 just run-server # start a local MongoDB server
just install # set up venv + pre-commit hooks
just typing # type check
just lint-manual # pre-commit linting and synchro
just synchro # generate synchronous driver and mirrored tests
just test # run all tests
just test test/asynchronous # run async tests
MONGODB_VERSION=8.0 just run-server # start a local MongoDB 8.0 server
```

## Testing
Tests require a live MongoDB server (`just run-server` above).

Never modify pymongo/synchronous code first; update the async counterpart and run our `tools/synchro.py` script:
1. Make changes in `pymongo/asynchronous` or top-level `pymongo/` files and `test/`.
2. Run `tools/convert_test_to_async.py` on the sync test file to generate a starting-point async version.
3. Manually complete the async version in `test/asynchronous/`.

Do not edit files in `pymongo/synchronous/` or mirrored files in `test/` directly — they are auto-generated by `tools/synchro.py` from `pymongo/asynchronous/` and `test/asynchronous/`. Only edit them if the change includes a `_IS_SYNC` statement.

Async functions must not call blocking I/O.

New features need integration tests. Bug fixes need regression tests.
Expand Down
8 changes: 0 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,14 +529,6 @@ Python errors, such as missing imports, incorrect syntax, or other fatal typos.
run `pre-commit run --all-files --hook-stage manual ruff` and fix all reported errors before running the `synchro`
hook again.

## Converting a test to async

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

The script is used like so: `python tools/convert_test_to_async.py [test_file.py]`

## CPU profiling

To profile a test script and generate a flame graph, follow these steps:
Expand Down
14 changes: 8 additions & 6 deletions bson/codec_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,14 +377,16 @@ def __new__(
datetime_conversion: Optional[DatetimeConversion] = DatetimeConversion.DATETIME,
) -> CodecOptions:
doc_class = document_class or dict
# issubclass can raise TypeError for generic aliases like SON[str, Any].
# In that case we can use the base class for the comparison.
is_mapping = False
# Generic aliases like SON[str, Any] or dict[str, Any] aren't classes, so
# resolve to their origin before the subclass check. Whether issubclass()
# raises TypeError or just returns False for such aliases is inconsistent
# across Python implementations (e.g. PyPy vs CPython), so check the
# origin proactively instead of relying on catching the error.
check_class = getattr(doc_class, "__origin__", doc_class)
try:
is_mapping = issubclass(doc_class, _MutableMapping)
is_mapping = issubclass(check_class, _MutableMapping)
except TypeError:
if hasattr(doc_class, "__origin__"):
is_mapping = issubclass(doc_class.__origin__, _MutableMapping)
is_mapping = False
if not (is_mapping or _raw_document_class(doc_class)):
raise TypeError(
"document_class must be dict, bson.son.SON, "
Expand Down
5 changes: 5 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ lint *args="": && resync
lint-manual *args="": && resync
uvx pre-commit run --all-files --hook-stage manual {{args}}

# Run synchro
[group('lint')]
synchro: && resync
uvx pre-commit run --all-files synchro

# Run pytest (e.g. just test test/test_uri_parser.py)
[group('test')]
test *args="-v --durations=5 --maxfail=10": && resync
Expand Down
Loading
Loading