Compare commits
35 Commits
PYTHON-543
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cd98d9b94 | ||
|
|
4fe13c6f25 | ||
|
|
f45226d02f | ||
|
|
c869e5cd7d | ||
|
|
160dbce99f | ||
|
|
2433f62fd9 | ||
|
|
99b56b4633 | ||
|
|
bb744b7b5c | ||
|
|
94a26fa9da | ||
|
|
b3b102a89d | ||
|
|
9bae93d875 | ||
|
|
aab94545dd | ||
|
|
ccc861c5c7 | ||
|
|
87d1c9ed87 | ||
|
|
77bd8ba755 | ||
|
|
61c0e5ccf0 | ||
|
|
156f3b5f16 | ||
|
|
bafa539ed0 | ||
|
|
d0ed67cd80 | ||
|
|
7785176fdc | ||
|
|
536b2dd9d8 | ||
|
|
224da029d5 | ||
|
|
52234081fb | ||
|
|
b81fd4e181 | ||
|
|
820ba59552 | ||
|
|
144c460d8e | ||
|
|
d6c688b609 | ||
|
|
79fd03a68f | ||
|
|
33e4f112c7 | ||
|
|
12d9d7db05 | ||
|
|
5bcdd4ad6a | ||
|
|
5fc7c41fb5 | ||
|
|
bbada7dace | ||
|
|
4bb5e32e80 | ||
|
|
8412d20e28 |
@ -346,33 +346,6 @@ tasks:
|
||||
|
||||
# Test tasks {{{
|
||||
|
||||
- name: "test-4.0-standalone"
|
||||
tags: ["4.0", "standalone"]
|
||||
commands:
|
||||
- func: "bootstrap mongo-orchestration"
|
||||
vars:
|
||||
VERSION: "4.0"
|
||||
TOPOLOGY: "server"
|
||||
- func: "run tox"
|
||||
|
||||
- name: "test-4.0-replica_set"
|
||||
tags: ["4.0", "replica_set"]
|
||||
commands:
|
||||
- func: "bootstrap mongo-orchestration"
|
||||
vars:
|
||||
VERSION: "4.0"
|
||||
TOPOLOGY: "replica_set"
|
||||
- func: "run tox"
|
||||
|
||||
- name: "test-4.0-sharded_cluster"
|
||||
tags: ["4.0", "sharded_cluster"]
|
||||
commands:
|
||||
- func: "bootstrap mongo-orchestration"
|
||||
vars:
|
||||
VERSION: "4.0"
|
||||
TOPOLOGY: "sharded_cluster"
|
||||
- func: "run tox"
|
||||
|
||||
- name: "test-4.2-standalone"
|
||||
tags: ["4.2", "standalone"]
|
||||
commands:
|
||||
@ -636,14 +609,10 @@ axes:
|
||||
- id: tox-env
|
||||
display_name: "Tox Env RHEL8"
|
||||
values:
|
||||
- id: "test-pypy39"
|
||||
- id: "test-pypy310"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "/opt/python/pypy3.9/bin/python3"
|
||||
- id: "test-py39"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/pypy3.10/bin/python3"
|
||||
- id: "test-py310"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
@ -660,55 +629,55 @@ axes:
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "/opt/python/3.13/bin/python3"
|
||||
- id: "test-py314"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "/opt/python/3.14/bin/python3"
|
||||
- id: "test-pymongo-4.9"
|
||||
variables:
|
||||
TOX_ENV: "test-pymongo-4.9"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
- id: "test-pymongo-4.10"
|
||||
variables:
|
||||
TOX_ENV: "test-pymongo-4.10"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
- id: "test-pymongo-4.11"
|
||||
variables:
|
||||
TOX_ENV: "test-pymongo-4.11"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
- id: "test-pymongo-latest"
|
||||
variables:
|
||||
TOX_ENV: "test-pymongo-latest"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
- id: "synchro-py39"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
- id: "synchro-py310"
|
||||
variables:
|
||||
TOX_ENV: "synchro"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
- id: "synchro-py312"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
- id: "synchro-py313"
|
||||
variables:
|
||||
TOX_ENV: "synchro"
|
||||
PYTHON_BINARY: "/opt/python/3.12/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/3.13/bin/python3"
|
||||
|
||||
- id: tox-env-rhel7
|
||||
display_name: "Tox Env RHEL7"
|
||||
- id: tox-env-rhel8
|
||||
display_name: "Tox Env RHEL8"
|
||||
values:
|
||||
- id: "test"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
|
||||
# Test Python 3.9 only on Mac.
|
||||
# Test Python 3.10 only on Mac.
|
||||
- id: tox-env-osx
|
||||
display_name: "Tox Env OSX"
|
||||
values:
|
||||
- id: "test"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "/Library/Frameworks/Python.framework/Versions/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/Library/Frameworks/Python.framework/Versions/3.10/bin/python3"
|
||||
|
||||
- id: tox-env-win
|
||||
display_name: "Tox Env Windows"
|
||||
values:
|
||||
- id: "test-py39"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "c:/python/Python39/python.exe"
|
||||
- id: "test-py310"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
@ -721,6 +690,14 @@ axes:
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "c:/python/Python312/python.exe"
|
||||
- id: "test-py313"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "c:/python/Python313/python.exe"
|
||||
- id: "test-py314"
|
||||
variables:
|
||||
TOX_ENV: "test"
|
||||
PYTHON_BINARY: "c:/python/Python314/python.exe"
|
||||
|
||||
- id: os
|
||||
display_name: "Operating System"
|
||||
@ -728,9 +705,6 @@ axes:
|
||||
- id: "rhel8"
|
||||
display_name: "RHEL 8.x"
|
||||
run_on: "rhel84-small"
|
||||
- id: "rhel7"
|
||||
display_name: "RHEL 7.x"
|
||||
run_on: "rhel79-small"
|
||||
- id: "win"
|
||||
display_name: "Windows"
|
||||
run_on: "windows-64-vsMulti-small"
|
||||
@ -751,7 +725,7 @@ buildvariants:
|
||||
# TODO: synchro needs PyMongo's updated SSL test certs,
|
||||
# which may require Motor test suite changes.
|
||||
- os: "*"
|
||||
tox-env: ["synchro-py39", "synchro-py312"]
|
||||
tox-env: ["synchro-py310", "synchro-py313"]
|
||||
ssl: "ssl"
|
||||
tasks:
|
||||
- ".rapid"
|
||||
@ -764,11 +738,11 @@ buildvariants:
|
||||
- ".4.2"
|
||||
- ".4.0"
|
||||
|
||||
- matrix_name: "test-rhel7"
|
||||
display_name: "${os}-${tox-env-rhel7}-${ssl}"
|
||||
- matrix_name: "test-rhel8"
|
||||
display_name: "${os}-${tox-env-rhel8}-${ssl}"
|
||||
matrix_spec:
|
||||
os: "rhel7"
|
||||
tox-env-rhel7: "*"
|
||||
os: "rhel8"
|
||||
tox-env-rhel8: "*"
|
||||
ssl: "*"
|
||||
tasks:
|
||||
- ".rapid"
|
||||
@ -811,7 +785,7 @@ buildvariants:
|
||||
|
||||
- matrix_name: "enterprise-auth"
|
||||
display_name: "Enterprise Auth-${tox-env}"
|
||||
matrix_spec: {"tox-env": ["synchro-py39", "synchro-py312"], ssl: "ssl"}
|
||||
matrix_spec: {"tox-env": ["synchro-py310", "synchro-py313"], ssl: "ssl"}
|
||||
run_on:
|
||||
- "rhel84-small"
|
||||
tasks:
|
||||
@ -823,7 +797,7 @@ buildvariants:
|
||||
- "rhel84-small"
|
||||
expansions:
|
||||
TOX_ENV: "docs"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
tasks:
|
||||
- name: "docs"
|
||||
|
||||
@ -833,6 +807,6 @@ buildvariants:
|
||||
- "rhel84-small"
|
||||
expansions:
|
||||
TOX_ENV: "doctest"
|
||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
||||
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||
tasks:
|
||||
- name: "doctest"
|
||||
|
||||
8
.github/workflows/codeql.yml
vendored
8
.github/workflows/codeql.yml
vendored
@ -44,18 +44,18 @@ jobs:
|
||||
- language: actions
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@28deaeda66b76a05916b6923827895f2b14ab387 # v3
|
||||
uses: github/codeql-action/init@c793b717bc78562f491db7b0e93a3a178b099162 # v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: none
|
||||
@ -71,6 +71,6 @@ jobs:
|
||||
pip install -e .
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@28deaeda66b76a05916b6923827895f2b14ab387 # v3
|
||||
uses: github/codeql-action/analyze@c793b717bc78562f491db7b0e93a3a178b099162 # v4
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
6
.github/workflows/dist.yml
vendored
6
.github/workflows/dist.yml
vendored
@ -24,12 +24,12 @@ jobs:
|
||||
name: "Build Dist"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Install dependencies
|
||||
@ -37,7 +37,7 @@ jobs:
|
||||
- name: Create packages
|
||||
run: python -m build .
|
||||
- name: Store package artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: all-dist-${{ github.run_id }}
|
||||
path: "dist/*"
|
||||
|
||||
20
.github/workflows/release.yml
vendored
20
.github/workflows/release.yml
vendored
@ -38,17 +38,16 @@ jobs:
|
||||
outputs:
|
||||
version: ${{ steps.pre-publish.outputs.version }}
|
||||
steps:
|
||||
- uses: mongodb-labs/drivers-github-tools/secure-checkout@v2
|
||||
- uses: mongodb-labs/drivers-github-tools/secure-checkout@v3
|
||||
with:
|
||||
app_id: ${{ vars.APP_ID }}
|
||||
private_key: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
- uses: mongodb-labs/drivers-github-tools/setup@v2
|
||||
- uses: mongodb-labs/drivers-github-tools/setup@v3
|
||||
with:
|
||||
aws_role_arn: ${{ secrets.AWS_ROLE_ARN }}
|
||||
aws_region_name: ${{ vars.AWS_REGION_NAME }}
|
||||
aws_secret_id: ${{ secrets.AWS_SECRET_ID }}
|
||||
artifactory_username: ${{ vars.ARTIFACTORY_USERNAME }}
|
||||
- uses: mongodb-labs/drivers-github-tools/python/pre-publish@v2
|
||||
- uses: mongodb-labs/drivers-github-tools/python/pre-publish@v3
|
||||
id: pre-publish
|
||||
with:
|
||||
dry_run: ${{ env.DRY_RUN }}
|
||||
@ -74,19 +73,19 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Download all the dists
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: all-dist-${{ github.run_id }}
|
||||
path: dist/
|
||||
- name: Publish package distributions to TestPyPI
|
||||
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1
|
||||
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
||||
with:
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
skip-existing: true
|
||||
attestations: ${{ env.DRY_RUN }}
|
||||
- name: Publish package distributions to PyPI
|
||||
if: startsWith(env.DRY_RUN, 'false')
|
||||
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1
|
||||
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
|
||||
|
||||
post-publish:
|
||||
needs: [publish]
|
||||
@ -98,17 +97,16 @@ jobs:
|
||||
attestations: write
|
||||
security-events: write
|
||||
steps:
|
||||
- uses: mongodb-labs/drivers-github-tools/secure-checkout@v2
|
||||
- uses: mongodb-labs/drivers-github-tools/secure-checkout@v3
|
||||
with:
|
||||
app_id: ${{ vars.APP_ID }}
|
||||
private_key: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
- uses: mongodb-labs/drivers-github-tools/setup@v2
|
||||
- uses: mongodb-labs/drivers-github-tools/setup@v3
|
||||
with:
|
||||
aws_role_arn: ${{ secrets.AWS_ROLE_ARN }}
|
||||
aws_region_name: ${{ vars.AWS_REGION_NAME }}
|
||||
aws_secret_id: ${{ secrets.AWS_SECRET_ID }}
|
||||
artifactory_username: ${{ vars.ARTIFACTORY_USERNAME }}
|
||||
- uses: mongodb-labs/drivers-github-tools/python/post-publish@v2
|
||||
- uses: mongodb-labs/drivers-github-tools/python/post-publish@v3
|
||||
with:
|
||||
following_version: ${{ env.FOLLOWING_VERSION }}
|
||||
product_name: ${{ env.PRODUCT_NAME }}
|
||||
|
||||
30
.github/workflows/test-python.yml
vendored
30
.github/workflows/test-python.yml
vendored
@ -20,15 +20,15 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
python-version: ["3.9", "3.12", "3.13"]
|
||||
python-version: ["3.10", "3.12", "3.14"]
|
||||
fail-fast: false
|
||||
name: CPython ${{ matrix.python-version }}-${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
@ -49,12 +49,12 @@ jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.9
|
||||
python-version: '3.10'
|
||||
cache: 'pip'
|
||||
cache-dependency-path: 'pyproject.toml'
|
||||
- name: Install Python dependencies
|
||||
@ -67,12 +67,12 @@ jobs:
|
||||
docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.9
|
||||
python-version: '3.10'
|
||||
cache: 'pip'
|
||||
cache-dependency-path: 'pyproject.toml'
|
||||
- name: Install Python dependencies
|
||||
@ -83,7 +83,7 @@ jobs:
|
||||
- name: Run linkcheck
|
||||
run: tox -m linkcheck
|
||||
- name: Start MongoDB
|
||||
uses: supercharge/mongodb-github-action@90004df786821b6308fb02299e5835d0dae05d0d # 1.12.0
|
||||
uses: supercharge/mongodb-github-action@315db7fe45ac2880b7758f1933e6e5d59afd5e94 # 1.12.1
|
||||
with:
|
||||
mongodb-version: 5.0
|
||||
- name: Run doctest
|
||||
@ -92,12 +92,12 @@ jobs:
|
||||
release:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.9
|
||||
python-version: '3.10'
|
||||
cache: 'pip'
|
||||
cache-dependency-path: 'pyproject.toml'
|
||||
- name: Install Python dependencies
|
||||
@ -111,11 +111,11 @@ jobs:
|
||||
name: Typing Tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.10"
|
||||
cache: 'pip'
|
||||
|
||||
19
.github/workflows/zizmor.yml
vendored
19
.github/workflows/zizmor.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: GitHub Actions Security Analysis with zizmor
|
||||
name: GitHub Actions Security Analysis with zizmor 🌈
|
||||
|
||||
on:
|
||||
push:
|
||||
@ -14,19 +14,8 @@ jobs:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Setup Rust
|
||||
uses: actions-rust-lang/setup-rust-toolchain@9d7e65c320fdb52dcd45ffaa68deb6c02c8754d9 # v1
|
||||
- name: Get zizmor
|
||||
run: cargo install zizmor
|
||||
- name: Run zizmor
|
||||
run: zizmor --format sarif . > results.sarif
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Upload SARIF file
|
||||
uses: github/codeql-action/upload-sarif@28deaeda66b76a05916b6923827895f2b14ab387 # v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
category: zizmor
|
||||
- name: Run zizmor 🌈
|
||||
uses: zizmorcore/zizmor-action@0dce2577a4760a2749d8cfb7a84b7d5585ebcb7d
|
||||
|
||||
7
.github/zizmor.yml
vendored
Normal file
7
.github/zizmor.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
rules:
|
||||
unpinned-uses:
|
||||
config:
|
||||
policies:
|
||||
actions/*: ref-pin
|
||||
mongodb-labs/drivers-github-tools/*: ref-pin
|
||||
mongodb-labs/drivers-evergreen-tools: ref-pin
|
||||
@ -35,7 +35,7 @@ Python version on your path, and run:
|
||||
tox -m test
|
||||
```
|
||||
|
||||
The doctests pass with Python 3.9+ and a MongoDB 5.0 instance running on
|
||||
The doctests pass with Python 3.10+ and a MongoDB 5.0 instance running on
|
||||
port 27017:
|
||||
|
||||
```bash
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
> No new features will be added to Motor, and only bug fixes will be provided until it reaches end of life on May 14th, 2026.
|
||||
> After that, only critical bug fixes will be made until final support ends on May 14th, 2027.
|
||||
> We strongly recommend migrating to the PyMongo Async API while Motor is still supported.
|
||||
> For help transitioning, see the Migrate to PyMongo Async guide: https://www.mongodb.com/docs/languages/python/pymongo-driver/current/reference/migration/>.
|
||||
> For help transitioning, see the Migrate to PyMongo Async guide: https://www.mongodb.com/docs/languages/python/pymongo-driver/current/reference/migration/.
|
||||
|
||||
## About
|
||||
|
||||
@ -116,7 +116,7 @@ by asyncio. It requires:
|
||||
|
||||
- Unix (including macOS) or Windows.
|
||||
- [PyMongo](http://pypi.python.org/pypi/pymongo/) >=4.9,<5
|
||||
- Python 3.9+
|
||||
- Python 3.10+
|
||||
|
||||
Optional dependencies:
|
||||
|
||||
@ -192,7 +192,7 @@ ReadTheDocs](https://motor.readthedocs.io/en/stable/examples/index.html).
|
||||
Motor's documentation is on
|
||||
[ReadTheDocs](https://motor.readthedocs.io/en/stable/).
|
||||
|
||||
Build the documentation with Python 3.9+. Install
|
||||
Build the documentation with Python 3.10+. Install
|
||||
[sphinx](http://sphinx.pocoo.org/), [Tornado](http://tornadoweb.org/),
|
||||
and [aiohttp](https://github.com/aio-libs/aiohttp), and do
|
||||
`cd doc; make html`.
|
||||
|
||||
@ -3,6 +3,18 @@ Changelog
|
||||
|
||||
.. currentmodule:: motor.motor_tornado
|
||||
|
||||
Motor 3.8.0
|
||||
-----------
|
||||
|
||||
.. warning:: As of May 14th, 2025, Motor is deprecated in favor of the GA release of the PyMongo Async API.
|
||||
No new features will be added to Motor, and only bug fixes will be provided until it reaches end of life on May 14th, 2026.
|
||||
After that, only critical bug fixes will be made until final support ends on May 14th, 2027.
|
||||
We strongly recommend migrating to the PyMongo Async API while Motor is still supported.
|
||||
For help transitioning, see the `Migrate to PyMongo Async guide <https://www.mongodb.com/docs/languages/python/pymongo-driver/current/reference/migration/>`_.
|
||||
|
||||
- Add support for Python 3.14.
|
||||
- Drop support for Python 3.9.
|
||||
|
||||
Motor 3.7.1
|
||||
-----------
|
||||
|
||||
@ -229,8 +241,8 @@ Breaking Changes
|
||||
- Comparing two :class:`~motor.motor_tornado.MotorClient` instances now
|
||||
uses a set of immutable properties rather than
|
||||
:attr:`~motor.motor_tornado.MotorClient.address` which can change.
|
||||
- Removed the ``disable_md5`` parameter for :class:`~gridfs.GridFSBucket` and
|
||||
:class:`~gridfs.GridFS`. See :ref:`removed-gridfs-checksum` for details.
|
||||
- Removed the ``disable_md5`` parameter for :class:`~pymongo.GridFSBucket` and
|
||||
:class:`~pymongo.GridFS`. See :ref:`removed-gridfs-checksum` for details.
|
||||
- PyMongoCrypt 1.2.0 or later is now required for client side field level
|
||||
encryption support.
|
||||
|
||||
@ -697,9 +709,9 @@ Highlights include:
|
||||
|
||||
- Complete support for MongoDB 3.4:
|
||||
|
||||
- Unicode aware string comparison using collations. See :ref:`PyMongo's examples for collation <collation-on-operation>`.
|
||||
- Unicode aware string comparison using collations.
|
||||
- :class:`MotorCursor` and :class:`MotorGridOutCursor` have a new attribute :meth:`~MotorCursor.collation`.
|
||||
- Support for the new :class:`~bson.decimal128.Decimal128` BSON type.
|
||||
- Support for the new :class:`~pymongo.decimal128.Decimal128` BSON type.
|
||||
- A new maxStalenessSeconds read preference option.
|
||||
- A username is no longer required for the MONGODB-X509 authentication
|
||||
mechanism when connected to MongoDB >= 3.4.
|
||||
@ -729,8 +741,8 @@ Highlights include:
|
||||
- TLS compression is now explicitly disabled when possible.
|
||||
- The Server Name Indication (SNI) TLS extension is used when possible.
|
||||
- PyMongo's ``bson`` module provides finer control over JSON encoding/decoding
|
||||
with :class:`~bson.json_util.JSONOptions`.
|
||||
- Allow :class:`~bson.code.Code` objects to have a scope of ``None``,
|
||||
with :class:`~pymongo.json_util.JSONOptions`.
|
||||
- Allow :class:`~pymongo.code.Code` objects to have a scope of ``None``,
|
||||
signifying no scope. Also allow encoding Code objects with an empty scope
|
||||
(i.e. ``{}``).
|
||||
|
||||
@ -850,9 +862,9 @@ The following find/find_one options have been removed:
|
||||
- await_data (use the new ``cursor_type`` option instead)
|
||||
- exhaust (use the new ``cursor_type`` option instead)
|
||||
- as_class (use :meth:`~motor.motor_tornado.MotorCollection.with_options` with
|
||||
:class:`~bson.codec_options.CodecOptions` instead)
|
||||
:class:`~pymongo.codec_options.CodecOptions` instead)
|
||||
- compile_re (BSON regular expressions are always decoded to
|
||||
:class:`~bson.regex.Regex`)
|
||||
:class:`~pymongo.regex.Regex`)
|
||||
|
||||
The following find/find_one options are deprecated:
|
||||
|
||||
|
||||
11
doc/conf.py
11
doc/conf.py
@ -73,7 +73,14 @@ pygments_style = "sphinx"
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
# modindex_common_prefix = []
|
||||
|
||||
linkcheck_ignore = [r"http://localhost:\d+"]
|
||||
# Links to release notes in jira give 401 error: unauthorized. MOTOR-1476
|
||||
linkcheck_ignore = [
|
||||
r"http://localhost:\d+",
|
||||
r"https://jira\.mongodb\.org/secure/ReleaseNote\.jspa.*",
|
||||
]
|
||||
|
||||
# Allow for flaky links.
|
||||
linkcheck_retries = 3
|
||||
|
||||
# -- Options for extensions ----------------------------------------------------
|
||||
autoclass_content = "init"
|
||||
@ -221,8 +228,6 @@ pymongo_version = metadata("pymongo")["version"]
|
||||
pymongo_inventory = ("https://pymongo.readthedocs.io/en/%s/" % pymongo_version, None)
|
||||
|
||||
intersphinx_mapping = {
|
||||
"bson": pymongo_inventory,
|
||||
"gridfs": pymongo_inventory,
|
||||
"pymongo": pymongo_inventory,
|
||||
"aiohttp": ("http://aiohttp.readthedocs.io/en/stable/", None),
|
||||
"tornado": ("http://www.tornadoweb.org/en/stable/", None),
|
||||
|
||||
@ -49,8 +49,8 @@ GridFS
|
||||
|
||||
- File-like
|
||||
|
||||
PyMongo's :class:`~gridfs.grid_file.GridIn` and
|
||||
:class:`~gridfs.grid_file.GridOut` strive to act like Python's built-in
|
||||
PyMongo's :class:`~pymongo.grid_file.GridIn` and
|
||||
:class:`~pymongo.grid_file.GridOut` strive to act like Python's built-in
|
||||
file objects, so they can be passed to many functions that expect files.
|
||||
But the I/O methods of :class:`MotorGridIn` and
|
||||
:class:`MotorGridOut` are asynchronous, so they cannot obey the
|
||||
@ -59,7 +59,7 @@ GridFS
|
||||
- Setting properties
|
||||
|
||||
In PyMongo, you can set arbitrary attributes on
|
||||
a :class:`~gridfs.grid_file.GridIn` and they're stored as metadata on
|
||||
a :class:`~pymongo.grid_file.GridIn` and they're stored as metadata on
|
||||
the server, even after the ``GridIn`` is closed::
|
||||
|
||||
fs = gridfs.GridFSBucket(db)
|
||||
|
||||
@ -74,7 +74,7 @@ Typed Client
|
||||
|
||||
:class:`~motor.motor_asyncio.AsyncIOMotorClient` is generic on the document type used to decode BSON documents.
|
||||
|
||||
You can specify a :class:`~bson.raw_bson.RawBSONDocument` document type:
|
||||
You can specify a :class:`~pymongo.raw_bson.RawBSONDocument` document type:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -89,7 +89,7 @@ You can specify a :class:`~bson.raw_bson.RawBSONDocument` document type:
|
||||
result = await collection.find_one({"x": 1})
|
||||
assert isinstance(result, RawBSONDocument)
|
||||
|
||||
Subclasses of :py:class:`collections.abc.Mapping` can also be used, such as :class:`~bson.son.SON`:
|
||||
Subclasses of :py:class:`collections.abc.Mapping` can also be used, such as :class:`~pymongo.son.SON`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -105,7 +105,7 @@ Subclasses of :py:class:`collections.abc.Mapping` can also be used, such as :cla
|
||||
assert result is not None
|
||||
assert result["x"] == 1
|
||||
|
||||
Note that when using :class:`~bson.son.SON`, the key and value types must be given, e.g. ``SON[str, Any]``.
|
||||
Note that when using :class:`~pymongo.son.SON`, the key and value types must be given, e.g. ``SON[str, Any]``.
|
||||
|
||||
|
||||
Typed Collection
|
||||
@ -260,7 +260,7 @@ match a well-defined schema using :py:class:`~typing.TypedDict`.
|
||||
|
||||
Typed Command
|
||||
-------------
|
||||
When using the :meth:`~motor.motor_asyncio.AsyncIOMotorDatabase.command`, you can specify the document type by providing a custom :class:`~bson.codec_options.CodecOptions`:
|
||||
When using the :meth:`~motor.motor_asyncio.AsyncIOMotorDatabase.command`, you can specify the document type by providing a custom :class:`~pymongo.codec_options.CodecOptions`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -280,7 +280,7 @@ For :py:class:`~typing.TypedDict`, use the form: ``options: CodecOptions[MyTyped
|
||||
|
||||
Typed BSON Decoding
|
||||
-------------------
|
||||
You can specify the document type returned by :mod:`bson` decoding functions by providing :class:`~bson.codec_options.CodecOptions`:
|
||||
You can specify the document type returned by :mod:`bson` decoding functions by providing :class:`~pymongo.codec_options.CodecOptions`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -302,7 +302,7 @@ You can specify the document type returned by :mod:`bson` decoding functions by
|
||||
rt_document = decode(bsonbytes, codec_options=options)
|
||||
assert rt_document.foo() == "bar"
|
||||
|
||||
:class:`~bson.raw_bson.RawBSONDocument` and :py:class:`~typing.TypedDict` are also supported.
|
||||
:class:`~pymongo.raw_bson.RawBSONDocument` and :py:class:`~typing.TypedDict` are also supported.
|
||||
For :py:class:`~typing.TypedDict`, use the form: ``options: CodecOptions[MyTypedDict] = CodecOptions(...)``.
|
||||
|
||||
|
||||
@ -363,7 +363,7 @@ Other times ``mypy`` will catch an actual error, like the following code:
|
||||
|
||||
In this case the solution is to use ``insert_one({})``, passing a document instead of a list.
|
||||
|
||||
Another example is trying to set a value on a :class:`~bson.raw_bson.RawBSONDocument`, which is read-only.:
|
||||
Another example is trying to set a value on a :class:`~pymongo.raw_bson.RawBSONDocument`, which is read-only.:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ project.
|
||||
|
||||
Feature Requests / Feedback
|
||||
---------------------------
|
||||
Use our `feedback engine <https://feedback.mongodb.com/forums/924286-drivers>`_
|
||||
Use our `feedback engine <https://feedback.mongodb.com/?category=7548141816650747033>`_
|
||||
to send us feature requests and general feedback about PyMongo.
|
||||
|
||||
Contributing
|
||||
|
||||
@ -27,7 +27,7 @@ asyncio. It requires:
|
||||
|
||||
* Unix (including macOS) or Windows.
|
||||
* PyMongo_ >=4.9,<5
|
||||
* Python 3.9+
|
||||
* Python 3.10+
|
||||
|
||||
Optional dependencies:
|
||||
|
||||
@ -41,7 +41,7 @@ dependency can be installed automatically along with Motor::
|
||||
|
||||
similarly,
|
||||
|
||||
`MONGODB-AWS <https://pymongo.readthedocs.io/en/stable/examples/authentication.html#mongodb-aws>`_
|
||||
`MONGODB-AWS <https://www.mongodb.com/docs/languages/python/pymongo-driver/current/security/authentication/aws-iam/#std-label-pymongo-mongodb-aws>`_
|
||||
authentication requires ``aws`` extra dependency::
|
||||
|
||||
$ pip install "motor[aws]"
|
||||
|
||||
@ -186,7 +186,7 @@ can be changed to this::
|
||||
``tz_aware`` defaults to ``False``
|
||||
..................................
|
||||
|
||||
``tz_aware``, an argument for :class:`~bson.json_util.JSONOptions`,
|
||||
``tz_aware``, an argument for :class:`~pymongo.json_util.JSONOptions`,
|
||||
now defaults to ``False`` instead of ``True``. ``json_util.loads`` now
|
||||
decodes datetime as naive by default.
|
||||
|
||||
@ -416,8 +416,8 @@ documents in your own code before passing them to PyMongo, and transform
|
||||
incoming documents after receiving them from PyMongo.
|
||||
|
||||
Alternatively, if your application uses the ``SONManipulator`` API to convert
|
||||
custom types to BSON, the :class:`~bson.codec_options.TypeCodec` and
|
||||
:class:`~bson.codec_options.TypeRegistry` APIs may be a suitable alternative.
|
||||
custom types to BSON, the :class:`~pymongo.codec_options.TypeCodec` and
|
||||
:class:`~pymongo.codec_options.TypeRegistry` APIs may be a suitable alternative.
|
||||
For more information, see the `Custom Types documentation`_.
|
||||
|
||||
.. _Custom Types documentation: https://www.mongodb.com/docs/languages/python/pymongo-driver/current/data-formats/custom-types/type-codecs/
|
||||
@ -454,13 +454,12 @@ Removed features with no migration path
|
||||
Encoding a UUID raises an error by default
|
||||
..........................................
|
||||
|
||||
The default uuid_representation for :class:`~bson.codec_options.CodecOptions`,
|
||||
:class:`~bson.json_util.JSONOptions`, and
|
||||
The default uuid_representation for :class:`~pymongo.codec_options.CodecOptions`,
|
||||
:class:`~pymongo.json_util.JSONOptions`, and
|
||||
:class:`~motor.motor_tornado.MotorClient` has been changed from
|
||||
:data:`bson.binary.UuidRepresentation.PYTHON_LEGACY` to
|
||||
:data:`bson.binary.UuidRepresentation.UNSPECIFIED`. Attempting to encode a
|
||||
:class:`uuid.UUID` instance to BSON or JSON now produces an error by default.
|
||||
See :ref:`handling-uuid-data-example` for details.
|
||||
|
||||
|
||||
Upgrade to Motor 3.0
|
||||
|
||||
@ -10,7 +10,7 @@ Requirements
|
||||
|
||||
The current version of Motor requires:
|
||||
|
||||
* CPython 3.9 and later.
|
||||
* CPython 3.10 and later.
|
||||
* PyMongo_ 4.9 and later.
|
||||
|
||||
Motor can integrate with either Tornado or asyncio.
|
||||
@ -125,47 +125,51 @@ Motor 3.5 dropped support for Python 3.7 and added support for Python 3.13.
|
||||
|
||||
Motor 3.7 dropped support for Python 3.8.
|
||||
|
||||
+---------------------------------------------------------------------+
|
||||
| Python Version |
|
||||
+=====================+=====+=====+=====+=====+=====+=====+=====+=====+
|
||||
| | 3.6 | 3.7 | 3.8 | 3.9 | 3.10| 3.11| 3.12| 3.13|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| Motor Version | 1.0 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 1.1 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 1.2 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 1.3 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.0 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.1 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.2 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.3 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.4 | Y | Y | Y | Y |**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.5 | Y | Y | Y | Y | Y |**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.0 |**N**| Y | Y | Y | Y |**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.1 |**N**| Y | Y | Y | Y | Y |**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.2 |**N**| Y | Y | Y | Y | Y |**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.3 |**N**| Y | Y | Y | Y | Y | Y |**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.4 |**N**| Y | Y | Y | Y | Y | Y |**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.5 |**N**|**N**| Y | Y | Y | Y | Y |**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.6 |**N**|**N**| Y | Y | Y | Y | Y | Y |
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.7 |**N**|**N**|**N**| Y | Y | Y | Y | Y |
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
Motor 3.8 dropped support for Python 3.9 and added support for Python 3.14.
|
||||
|
||||
+---------------------------------------------------------------------------+
|
||||
| Python Version |
|
||||
+=====================+=====+=====+=====+=====+=====+=====+=====+=====+=====+
|
||||
| | 3.6 | 3.7 | 3.8 | 3.9 | 3.10| 3.11| 3.12| 3.13| 3.14|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| Motor Version | 1.0 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 1.1 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 1.2 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 1.3 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.0 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.1 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.2 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.3 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.4 | Y | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 2.5 | Y | Y | Y | Y | Y |**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.0 |**N**| Y | Y | Y | Y |**N**|**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.1 |**N**| Y | Y | Y | Y | Y |**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.2 |**N**| Y | Y | Y | Y | Y |**N**|**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.3 |**N**| Y | Y | Y | Y | Y | Y |**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.4 |**N**| Y | Y | Y | Y | Y | Y |**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.5 |**N**|**N**| Y | Y | Y | Y | Y |**N**|**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.6 |**N**|**N**| Y | Y | Y | Y | Y | Y |**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.7 |**N**|**N**|**N**| Y | Y | Y | Y | Y |**N**|
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| | 3.8 |**N**|**N**|**N**|**N**| Y | Y | Y | Y | Y |
|
||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
|
||||
Not Supported
|
||||
-------------
|
||||
|
||||
@ -14,16 +14,16 @@
|
||||
|
||||
"""Version-related data for motor."""
|
||||
import re
|
||||
from typing import List, Tuple, Union
|
||||
from typing import Union
|
||||
|
||||
__version__ = "3.7.2.dev0"
|
||||
|
||||
|
||||
def get_version_tuple(version: str) -> Tuple[Union[int, str], ...]:
|
||||
def get_version_tuple(version: str) -> tuple[Union[int, str], ...]:
|
||||
pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)"
|
||||
match = re.match(pattern, version)
|
||||
if match:
|
||||
parts: List[Union[int, str]] = [int(match[part]) for part in ["major", "minor", "patch"]]
|
||||
parts: list[Union[int, str]] = [int(match[part]) for part in ["major", "minor", "patch"]]
|
||||
if match["rest"]:
|
||||
parts.append(match["rest"])
|
||||
elif re.match(r"\d+.\d+", version):
|
||||
|
||||
@ -171,6 +171,21 @@ class AgnosticClient(AgnosticBaseProperties):
|
||||
delegate = self.__delegate_class__(*args, **kwargs)
|
||||
super().__init__(delegate)
|
||||
|
||||
warnings.warn(
|
||||
DeprecationWarning(
|
||||
"""Motor is deprecated as of May 14th, 2025,
|
||||
in favor of the GA release of the PyMongo Async API.
|
||||
No new features will be added to Motor,
|
||||
and only bug fixes will be provided until it reaches end of life on May 14th, 2026.
|
||||
After that, only critical bug fixes will be made until final support ends on May 14th, 2027.
|
||||
We strongly recommend migrating to the PyMongo Async API while Motor is still supported.
|
||||
For help transitioning, see the Migrate to PyMongo Async guide here:
|
||||
https://www.mongodb.com/docs/languages/python/pymongo-driver/current/reference/migration/
|
||||
"""
|
||||
),
|
||||
stacklevel=2,
|
||||
)
|
||||
|
||||
@property
|
||||
def io_loop(self):
|
||||
if self._io_loop is None:
|
||||
@ -227,7 +242,7 @@ class AgnosticClient(AgnosticBaseProperties):
|
||||
to use for the aggregation.
|
||||
- `start_at_operation_time` (optional): If provided, the resulting
|
||||
change stream will only return changes that occurred at or after
|
||||
the specified :class:`~bson.timestamp.Timestamp`. Requires
|
||||
the specified :class:`~pymongo.timestamp.Timestamp`. Requires
|
||||
MongoDB >= 4.0.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
@ -693,7 +708,7 @@ class AgnosticDatabase(AgnosticBaseProperties):
|
||||
to use for the aggregation.
|
||||
- `start_at_operation_time` (optional): If provided, the resulting
|
||||
change stream will only return changes that occurred at or after
|
||||
the specified :class:`~bson.timestamp.Timestamp`. Requires
|
||||
the specified :class:`~pymongo.timestamp.Timestamp`. Requires
|
||||
MongoDB >= 4.0.
|
||||
- `session` (optional): a
|
||||
:class:`~pymongo.client_session.ClientSession`.
|
||||
@ -771,7 +786,7 @@ class AgnosticDatabase(AgnosticBaseProperties):
|
||||
.. note:: the order of keys in the `command` document is
|
||||
significant (the "verb" must come first), so commands
|
||||
which require multiple keys (e.g. `findandmodify`)
|
||||
should use an instance of :class:`~bson.son.SON` or
|
||||
should use an instance of :class:`~pymongo.son.SON` or
|
||||
a string and kwargs instead of a Python `dict`.
|
||||
|
||||
- `value` (optional): value to use for the command verb when
|
||||
@ -782,7 +797,7 @@ class AgnosticDatabase(AgnosticBaseProperties):
|
||||
read preference configured for the transaction.
|
||||
Otherwise, defaults to
|
||||
:attr:`~pymongo.read_preferences.ReadPreference.PRIMARY`.
|
||||
- `codec_options`: A :class:`~bson.codec_options.CodecOptions`
|
||||
- `codec_options`: A :class:`~pymongo.codec_options.CodecOptions`
|
||||
instance.
|
||||
- `session` (optional): A
|
||||
:class:`MotorClientSession`.
|
||||
|
||||
@ -13,17 +13,12 @@
|
||||
# limitations under the License.
|
||||
|
||||
from asyncio import Future
|
||||
from collections.abc import Callable, Coroutine, Iterable, Mapping, MutableMapping, Sequence
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
Coroutine,
|
||||
Generic,
|
||||
Iterable,
|
||||
Mapping,
|
||||
MutableMapping,
|
||||
NoReturn,
|
||||
Optional,
|
||||
Sequence,
|
||||
TypeVar,
|
||||
Union,
|
||||
overload,
|
||||
|
||||
@ -31,7 +31,7 @@ read preference, and/or write concern from this :class:`MotorClient`.
|
||||
:Parameters:
|
||||
- `name`: The name of the database - a string.
|
||||
- `codec_options` (optional): An instance of
|
||||
:class:`~bson.codec_options.CodecOptions`. If ``None`` (the
|
||||
:class:`~pymongo.codec_options.CodecOptions`. If ``None`` (the
|
||||
default) the :attr:`codec_options` of this :class:`MotorClient` is
|
||||
used.
|
||||
- `read_preference` (optional): The read preference to use. If
|
||||
@ -66,7 +66,7 @@ based only on the URI in a configuration file.
|
||||
- `default` (optional): the database name to use if no database name
|
||||
was provided in the URI.
|
||||
- `codec_options` (optional): An instance of
|
||||
:class:`~bson.codec_options.CodecOptions`. If ``None`` (the
|
||||
:class:`~pymongo.codec_options.CodecOptions`. If ``None`` (the
|
||||
default) the :attr:`codec_options` of this :class:`MotorClient` is
|
||||
used.
|
||||
- `read_preference` (optional): The read preference to use. If
|
||||
@ -187,7 +187,7 @@ This will print something like::
|
||||
:Returns:
|
||||
An instance of :class:`~pymongo.results.BulkWriteResult`.
|
||||
|
||||
.. seealso:: :ref:`writes-and-ids`
|
||||
.. seealso:: `Writes and ids <https://www.mongodb.com/docs/languages/python/pymongo-driver/current/crud/insert/#overview>`_
|
||||
|
||||
.. note:: `bypass_document_validation` requires server version
|
||||
**>= 3.2**
|
||||
@ -344,7 +344,7 @@ kwargs. So ``{count: collection_name, query: query}`` becomes::
|
||||
.. note:: the order of keys in the `command` document is
|
||||
significant (the "verb" must come first), so commands
|
||||
which require multiple keys (e.g. `findandmodify`)
|
||||
should use an instance of :class:`~bson.son.SON` or
|
||||
should use an instance of :class:`~pymongo.son.SON` or
|
||||
a string and kwargs instead of a Python :class:`dict`.
|
||||
|
||||
- `value` (optional): value to use for the command verb when
|
||||
@ -829,7 +829,7 @@ This prints something like::
|
||||
:Returns:
|
||||
An instance of :class:`~pymongo.results.InsertManyResult`.
|
||||
|
||||
.. seealso:: :ref:`writes-and-ids`
|
||||
.. seealso:: `Writes and ids <https://www.mongodb.com/docs/languages/python/pymongo-driver/current/crud/insert/#overview>`_
|
||||
|
||||
.. note:: `bypass_document_validation` requires server version
|
||||
**>= 3.2**
|
||||
@ -866,7 +866,7 @@ This code outputs the new document's ``_id``::
|
||||
:Returns:
|
||||
- An instance of :class:`~pymongo.results.InsertOneResult`.
|
||||
|
||||
.. seealso:: :ref:`writes-and-ids`
|
||||
.. seealso:: `Writes and ids <https://www.mongodb.com/docs/languages/python/pymongo-driver/current/crud/insert/#overview>`_
|
||||
|
||||
.. note:: `bypass_document_validation` requires server version
|
||||
**>= 3.2**
|
||||
@ -890,7 +890,7 @@ response from the server to the `map reduce command`_.
|
||||
- `reduce`: reduce function (as a JavaScript string)
|
||||
- `out`: output collection name or `out object` (dict). See
|
||||
the `map reduce command`_ documentation for available options.
|
||||
Note: `out` options are order sensitive. :class:`~bson.son.SON`
|
||||
Note: `out` options are order sensitive. :class:`~pymongo.son.SON`
|
||||
can be used to specify multiple options.
|
||||
e.g. SON([('replace', <collection name>), ('db', <database name>)])
|
||||
- `full_response` (optional): if ``True``, return full response to
|
||||
@ -1277,7 +1277,7 @@ started it.
|
||||
where_doc = """Adds a `$where`_ clause to this query.
|
||||
|
||||
The `code` argument must be an instance of :class:`str`
|
||||
:class:`~bson.code.Code` containing a JavaScript expression.
|
||||
:class:`~pymongo.code.Code` containing a JavaScript expression.
|
||||
This expression will be evaluated for each document scanned.
|
||||
Only those documents for which the expression evaluates to *true*
|
||||
will be returned as results. The keyword *this* refers to the object
|
||||
@ -1293,7 +1293,7 @@ if this :class:`~motor.motor_tornado.MotorCursor` has already been used.
|
||||
Only the last call to :meth:`where` applied to a
|
||||
:class:`~motor.motor_tornado.MotorCursor` has any effect.
|
||||
|
||||
.. note:: MongoDB 4.4 drops support for :class:`~bson.code.Code`
|
||||
.. note:: MongoDB 4.4 drops support for :class:`~pymongo.code.Code`
|
||||
with scope variables. Consider using `$expr`_ instead.
|
||||
|
||||
:Parameters:
|
||||
@ -1337,7 +1337,7 @@ gridfs_delete_doc = """Delete a file's metadata and data chunks from a GridFS bu
|
||||
b"data I want to store!")
|
||||
await fs.delete(file_id)
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no file with file_id exists.
|
||||
|
||||
:Parameters:
|
||||
- `file_id`: The _id of the file to be deleted.
|
||||
@ -1361,7 +1361,7 @@ gridfs_download_to_stream_doc = """Downloads the contents of the stored file spe
|
||||
file.seek(0)
|
||||
contents = file.read()
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no file with file_id exists.
|
||||
|
||||
:Parameters:
|
||||
- `file_id`: The _id of the file to be downloaded.
|
||||
@ -1383,7 +1383,7 @@ gridfs_download_to_stream_by_name_doc = """ Write the contents of `filename
|
||||
file = open('myfile','wb')
|
||||
await fs.download_to_stream_by_name("test_file", file)
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
|
||||
Raises :exc:`~ValueError` if `filename` is not a string.
|
||||
@ -1419,7 +1419,7 @@ gridfs_open_download_stream_doc = """Opens a stream to read the contents of the
|
||||
grid_out = await fs.open_download_stream(file_id)
|
||||
contents = await grid_out.read()
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no file with file_id exists.
|
||||
|
||||
:Parameters:
|
||||
- `file_id`: The _id of the file to be downloaded.
|
||||
@ -1441,7 +1441,7 @@ gridfs_open_download_stream_by_name_doc = """Opens a stream to read the contents
|
||||
grid_out = await fs.open_download_stream_by_name(file_id)
|
||||
contents = await grid_out.read()
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
|
||||
Raises :exc:`~ValueError` filename is not a string.
|
||||
@ -1484,7 +1484,7 @@ gridfs_open_upload_stream_doc = """Opens a stream for writing.
|
||||
|
||||
Returns an instance of :class:`AsyncIOMotorGridIn`.
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
Raises :exc:`~ValueError` if `filename` is not a string.
|
||||
|
||||
@ -1528,7 +1528,7 @@ gridfs_open_upload_stream_with_id_doc = """Opens a stream for writing.
|
||||
|
||||
Returns an instance of :class:`AsyncIOMotorGridIn`.
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
Raises :exc:`~ValueError` if `filename` is not a string.
|
||||
|
||||
@ -1560,7 +1560,7 @@ gridfs_rename_doc = """Renames the stored file with the specified file_id.
|
||||
|
||||
await fs.rename(file_id, "new_test_name")
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no file with file_id exists.
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no file with file_id exists.
|
||||
|
||||
:Parameters:
|
||||
- `file_id`: The _id of the file to be renamed.
|
||||
@ -1581,7 +1581,7 @@ gridfs_upload_from_stream_doc = """Uploads a user file to a GridFS bucket.
|
||||
b"data I want to store!",
|
||||
metadata={"contentType": "text/plain"})
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
Raises :exc:`~ValueError` if `filename` is not a string.
|
||||
|
||||
@ -1616,7 +1616,7 @@ gridfs_upload_from_stream_with_id_doc = """Uploads a user file to a GridFS bucke
|
||||
b"data I want to store!",
|
||||
metadata={"contentType": "text/plain"})
|
||||
|
||||
Raises :exc:`~gridfs.errors.NoFile` if no such version of
|
||||
Raises :exc:`~pymongo.errors.NoFile` if no such version of
|
||||
that file exists.
|
||||
Raises :exc:`~ValueError` if `filename` is not a string.
|
||||
|
||||
|
||||
@ -15,9 +15,10 @@
|
||||
"""Dynamic class-creation for Motor."""
|
||||
import functools
|
||||
import inspect
|
||||
from typing import Any, Callable, Dict, TypeVar
|
||||
from collections.abc import Callable
|
||||
from typing import Any, TypeVar
|
||||
|
||||
_class_cache: Dict[Any, Any] = {}
|
||||
_class_cache: dict[Any, Any] = {}
|
||||
|
||||
# mypy: ignore-errors
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
from typing import Any, Mapping, MutableMapping, Optional, Union
|
||||
from collections.abc import Mapping, MutableMapping
|
||||
from typing import Any, Optional, Union
|
||||
|
||||
from bson import Code, CodecOptions, Timestamp
|
||||
from bson.raw_bson import RawBSONDocument
|
||||
|
||||
@ -73,7 +73,7 @@ class AgnosticGridOut:
|
||||
"""Class to read data out of GridFS.
|
||||
|
||||
MotorGridOut supports the same attributes as PyMongo's
|
||||
:class:`~gridfs.grid_file.GridOut`, such as ``_id``, ``content_type``,
|
||||
:class:`~pymongo.grid_file.GridOut`, such as ``_id``, ``content_type``,
|
||||
etc.
|
||||
|
||||
You don't need to instantiate this class directly - use the
|
||||
@ -255,7 +255,7 @@ Metadata set on the file appears as attributes on a
|
||||
arguments include:
|
||||
|
||||
- ``"_id"``: unique ID for this file (default:
|
||||
:class:`~bson.objectid.ObjectId`) - this ``"_id"`` must
|
||||
:class:`~pymongo.objectid.ObjectId`) - this ``"_id"`` must
|
||||
not have already been used for another file
|
||||
|
||||
- ``"filename"``: human name for the file
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
|
||||
import datetime
|
||||
import os
|
||||
from typing import Any, Iterable, Mapping, NoReturn, Optional
|
||||
from collections.abc import Iterable, Mapping
|
||||
from typing import Any, NoReturn, Optional
|
||||
|
||||
from bson import ObjectId
|
||||
from gridfs import DEFAULT_CHUNK_SIZE, GridFSBucket, GridIn, GridOut, GridOutCursor # noqa: F401
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
from typing import Any, Mapping, MutableMapping, Optional, Union
|
||||
from collections.abc import Mapping, MutableMapping
|
||||
from typing import Any, Optional, Union
|
||||
|
||||
from bson import Code, CodecOptions, Timestamp
|
||||
from bson.raw_bson import RawBSONDocument
|
||||
|
||||
@ -8,7 +8,7 @@ dynamic = ["version", "dependencies", "optional-dependencies"]
|
||||
description = "Non-blocking MongoDB driver for Tornado or asyncio"
|
||||
readme = "README.md"
|
||||
license = { file = "LICENSE" }
|
||||
requires-python = ">=3.9"
|
||||
requires-python = ">=3.10"
|
||||
authors = [
|
||||
{ name = "A. Jesse Jiryu Davis", email = "jesse@mongodb.com" },
|
||||
]
|
||||
@ -33,13 +33,13 @@ classifiers = [
|
||||
"Typing :: Typed",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: 3.14",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
@ -66,7 +66,7 @@ test = ["requirements/test.txt"]
|
||||
zstd = ["requirements/zstd.txt"]
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.9"
|
||||
python_version = "3.10"
|
||||
strict = true
|
||||
pretty = true
|
||||
show_error_context = true
|
||||
@ -103,10 +103,11 @@ filterwarnings = [
|
||||
# TODO: Remove both of these in https://jira.mongodb.org/browse/PYTHON-4731
|
||||
"ignore:Unclosed AsyncMongoClient*",
|
||||
"ignore:Unclosed MongoClient*",
|
||||
# Deprecation warning now that Motor is officially deprecated
|
||||
"ignore:Motor is deprecated*",
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py38"
|
||||
line-length = 100
|
||||
|
||||
[tool.ruff.lint]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
tornado
|
||||
aiohttp
|
||||
sphinx>=5.3,<8
|
||||
sphinx_rtd_theme>=2,<3
|
||||
sphinx>=5.3,<9
|
||||
sphinx_rtd_theme>=2,<4
|
||||
readthedocs-sphinx-search~=0.3
|
||||
furo==2024.8.6
|
||||
furo==2025.12.19
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
pytest>=7
|
||||
pytest>=9.0.3
|
||||
mockupdb
|
||||
tornado>=5
|
||||
aiohttp>=3.8.7
|
||||
motor[encryption]
|
||||
cffi>=1.17.0rc1;python_version=="3.13"
|
||||
cffi>=1.17.0rc1;python_version>="3.13"
|
||||
pytest_asyncio
|
||||
|
||||
@ -299,7 +299,7 @@ class SynchroMeta(type):
|
||||
|
||||
# Set DelegateProperties' and SynchroProperties' names.
|
||||
for name, attr in attrs.items():
|
||||
if isinstance(attr, (MotorAttributeFactory, SynchroAttr)): # noqa: SIM102
|
||||
if isinstance(attr, (MotorAttributeFactory, SynchroAttr)): # noqa: SIM102,UP038
|
||||
if attr.name is None:
|
||||
attr.name = name
|
||||
|
||||
|
||||
@ -18,10 +18,22 @@ import asyncio
|
||||
import datetime
|
||||
import email
|
||||
import logging
|
||||
import sys
|
||||
import test
|
||||
import time
|
||||
from test.asyncio_tests import AsyncIOTestCase, asyncio_test
|
||||
|
||||
import pytest
|
||||
|
||||
# MOTOR-1477 - after libzstd is supported on build hosts
|
||||
# we can remove this guard.
|
||||
if sys.version_info >= (3, 14):
|
||||
try:
|
||||
import compression.zstd # noqa: F401
|
||||
except ModuleNotFoundError:
|
||||
pytest.skip(allow_module_level=True)
|
||||
|
||||
|
||||
import aiohttp
|
||||
import aiohttp.web
|
||||
import gridfs
|
||||
|
||||
@ -334,7 +334,7 @@ class TestAsyncIOCollection(AsyncIOTestCase):
|
||||
await self.collection.explicit_encryption.find(find_payload).to_list(3),
|
||||
key=lambda x: x["_id"],
|
||||
)
|
||||
for elem, expected in zip(sorted_find, [6.0, 30.0, 200.0]):
|
||||
for elem, expected in zip(sorted_find, [6.0, 30.0, 200.0], strict=False):
|
||||
self.assertEqual(elem[f"encrypted{name}"], expected)
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from typing import Any, Dict
|
||||
from typing import Any
|
||||
|
||||
from motor.motor_asyncio import (
|
||||
AsyncIOMotorChangeStream,
|
||||
@ -9,9 +9,9 @@ from motor.motor_asyncio import (
|
||||
AsyncIOMotorDatabase,
|
||||
)
|
||||
|
||||
client: AsyncIOMotorClient[Dict[str, Any]]
|
||||
db: AsyncIOMotorDatabase[Dict[str, Any]]
|
||||
cur: AsyncIOMotorCursor[Dict[str, Any]]
|
||||
coll: AsyncIOMotorCollection[Dict[str, Any]]
|
||||
cs: AsyncIOMotorChangeStream[Dict[str, Any]]
|
||||
enc: AsyncIOMotorClientEncryption[Dict[str, Any]]
|
||||
client: AsyncIOMotorClient[dict[str, Any]]
|
||||
db: AsyncIOMotorDatabase[dict[str, Any]]
|
||||
cur: AsyncIOMotorCursor[dict[str, Any]]
|
||||
coll: AsyncIOMotorCollection[dict[str, Any]]
|
||||
cs: AsyncIOMotorChangeStream[dict[str, Any]]
|
||||
enc: AsyncIOMotorClientEncryption[dict[str, Any]]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from typing import Iterable
|
||||
from collections.abc import Iterable
|
||||
|
||||
try:
|
||||
from mypy import api
|
||||
|
||||
@ -17,8 +17,9 @@ sample client code that uses Motor typings.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from collections.abc import Callable, Mapping
|
||||
from test.asyncio_tests import AsyncIOTestCase, asyncio_test
|
||||
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Mapping, TypeVar, Union, cast
|
||||
from typing import TYPE_CHECKING, Any, TypeVar, Union, cast
|
||||
|
||||
from bson import CodecOptions
|
||||
from bson.raw_bson import RawBSONDocument
|
||||
@ -116,11 +117,11 @@ class TestMotor(AsyncIOTestCase):
|
||||
async def test_bulk_write(self) -> None:
|
||||
await self.collection.insert_one({})
|
||||
coll = self.collection
|
||||
requests: List[InsertOne[Movie]] = [InsertOne(Movie(name="American Graffiti", year=1973))]
|
||||
requests: list[InsertOne[Movie]] = [InsertOne(Movie(name="American Graffiti", year=1973))]
|
||||
result_one = await coll.bulk_write(requests)
|
||||
self.assertTrue(result_one.acknowledged)
|
||||
new_requests: List[Union[InsertOne[Movie], ReplaceOne[Movie]]] = []
|
||||
input_list: List[Union[InsertOne[Movie], ReplaceOne[Movie]]] = [
|
||||
new_requests: list[Union[InsertOne[Movie], ReplaceOne[Movie]]] = []
|
||||
input_list: list[Union[InsertOne[Movie], ReplaceOne[Movie]]] = [
|
||||
InsertOne(Movie(name="American Graffiti", year=1973)),
|
||||
ReplaceOne({}, Movie(name="American Graffiti", year=1973)),
|
||||
]
|
||||
@ -134,14 +135,14 @@ class TestMotor(AsyncIOTestCase):
|
||||
@asyncio_test # type:ignore[misc]
|
||||
async def test_bulk_write_heterogeneous(self) -> None:
|
||||
coll = self.collection
|
||||
requests: List[Union[InsertOne[Movie], ReplaceOne, DeleteOne]] = [
|
||||
requests: list[Union[InsertOne[Movie], ReplaceOne, DeleteOne]] = [
|
||||
InsertOne(Movie(name="American Graffiti", year=1973)),
|
||||
ReplaceOne({}, {"name": "American Graffiti", "year": "WRONG_TYPE"}),
|
||||
DeleteOne({}),
|
||||
]
|
||||
result_one = await coll.bulk_write(requests)
|
||||
self.assertTrue(result_one.acknowledged)
|
||||
requests_two: List[Union[InsertOne[Movie], ReplaceOne[Movie], DeleteOne]] = [
|
||||
requests_two: list[Union[InsertOne[Movie], ReplaceOne[Movie], DeleteOne]] = [
|
||||
InsertOne(Movie(name="American Graffiti", year=1973)),
|
||||
ReplaceOne(
|
||||
{},
|
||||
@ -154,7 +155,7 @@ class TestMotor(AsyncIOTestCase):
|
||||
|
||||
@asyncio_test # type:ignore[misc]
|
||||
async def test_command(self) -> None:
|
||||
result: Dict = await self.cx.admin.command("ping")
|
||||
result: dict = await self.cx.admin.command("ping")
|
||||
result.items()
|
||||
|
||||
@asyncio_test # type:ignore[misc]
|
||||
@ -192,7 +193,7 @@ class TestMotor(AsyncIOTestCase):
|
||||
]
|
||||
)
|
||||
|
||||
class mydict(Dict[str, Any]):
|
||||
class mydict(dict[str, Any]):
|
||||
pass
|
||||
|
||||
result = coll3.aggregate(
|
||||
@ -226,7 +227,7 @@ class TestDocumentType(AsyncIOTestCase):
|
||||
|
||||
@only_type_check
|
||||
async def test_explicit_document_type(self) -> None:
|
||||
client: AsyncIOMotorClient[Dict[str, Any]] = AsyncIOMotorClient()
|
||||
client: AsyncIOMotorClient[dict[str, Any]] = AsyncIOMotorClient()
|
||||
coll = client.test.test
|
||||
retrieved = await coll.find_one({"_id": "foo"})
|
||||
assert retrieved is not None
|
||||
@ -320,7 +321,7 @@ class TestDocumentType(AsyncIOTestCase):
|
||||
|
||||
@only_type_check
|
||||
async def test_create_index(self) -> None:
|
||||
client: AsyncIOMotorClient[Dict[str, str]] = AsyncIOMotorClient("test")
|
||||
client: AsyncIOMotorClient[dict[str, str]] = AsyncIOMotorClient("test")
|
||||
db = client.test
|
||||
async with await client.start_session() as session:
|
||||
index = await db.test.create_index(
|
||||
@ -361,13 +362,13 @@ class TestCommandDocumentType(AsyncIOTestCase):
|
||||
@only_type_check
|
||||
async def test_default(self) -> None:
|
||||
client: AsyncIOMotorClient = AsyncIOMotorClient()
|
||||
result: Dict = await client.admin.command("ping")
|
||||
result: dict = await client.admin.command("ping")
|
||||
result["a"] = 1
|
||||
|
||||
@only_type_check
|
||||
async def test_explicit_document_type(self) -> None:
|
||||
client: AsyncIOMotorClient = AsyncIOMotorClient()
|
||||
codec_options: CodecOptions[Dict[str, Any]] = CodecOptions()
|
||||
codec_options: CodecOptions[dict[str, Any]] = CodecOptions()
|
||||
result = await client.admin.command("ping", codec_options=codec_options)
|
||||
result["a"] = 1
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ from test.utils import AUTO_ISMASTER, get_primary_pool, one
|
||||
import pymongo
|
||||
import pymongo.mongo_client
|
||||
from bson import CodecOptions
|
||||
from mockupdb import OpQuery
|
||||
from mockupdb import OpMsg, OpQuery
|
||||
from pymongo import CursorType, ReadPreference, WriteConcern
|
||||
from pymongo.common import MIN_SUPPORTED_WIRE_VERSION
|
||||
from pymongo.driver_info import DriverInfo
|
||||
@ -234,7 +234,8 @@ class MotorClientExhaustCursorTest(MotorMockServerTest):
|
||||
|
||||
# With Tornado, simply accessing fetch_next starts the fetch.
|
||||
fetch_next = cursor.fetch_next
|
||||
request = await self.run_thread(server.receives, OpQuery)
|
||||
expected = OpQuery if pymongo.version_tuple[0:2] < (4, 14) else OpMsg({})
|
||||
request = await self.run_thread(server.receives, expected)
|
||||
request.fail(code=1)
|
||||
|
||||
with self.assertRaises(pymongo.errors.OperationFailure):
|
||||
@ -245,10 +246,12 @@ class MotorClientExhaustCursorTest(MotorMockServerTest):
|
||||
|
||||
@gen_test
|
||||
async def test_exhaust_query_server_error_standalone(self):
|
||||
raise self.skipTest("MOTOR-1472")
|
||||
await self._test_exhaust_query_server_error(rs=False)
|
||||
|
||||
@gen_test
|
||||
async def test_exhaust_query_server_error_rs(self):
|
||||
raise self.skipTest("MOTOR-1472")
|
||||
await self._test_exhaust_query_server_error(rs=True)
|
||||
|
||||
async def _test_exhaust_query_network_error(self, rs):
|
||||
@ -267,7 +270,8 @@ class MotorClientExhaustCursorTest(MotorMockServerTest):
|
||||
|
||||
# With Tornado, simply accessing fetch_next starts the fetch.
|
||||
fetch_next = cursor.fetch_next
|
||||
request = await self.run_thread(server.receives, OpQuery)
|
||||
expected = OpQuery if pymongo.version_tuple[0:2] < (4, 14) else OpMsg({})
|
||||
request = await self.run_thread(server.receives, expected)
|
||||
request.hangs_up()
|
||||
|
||||
with self.assertRaises(pymongo.errors.ConnectionFailure):
|
||||
|
||||
@ -336,7 +336,7 @@ class MotorCollectionTest(MotorTest):
|
||||
await self.collection.explicit_encryption.find(find_payload).to_list(3),
|
||||
key=lambda x: x["_id"],
|
||||
)
|
||||
for elem, expected in zip(sorted_find, [6.0, 30.0, 200.0]):
|
||||
for elem, expected in zip(sorted_find, [6.0, 30.0, 200.0], strict=False):
|
||||
self.assertEqual(elem[f"encrypted{name}"], expected)
|
||||
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ pymongo_gridfs_only = set(["delete_by_name", "rename_by_name"])
|
||||
|
||||
motor_client_only = motor_only.union(["open"])
|
||||
|
||||
pymongo_client_only = set(["eq_props"]).union(pymongo_only)
|
||||
pymongo_client_only = set(["eq_props", "append_metadata"]).union(pymongo_only)
|
||||
|
||||
pymongo_database_only = set([]).union(pymongo_only)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user