MOTOR-1473 Add support for Python 3.14 and drop 3.9 support (#344)
This commit is contained in:
parent
bbada7dace
commit
5fc7c41fb5
@ -609,14 +609,10 @@ axes:
|
|||||||
- id: tox-env
|
- id: tox-env
|
||||||
display_name: "Tox Env RHEL8"
|
display_name: "Tox Env RHEL8"
|
||||||
values:
|
values:
|
||||||
- id: "test-pypy39"
|
- id: "test-pypy310"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test"
|
TOX_ENV: "test"
|
||||||
PYTHON_BINARY: "/opt/python/pypy3.9/bin/python3"
|
PYTHON_BINARY: "/opt/python/pypy3.10/bin/python3"
|
||||||
- id: "test-py39"
|
|
||||||
variables:
|
|
||||||
TOX_ENV: "test"
|
|
||||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
|
||||||
- id: "test-py310"
|
- id: "test-py310"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test"
|
TOX_ENV: "test"
|
||||||
@ -633,30 +629,34 @@ axes:
|
|||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test"
|
TOX_ENV: "test"
|
||||||
PYTHON_BINARY: "/opt/python/3.13/bin/python3"
|
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"
|
- id: "test-pymongo-4.9"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test-pymongo-4.9"
|
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"
|
- id: "test-pymongo-4.10"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test-pymongo-4.10"
|
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"
|
- id: "test-pymongo-4.11"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test-pymongo-4.11"
|
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"
|
- id: "test-pymongo-latest"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test-pymongo-latest"
|
TOX_ENV: "test-pymongo-latest"
|
||||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||||
- id: "synchro-py39"
|
- id: "synchro-py310"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "synchro"
|
TOX_ENV: "synchro"
|
||||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||||
- id: "synchro-py312"
|
- id: "synchro-py313"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "synchro"
|
TOX_ENV: "synchro"
|
||||||
PYTHON_BINARY: "/opt/python/3.12/bin/python3"
|
PYTHON_BINARY: "/opt/python/3.13/bin/python3"
|
||||||
|
|
||||||
- id: tox-env-rhel7
|
- id: tox-env-rhel7
|
||||||
display_name: "Tox Env RHEL7"
|
display_name: "Tox Env RHEL7"
|
||||||
@ -664,24 +664,20 @@ axes:
|
|||||||
- id: "test"
|
- id: "test"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test"
|
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
|
- id: tox-env-osx
|
||||||
display_name: "Tox Env OSX"
|
display_name: "Tox Env OSX"
|
||||||
values:
|
values:
|
||||||
- id: "test"
|
- id: "test"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test"
|
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
|
- id: tox-env-win
|
||||||
display_name: "Tox Env Windows"
|
display_name: "Tox Env Windows"
|
||||||
values:
|
values:
|
||||||
- id: "test-py39"
|
|
||||||
variables:
|
|
||||||
TOX_ENV: "test"
|
|
||||||
PYTHON_BINARY: "c:/python/Python39/python.exe"
|
|
||||||
- id: "test-py310"
|
- id: "test-py310"
|
||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test"
|
TOX_ENV: "test"
|
||||||
@ -694,6 +690,14 @@ axes:
|
|||||||
variables:
|
variables:
|
||||||
TOX_ENV: "test"
|
TOX_ENV: "test"
|
||||||
PYTHON_BINARY: "c:/python/Python312/python.exe"
|
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
|
- id: os
|
||||||
display_name: "Operating System"
|
display_name: "Operating System"
|
||||||
@ -724,7 +728,7 @@ buildvariants:
|
|||||||
# TODO: synchro needs PyMongo's updated SSL test certs,
|
# TODO: synchro needs PyMongo's updated SSL test certs,
|
||||||
# which may require Motor test suite changes.
|
# which may require Motor test suite changes.
|
||||||
- os: "*"
|
- os: "*"
|
||||||
tox-env: ["synchro-py39", "synchro-py312"]
|
tox-env: ["synchro-py310", "synchro-py313"]
|
||||||
ssl: "ssl"
|
ssl: "ssl"
|
||||||
tasks:
|
tasks:
|
||||||
- ".rapid"
|
- ".rapid"
|
||||||
@ -784,7 +788,7 @@ buildvariants:
|
|||||||
|
|
||||||
- matrix_name: "enterprise-auth"
|
- matrix_name: "enterprise-auth"
|
||||||
display_name: "Enterprise Auth-${tox-env}"
|
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:
|
run_on:
|
||||||
- "rhel84-small"
|
- "rhel84-small"
|
||||||
tasks:
|
tasks:
|
||||||
@ -796,7 +800,7 @@ buildvariants:
|
|||||||
- "rhel84-small"
|
- "rhel84-small"
|
||||||
expansions:
|
expansions:
|
||||||
TOX_ENV: "docs"
|
TOX_ENV: "docs"
|
||||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||||
tasks:
|
tasks:
|
||||||
- name: "docs"
|
- name: "docs"
|
||||||
|
|
||||||
@ -806,6 +810,6 @@ buildvariants:
|
|||||||
- "rhel84-small"
|
- "rhel84-small"
|
||||||
expansions:
|
expansions:
|
||||||
TOX_ENV: "doctest"
|
TOX_ENV: "doctest"
|
||||||
PYTHON_BINARY: "/opt/python/3.9/bin/python3"
|
PYTHON_BINARY: "/opt/python/3.10/bin/python3"
|
||||||
tasks:
|
tasks:
|
||||||
- name: "doctest"
|
- name: "doctest"
|
||||||
|
|||||||
8
.github/workflows/test-python.yml
vendored
8
.github/workflows/test-python.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
python-version: ["3.9", "3.12", "3.13"]
|
python-version: ["3.10", "3.12", "3.14"]
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
name: CPython ${{ matrix.python-version }}-${{ matrix.os }}
|
name: CPython ${{ matrix.python-version }}-${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
@ -54,7 +54,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: '3.10'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
cache-dependency-path: 'pyproject.toml'
|
cache-dependency-path: 'pyproject.toml'
|
||||||
- name: Install Python dependencies
|
- name: Install Python dependencies
|
||||||
@ -72,7 +72,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: '3.10'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
cache-dependency-path: 'pyproject.toml'
|
cache-dependency-path: 'pyproject.toml'
|
||||||
- name: Install Python dependencies
|
- name: Install Python dependencies
|
||||||
@ -97,7 +97,7 @@ jobs:
|
|||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: actions/setup-python@v5
|
- uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: '3.10'
|
||||||
cache: 'pip'
|
cache: 'pip'
|
||||||
cache-dependency-path: 'pyproject.toml'
|
cache-dependency-path: 'pyproject.toml'
|
||||||
- name: Install Python dependencies
|
- name: Install Python dependencies
|
||||||
|
|||||||
@ -35,7 +35,7 @@ Python version on your path, and run:
|
|||||||
tox -m test
|
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:
|
port 27017:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@ -116,7 +116,7 @@ by asyncio. It requires:
|
|||||||
|
|
||||||
- Unix (including macOS) or Windows.
|
- Unix (including macOS) or Windows.
|
||||||
- [PyMongo](http://pypi.python.org/pypi/pymongo/) >=4.9,<5
|
- [PyMongo](http://pypi.python.org/pypi/pymongo/) >=4.9,<5
|
||||||
- Python 3.9+
|
- Python 3.10+
|
||||||
|
|
||||||
Optional dependencies:
|
Optional dependencies:
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ ReadTheDocs](https://motor.readthedocs.io/en/stable/examples/index.html).
|
|||||||
Motor's documentation is on
|
Motor's documentation is on
|
||||||
[ReadTheDocs](https://motor.readthedocs.io/en/stable/).
|
[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/),
|
[sphinx](http://sphinx.pocoo.org/), [Tornado](http://tornadoweb.org/),
|
||||||
and [aiohttp](https://github.com/aio-libs/aiohttp), and do
|
and [aiohttp](https://github.com/aio-libs/aiohttp), and do
|
||||||
`cd doc; make html`.
|
`cd doc; make html`.
|
||||||
|
|||||||
@ -3,6 +3,18 @@ Changelog
|
|||||||
|
|
||||||
.. currentmodule:: motor.motor_tornado
|
.. 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
|
Motor 3.7.1
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ asyncio. It requires:
|
|||||||
|
|
||||||
* Unix (including macOS) or Windows.
|
* Unix (including macOS) or Windows.
|
||||||
* PyMongo_ >=4.9,<5
|
* PyMongo_ >=4.9,<5
|
||||||
* Python 3.9+
|
* Python 3.10+
|
||||||
|
|
||||||
Optional dependencies:
|
Optional dependencies:
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ Requirements
|
|||||||
|
|
||||||
The current version of Motor requires:
|
The current version of Motor requires:
|
||||||
|
|
||||||
* CPython 3.9 and later.
|
* CPython 3.10 and later.
|
||||||
* PyMongo_ 4.9 and later.
|
* PyMongo_ 4.9 and later.
|
||||||
|
|
||||||
Motor can integrate with either Tornado or asyncio.
|
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.
|
Motor 3.7 dropped support for Python 3.8.
|
||||||
|
|
||||||
+---------------------------------------------------------------------+
|
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|
|
| Python Version |
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+=====================+=====+=====+=====+=====+=====+=====+=====+=====+=====+
|
||||||
| Motor Version | 1.0 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
| | 3.6 | 3.7 | 3.8 | 3.9 | 3.10| 3.11| 3.12| 3.13| 3.14|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 1.1 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
| Motor Version | 1.0 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 1.2 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
| | 1.1 | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 1.3 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
| | 1.2 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 2.0 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
| | 1.3 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 2.1 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
| | 2.0 | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 2.2 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
| | 2.1 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 2.3 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
| | 2.2 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 2.4 | Y | Y | Y | Y |**N**|**N**|**N**|**N**|
|
| | 2.3 | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 2.5 | Y | Y | Y | Y | Y |**N**|**N**|**N**|
|
| | 2.4 | Y | Y | Y | Y |**N**|**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.0 |**N**| Y | Y | Y | Y |**N**|**N**|**N**|
|
| | 2.5 | Y | Y | Y | Y | Y |**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.1 |**N**| Y | Y | Y | Y | Y |**N**|**N**|
|
| | 3.0 |**N**| Y | Y | Y | Y |**N**|**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.2 |**N**| Y | Y | Y | Y | Y |**N**|**N**|
|
| | 3.1 |**N**| Y | Y | Y | Y | Y |**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.3 |**N**| Y | Y | Y | Y | Y | Y |**N**|
|
| | 3.2 |**N**| Y | Y | Y | Y | Y |**N**|**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.4 |**N**| Y | Y | Y | Y | Y | Y |**N**|
|
| | 3.3 |**N**| Y | Y | Y | Y | Y | Y |**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.5 |**N**|**N**| Y | Y | Y | Y | Y |**N**|
|
| | 3.4 |**N**| Y | Y | Y | Y | Y | Y |**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.6 |**N**|**N**| Y | Y | Y | Y | Y | Y |
|
| | 3.5 |**N**|**N**| Y | Y | Y | Y | Y |**N**|**N**|
|
||||||
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
| | 3.7 |**N**|**N**|**N**| Y | Y | Y | Y | Y |
|
| | 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
|
Not Supported
|
||||||
-------------
|
-------------
|
||||||
|
|||||||
@ -14,16 +14,16 @@
|
|||||||
|
|
||||||
"""Version-related data for motor."""
|
"""Version-related data for motor."""
|
||||||
import re
|
import re
|
||||||
from typing import List, Tuple, Union
|
from typing import Union
|
||||||
|
|
||||||
__version__ = "3.7.2.dev0"
|
__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>.*)"
|
pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)"
|
||||||
match = re.match(pattern, version)
|
match = re.match(pattern, version)
|
||||||
if match:
|
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"]:
|
if match["rest"]:
|
||||||
parts.append(match["rest"])
|
parts.append(match["rest"])
|
||||||
elif re.match(r"\d+.\d+", version):
|
elif re.match(r"\d+.\d+", version):
|
||||||
|
|||||||
@ -13,17 +13,12 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from asyncio import Future
|
from asyncio import Future
|
||||||
|
from collections.abc import Callable, Coroutine, Iterable, Mapping, MutableMapping, Sequence
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
Callable,
|
|
||||||
Coroutine,
|
|
||||||
Generic,
|
Generic,
|
||||||
Iterable,
|
|
||||||
Mapping,
|
|
||||||
MutableMapping,
|
|
||||||
NoReturn,
|
NoReturn,
|
||||||
Optional,
|
Optional,
|
||||||
Sequence,
|
|
||||||
TypeVar,
|
TypeVar,
|
||||||
Union,
|
Union,
|
||||||
overload,
|
overload,
|
||||||
|
|||||||
@ -15,9 +15,10 @@
|
|||||||
"""Dynamic class-creation for Motor."""
|
"""Dynamic class-creation for Motor."""
|
||||||
import functools
|
import functools
|
||||||
import inspect
|
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
|
# 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 import Code, CodecOptions, Timestamp
|
||||||
from bson.raw_bson import RawBSONDocument
|
from bson.raw_bson import RawBSONDocument
|
||||||
|
|||||||
@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
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 bson import ObjectId
|
||||||
from gridfs import DEFAULT_CHUNK_SIZE, GridFSBucket, GridIn, GridOut, GridOutCursor # noqa: F401
|
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 import Code, CodecOptions, Timestamp
|
||||||
from bson.raw_bson import RawBSONDocument
|
from bson.raw_bson import RawBSONDocument
|
||||||
|
|||||||
@ -8,7 +8,7 @@ dynamic = ["version", "dependencies", "optional-dependencies"]
|
|||||||
description = "Non-blocking MongoDB driver for Tornado or asyncio"
|
description = "Non-blocking MongoDB driver for Tornado or asyncio"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = { file = "LICENSE" }
|
license = { file = "LICENSE" }
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.10"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "A. Jesse Jiryu Davis", email = "jesse@mongodb.com" },
|
{ name = "A. Jesse Jiryu Davis", email = "jesse@mongodb.com" },
|
||||||
]
|
]
|
||||||
@ -33,13 +33,13 @@ classifiers = [
|
|||||||
"Typing :: Typed",
|
"Typing :: Typed",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3.9",
|
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
"Programming Language :: Python :: Implementation :: PyPy",
|
"Programming Language :: Python :: Implementation :: PyPy",
|
||||||
"Programming Language :: Python :: 3.10",
|
"Programming Language :: Python :: 3.10",
|
||||||
"Programming Language :: Python :: 3.11",
|
"Programming Language :: Python :: 3.11",
|
||||||
"Programming Language :: Python :: 3.12",
|
"Programming Language :: Python :: 3.12",
|
||||||
"Programming Language :: Python :: 3.13",
|
"Programming Language :: Python :: 3.13",
|
||||||
|
"Programming Language :: Python :: 3.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
@ -66,7 +66,7 @@ test = ["requirements/test.txt"]
|
|||||||
zstd = ["requirements/zstd.txt"]
|
zstd = ["requirements/zstd.txt"]
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
python_version = "3.9"
|
python_version = "3.10"
|
||||||
strict = true
|
strict = true
|
||||||
pretty = true
|
pretty = true
|
||||||
show_error_context = true
|
show_error_context = true
|
||||||
@ -106,7 +106,6 @@ filterwarnings = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
target-version = "py38"
|
|
||||||
line-length = 100
|
line-length = 100
|
||||||
|
|
||||||
[tool.ruff.lint]
|
[tool.ruff.lint]
|
||||||
|
|||||||
@ -3,5 +3,5 @@ mockupdb
|
|||||||
tornado>=5
|
tornado>=5
|
||||||
aiohttp>=3.8.7
|
aiohttp>=3.8.7
|
||||||
motor[encryption]
|
motor[encryption]
|
||||||
cffi>=1.17.0rc1;python_version=="3.13"
|
cffi>=1.17.0rc1;python_version>="3.13"
|
||||||
pytest_asyncio
|
pytest_asyncio
|
||||||
|
|||||||
@ -299,7 +299,7 @@ class SynchroMeta(type):
|
|||||||
|
|
||||||
# Set DelegateProperties' and SynchroProperties' names.
|
# Set DelegateProperties' and SynchroProperties' names.
|
||||||
for name, attr in attrs.items():
|
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:
|
if attr.name is None:
|
||||||
attr.name = name
|
attr.name = name
|
||||||
|
|
||||||
|
|||||||
@ -334,7 +334,7 @@ class TestAsyncIOCollection(AsyncIOTestCase):
|
|||||||
await self.collection.explicit_encryption.find(find_payload).to_list(3),
|
await self.collection.explicit_encryption.find(find_payload).to_list(3),
|
||||||
key=lambda x: x["_id"],
|
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)
|
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 (
|
from motor.motor_asyncio import (
|
||||||
AsyncIOMotorChangeStream,
|
AsyncIOMotorChangeStream,
|
||||||
@ -9,9 +9,9 @@ from motor.motor_asyncio import (
|
|||||||
AsyncIOMotorDatabase,
|
AsyncIOMotorDatabase,
|
||||||
)
|
)
|
||||||
|
|
||||||
client: AsyncIOMotorClient[Dict[str, Any]]
|
client: AsyncIOMotorClient[dict[str, Any]]
|
||||||
db: AsyncIOMotorDatabase[Dict[str, Any]]
|
db: AsyncIOMotorDatabase[dict[str, Any]]
|
||||||
cur: AsyncIOMotorCursor[Dict[str, Any]]
|
cur: AsyncIOMotorCursor[dict[str, Any]]
|
||||||
coll: AsyncIOMotorCollection[Dict[str, Any]]
|
coll: AsyncIOMotorCollection[dict[str, Any]]
|
||||||
cs: AsyncIOMotorChangeStream[Dict[str, Any]]
|
cs: AsyncIOMotorChangeStream[dict[str, Any]]
|
||||||
enc: AsyncIOMotorClientEncryption[Dict[str, Any]]
|
enc: AsyncIOMotorClientEncryption[dict[str, Any]]
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
from typing import Iterable
|
from collections.abc import Iterable
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from mypy import api
|
from mypy import api
|
||||||
|
|||||||
@ -17,8 +17,9 @@ sample client code that uses Motor typings.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
from collections.abc import Callable, Mapping
|
||||||
from test.asyncio_tests import AsyncIOTestCase, asyncio_test
|
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 import CodecOptions
|
||||||
from bson.raw_bson import RawBSONDocument
|
from bson.raw_bson import RawBSONDocument
|
||||||
@ -116,11 +117,11 @@ class TestMotor(AsyncIOTestCase):
|
|||||||
async def test_bulk_write(self) -> None:
|
async def test_bulk_write(self) -> None:
|
||||||
await self.collection.insert_one({})
|
await self.collection.insert_one({})
|
||||||
coll = self.collection
|
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)
|
result_one = await coll.bulk_write(requests)
|
||||||
self.assertTrue(result_one.acknowledged)
|
self.assertTrue(result_one.acknowledged)
|
||||||
new_requests: List[Union[InsertOne[Movie], ReplaceOne[Movie]]] = []
|
new_requests: list[Union[InsertOne[Movie], ReplaceOne[Movie]]] = []
|
||||||
input_list: List[Union[InsertOne[Movie], ReplaceOne[Movie]]] = [
|
input_list: list[Union[InsertOne[Movie], ReplaceOne[Movie]]] = [
|
||||||
InsertOne(Movie(name="American Graffiti", year=1973)),
|
InsertOne(Movie(name="American Graffiti", year=1973)),
|
||||||
ReplaceOne({}, 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]
|
@asyncio_test # type:ignore[misc]
|
||||||
async def test_bulk_write_heterogeneous(self) -> None:
|
async def test_bulk_write_heterogeneous(self) -> None:
|
||||||
coll = self.collection
|
coll = self.collection
|
||||||
requests: List[Union[InsertOne[Movie], ReplaceOne, DeleteOne]] = [
|
requests: list[Union[InsertOne[Movie], ReplaceOne, DeleteOne]] = [
|
||||||
InsertOne(Movie(name="American Graffiti", year=1973)),
|
InsertOne(Movie(name="American Graffiti", year=1973)),
|
||||||
ReplaceOne({}, {"name": "American Graffiti", "year": "WRONG_TYPE"}),
|
ReplaceOne({}, {"name": "American Graffiti", "year": "WRONG_TYPE"}),
|
||||||
DeleteOne({}),
|
DeleteOne({}),
|
||||||
]
|
]
|
||||||
result_one = await coll.bulk_write(requests)
|
result_one = await coll.bulk_write(requests)
|
||||||
self.assertTrue(result_one.acknowledged)
|
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)),
|
InsertOne(Movie(name="American Graffiti", year=1973)),
|
||||||
ReplaceOne(
|
ReplaceOne(
|
||||||
{},
|
{},
|
||||||
@ -154,7 +155,7 @@ class TestMotor(AsyncIOTestCase):
|
|||||||
|
|
||||||
@asyncio_test # type:ignore[misc]
|
@asyncio_test # type:ignore[misc]
|
||||||
async def test_command(self) -> None:
|
async def test_command(self) -> None:
|
||||||
result: Dict = await self.cx.admin.command("ping")
|
result: dict = await self.cx.admin.command("ping")
|
||||||
result.items()
|
result.items()
|
||||||
|
|
||||||
@asyncio_test # type:ignore[misc]
|
@asyncio_test # type:ignore[misc]
|
||||||
@ -192,7 +193,7 @@ class TestMotor(AsyncIOTestCase):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
class mydict(Dict[str, Any]):
|
class mydict(dict[str, Any]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
result = coll3.aggregate(
|
result = coll3.aggregate(
|
||||||
@ -226,7 +227,7 @@ class TestDocumentType(AsyncIOTestCase):
|
|||||||
|
|
||||||
@only_type_check
|
@only_type_check
|
||||||
async def test_explicit_document_type(self) -> None:
|
async def test_explicit_document_type(self) -> None:
|
||||||
client: AsyncIOMotorClient[Dict[str, Any]] = AsyncIOMotorClient()
|
client: AsyncIOMotorClient[dict[str, Any]] = AsyncIOMotorClient()
|
||||||
coll = client.test.test
|
coll = client.test.test
|
||||||
retrieved = await coll.find_one({"_id": "foo"})
|
retrieved = await coll.find_one({"_id": "foo"})
|
||||||
assert retrieved is not None
|
assert retrieved is not None
|
||||||
@ -320,7 +321,7 @@ class TestDocumentType(AsyncIOTestCase):
|
|||||||
|
|
||||||
@only_type_check
|
@only_type_check
|
||||||
async def test_create_index(self) -> None:
|
async def test_create_index(self) -> None:
|
||||||
client: AsyncIOMotorClient[Dict[str, str]] = AsyncIOMotorClient("test")
|
client: AsyncIOMotorClient[dict[str, str]] = AsyncIOMotorClient("test")
|
||||||
db = client.test
|
db = client.test
|
||||||
async with await client.start_session() as session:
|
async with await client.start_session() as session:
|
||||||
index = await db.test.create_index(
|
index = await db.test.create_index(
|
||||||
@ -361,13 +362,13 @@ class TestCommandDocumentType(AsyncIOTestCase):
|
|||||||
@only_type_check
|
@only_type_check
|
||||||
async def test_default(self) -> None:
|
async def test_default(self) -> None:
|
||||||
client: AsyncIOMotorClient = AsyncIOMotorClient()
|
client: AsyncIOMotorClient = AsyncIOMotorClient()
|
||||||
result: Dict = await client.admin.command("ping")
|
result: dict = await client.admin.command("ping")
|
||||||
result["a"] = 1
|
result["a"] = 1
|
||||||
|
|
||||||
@only_type_check
|
@only_type_check
|
||||||
async def test_explicit_document_type(self) -> None:
|
async def test_explicit_document_type(self) -> None:
|
||||||
client: AsyncIOMotorClient = AsyncIOMotorClient()
|
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 = await client.admin.command("ping", codec_options=codec_options)
|
||||||
result["a"] = 1
|
result["a"] = 1
|
||||||
|
|
||||||
|
|||||||
@ -336,7 +336,7 @@ class MotorCollectionTest(MotorTest):
|
|||||||
await self.collection.explicit_encryption.find(find_payload).to_list(3),
|
await self.collection.explicit_encryption.find(find_payload).to_list(3),
|
||||||
key=lambda x: x["_id"],
|
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)
|
self.assertEqual(elem[f"encrypted{name}"], expected)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user