MOTOR-1352 Update APIs to Support PyMongo 4.9 (#297)
This commit is contained in:
parent
72e68b7569
commit
972b7ffef9
@ -27,7 +27,8 @@ from pymongo.change_stream import ChangeStream
|
||||
from pymongo.client_session import ClientSession
|
||||
from pymongo.collection import Collection
|
||||
from pymongo.command_cursor import CommandCursor, RawBatchCommandCursor
|
||||
from pymongo.cursor import _QUERY_OPTIONS, Cursor, RawBatchCursor
|
||||
from pymongo.cursor import Cursor, RawBatchCursor
|
||||
from pymongo.cursor_shared import _QUERY_OPTIONS
|
||||
from pymongo.database import Database
|
||||
from pymongo.driver_info import DriverInfo
|
||||
from pymongo.encryption import ClientEncryption
|
||||
@ -1769,8 +1770,6 @@ class AgnosticCursor(AgnosticBaseCursor):
|
||||
comment = MotorCursorChainingMethod()
|
||||
allow_disk_use = MotorCursorChainingMethod()
|
||||
|
||||
_Cursor__die = AsyncRead()
|
||||
|
||||
def rewind(self):
|
||||
"""Rewind this cursor to its unevaluated state."""
|
||||
self.delegate.rewind()
|
||||
@ -1788,13 +1787,13 @@ class AgnosticCursor(AgnosticBaseCursor):
|
||||
return self.__class__(self.delegate.__deepcopy__(memo), self.collection)
|
||||
|
||||
def _query_flags(self):
|
||||
return self.delegate._Cursor__query_flags
|
||||
return self.delegate._query_flags
|
||||
|
||||
def _data(self):
|
||||
return self.delegate._Cursor__data
|
||||
return self.delegate._data
|
||||
|
||||
def _killed(self):
|
||||
return self.delegate._Cursor__killed
|
||||
return self.delegate._killed
|
||||
|
||||
|
||||
class AgnosticRawBatchCursor(AgnosticCursor):
|
||||
@ -1806,8 +1805,6 @@ class AgnosticCommandCursor(AgnosticBaseCursor):
|
||||
__motor_class_name__ = "MotorCommandCursor"
|
||||
__delegate_class__ = CommandCursor
|
||||
|
||||
_CommandCursor__die = AsyncRead()
|
||||
|
||||
async def try_next(self):
|
||||
"""Advance the cursor without blocking indefinitely.
|
||||
|
||||
@ -1834,10 +1831,10 @@ class AgnosticCommandCursor(AgnosticBaseCursor):
|
||||
return 0
|
||||
|
||||
def _data(self):
|
||||
return self.delegate._CommandCursor__data
|
||||
return self.delegate._data
|
||||
|
||||
def _killed(self):
|
||||
return self.delegate._CommandCursor__killed
|
||||
return self.delegate._killed
|
||||
|
||||
|
||||
class AgnosticRawBatchCommandCursor(AgnosticCommandCursor):
|
||||
@ -1849,25 +1846,25 @@ class _LatentCursor:
|
||||
"""Take the place of a PyMongo CommandCursor until aggregate() begins."""
|
||||
|
||||
alive = True
|
||||
_CommandCursor__data = []
|
||||
_CommandCursor__id = None
|
||||
_CommandCursor__killed = False
|
||||
_CommandCursor__sock_mgr = None
|
||||
_CommandCursor__session = None
|
||||
_CommandCursor__explicit_session = None
|
||||
_data = []
|
||||
_id = None
|
||||
_killed = False
|
||||
_sock_mgr = None
|
||||
_session = None
|
||||
_explicit_session = None
|
||||
cursor_id = None
|
||||
|
||||
def __init__(self, collection):
|
||||
self._CommandCursor__collection = collection.delegate
|
||||
self._collection = collection.delegate
|
||||
|
||||
def _CommandCursor__end_session(self, *args, **kwargs):
|
||||
def _end_session(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def _CommandCursor__die(self, *args, **kwargs):
|
||||
def _die_lock(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def clone(self):
|
||||
return _LatentCursor(self._CommandCursor__collection)
|
||||
return _LatentCursor(self._collection)
|
||||
|
||||
def rewind(self):
|
||||
pass
|
||||
@ -1924,9 +1921,9 @@ class AgnosticLatentCommandCursor(AgnosticCommandCursor):
|
||||
# Return early if the task was cancelled.
|
||||
if original_future.done():
|
||||
return
|
||||
if self.delegate._CommandCursor__data or not self.delegate.alive:
|
||||
if self.delegate._data or not self.delegate.alive:
|
||||
# _get_more is complete.
|
||||
original_future.set_result(len(self.delegate._CommandCursor__data))
|
||||
original_future.set_result(len(self.delegate._data))
|
||||
else:
|
||||
# Send a getMore.
|
||||
future = super()._get_more()
|
||||
|
||||
@ -40,10 +40,11 @@ from bson.raw_bson import RawBSONDocument
|
||||
from pymongo import IndexModel, ReadPreference, WriteConcern
|
||||
from pymongo.change_stream import ChangeStream
|
||||
from pymongo.client_options import ClientOptions
|
||||
from pymongo.client_session import _T, ClientSession, SessionOptions, TransactionOptions
|
||||
from pymongo.collection import Collection, ReturnDocument, _WriteOp # noqa: F401
|
||||
from pymongo.client_session import ClientSession, SessionOptions, TransactionOptions
|
||||
from pymongo.collection import Collection, ReturnDocument # noqa: F401
|
||||
from pymongo.command_cursor import CommandCursor, RawBatchCommandCursor
|
||||
from pymongo.cursor import Cursor, RawBatchCursor, _Hint, _Sort
|
||||
from pymongo.cursor import Cursor, RawBatchCursor
|
||||
from pymongo.cursor_shared import _Hint, _Sort
|
||||
from pymongo.database import Database
|
||||
from pymongo.encryption import ClientEncryption, RewrapManyDataKeyResult
|
||||
from pymongo.encryption_options import RangeOpts
|
||||
@ -57,6 +58,8 @@ from pymongo.results import (
|
||||
InsertOneResult,
|
||||
UpdateResult,
|
||||
)
|
||||
from pymongo.synchronous.client_session import _T
|
||||
from pymongo.synchronous.collection import _WriteOp
|
||||
from pymongo.topology_description import TopologyDescription
|
||||
from pymongo.typings import (
|
||||
_Address,
|
||||
@ -756,8 +759,7 @@ class AgnosticRawBatchCommandCursor(AgnosticCommandCursor[_DocumentType]):
|
||||
|
||||
class _LatentCursor(Generic[_DocumentType]):
|
||||
def __init__(self, collection: AgnosticCollection[_DocumentType]): ...
|
||||
def _CommandCursor__end_session(self, *args: Any, **kwargs: Any) -> None: ...
|
||||
def _CommandCursor__die(self, *args: Any, **kwargs: Any) -> None: ...
|
||||
def _end_session(self, *args: Any, **kwargs: Any) -> None: ...
|
||||
def clone(self) -> _LatentCursor[_DocumentType]: ...
|
||||
def rewind(self) -> _LatentCursor[_DocumentType]: ...
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ from typing import Any, Mapping, MutableMapping, Optional, Union
|
||||
from bson import Code, CodecOptions, Timestamp
|
||||
from bson.raw_bson import RawBSONDocument
|
||||
from pymongo.client_session import TransactionOptions
|
||||
from pymongo.cursor import _Hint, _Sort
|
||||
from pymongo.cursor_shared import _Hint, _Sort
|
||||
from pymongo.read_concern import ReadConcern
|
||||
from pymongo.read_preferences import ReadPreference, _ServerMode
|
||||
from pymongo.typings import _CollationIn, _DocumentType, _DocumentTypeArg, _Pipeline
|
||||
|
||||
@ -37,9 +37,6 @@ class AgnosticGridOutCursor(AgnosticCursor):
|
||||
__motor_class_name__ = "MotorGridOutCursor"
|
||||
__delegate_class__ = gridfs.GridOutCursor
|
||||
|
||||
# PyMongo's GridOutCursor inherits __die from Cursor.
|
||||
_Cursor__die = AsyncCommand()
|
||||
|
||||
def next_object(self):
|
||||
"""**DEPRECATED** - Get next GridOut object from cursor."""
|
||||
# Note: the super() call will raise a warning for the deprecation.
|
||||
@ -88,7 +85,6 @@ class AgnosticGridOut:
|
||||
__motor_class_name__ = "MotorGridOut"
|
||||
__delegate_class__ = gridfs.GridOut
|
||||
|
||||
_ensure_file = AsyncCommand()
|
||||
_id = MotorGridOutProperty()
|
||||
aliases = MotorGridOutProperty()
|
||||
chunk_size = MotorGridOutProperty()
|
||||
@ -98,6 +94,7 @@ class AgnosticGridOut:
|
||||
length = MotorGridOutProperty()
|
||||
metadata = MotorGridOutProperty()
|
||||
name = MotorGridOutProperty()
|
||||
_open = AsyncCommand(attr_name="open")
|
||||
read = AsyncRead()
|
||||
readable = DelegateMethod()
|
||||
readchunk = AsyncRead()
|
||||
@ -160,7 +157,7 @@ class AgnosticGridOut:
|
||||
:class:`~motor.MotorGridOut` now opens itself on demand, calling
|
||||
``open`` explicitly is rarely needed.
|
||||
"""
|
||||
return self._framework.chain_return_value(self._ensure_file(), self.get_io_loop(), self)
|
||||
return self._framework.chain_return_value(self._open(), self.get_io_loop(), self)
|
||||
|
||||
def get_io_loop(self):
|
||||
return self.io_loop
|
||||
|
||||
@ -35,7 +35,6 @@ _SEEK_END = os.SEEK_END
|
||||
class AgnosticGridOutCursor(AgnosticCursor):
|
||||
__motor_class_name__: str
|
||||
__delegate_class__: type[GridOutCursor]
|
||||
async def _Cursor__die(self, synchronous: bool = False) -> None: ...
|
||||
def next_object(self) -> AgnosticGridOutCursor: ...
|
||||
|
||||
class AgnosticGridOut:
|
||||
@ -50,7 +49,7 @@ class AgnosticGridOut:
|
||||
length: int
|
||||
upload_date: datetime.datetime
|
||||
metadata: Optional[Mapping[str, Any]]
|
||||
async def _ensure_file(self) -> None: ...
|
||||
async def _open(self) -> None: ...
|
||||
def close(self) -> None: ...
|
||||
async def read(self, size: int = -1) -> NoReturn: ...
|
||||
def readable(self) -> bool: ...
|
||||
|
||||
@ -3,7 +3,7 @@ from typing import Any, Mapping, MutableMapping, Optional, Union
|
||||
from bson import Code, CodecOptions, Timestamp
|
||||
from bson.raw_bson import RawBSONDocument
|
||||
from pymongo.client_session import TransactionOptions
|
||||
from pymongo.cursor import _Hint, _Sort
|
||||
from pymongo.cursor_shared import _Hint, _Sort
|
||||
from pymongo.read_concern import ReadConcern
|
||||
from pymongo.read_preferences import ReadPreference, _ServerMode
|
||||
from pymongo.typings import _CollationIn, _DocumentType, _DocumentTypeArg, _Pipeline
|
||||
|
||||
@ -52,6 +52,10 @@ Tracker = "https://jira.mongodb.org/projects/MOTOR/issues"
|
||||
path = "motor/_version.py"
|
||||
validate-bump = false
|
||||
|
||||
[tool.hatch.metadata]
|
||||
# TODO: MOTOR-1351 Remove before releasing Motor 3.6.
|
||||
allow-direct-references = true
|
||||
|
||||
[tool.hatch.metadata.hooks.requirements_txt]
|
||||
files = ["requirements.txt"]
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
pymongo>=4.5,<5
|
||||
pymongo @ git+https://github.com/mongodb/mongo-python-driver.git
|
||||
|
||||
@ -98,7 +98,7 @@ class AIOMotorTestBasic(AsyncIOTestCase):
|
||||
motor_cursor = collection.find()
|
||||
cursor = motor_cursor.delegate
|
||||
|
||||
self.assertEqual(Nearest(tag_sets=[{"yay": "jesse"}]), cursor._read_preference())
|
||||
self.assertEqual(Nearest(tag_sets=[{"yay": "jesse"}]), cursor._get_read_preference())
|
||||
|
||||
cx.close()
|
||||
|
||||
|
||||
@ -287,6 +287,7 @@ class TestAsyncIOCollection(AsyncIOTestCase):
|
||||
self.assertEqual(exc.exception.code, 121)
|
||||
await self.db.drop_collection("testing1", encrypted_fields=ef)
|
||||
|
||||
@env.require_version_min(8, 0, -1, -1)
|
||||
@asyncio_test
|
||||
async def test_async_encrypt_expression(self):
|
||||
c = self.collection
|
||||
@ -299,12 +300,12 @@ class TestAsyncIOCollection(AsyncIOTestCase):
|
||||
"local", key_alt_names=["pymongo_encryption_example_1"]
|
||||
)
|
||||
name = "DoubleNoPrecision"
|
||||
range_opts = RangeOpts(sparsity=1)
|
||||
range_opts = RangeOpts(sparsity=1, trim_factor=1)
|
||||
for i in [6.0, 30.0, 200.0]:
|
||||
insert_payload = await client_encryption.encrypt(
|
||||
float(i),
|
||||
key_id=data_key,
|
||||
algorithm=Algorithm.RANGEPREVIEW,
|
||||
algorithm=Algorithm.RANGE,
|
||||
contention_factor=0,
|
||||
range_opts=range_opts,
|
||||
)
|
||||
@ -323,8 +324,8 @@ class TestAsyncIOCollection(AsyncIOTestCase):
|
||||
]
|
||||
},
|
||||
key_id=data_key,
|
||||
algorithm=Algorithm.RANGEPREVIEW,
|
||||
query_type=QueryType.RANGEPREVIEW,
|
||||
algorithm=Algorithm.RANGE,
|
||||
query_type=QueryType.RANGE,
|
||||
contention_factor=0,
|
||||
range_opts=range_opts,
|
||||
)
|
||||
|
||||
@ -133,7 +133,7 @@ class TestAsyncIOCursor(AsyncIOMockServerTestCase):
|
||||
self.assertTrue(cursor.next_object())
|
||||
|
||||
# Not valid on server, causes CursorNotFound.
|
||||
cursor.delegate._Cursor__id = bson.int64.Int64(1234)
|
||||
cursor.delegate._id = bson.int64.Int64(1234)
|
||||
|
||||
with self.assertRaises(OperationFailure):
|
||||
await cursor.fetch_next
|
||||
@ -355,7 +355,7 @@ class TestAsyncIOCursor(AsyncIOMockServerTestCase):
|
||||
|
||||
def canceled():
|
||||
try:
|
||||
self.assertFalse(cursor.delegate._Cursor__killed)
|
||||
self.assertFalse(cursor.delegate._killed)
|
||||
self.assertTrue(cursor.alive)
|
||||
|
||||
# Resume iteration
|
||||
|
||||
@ -127,7 +127,7 @@ class MotorGridFileTest(AsyncIOTestCase):
|
||||
|
||||
# The call tree should include PyMongo code we ran on a thread.
|
||||
formatted = "\n".join(traceback.format_tb(tb))
|
||||
self.assertTrue("_ensure_file" in formatted)
|
||||
self.assertTrue("open" in formatted)
|
||||
|
||||
@asyncio_test
|
||||
async def test_alternate_collection(self):
|
||||
|
||||
@ -100,7 +100,7 @@ class MotorTestBasic(MotorTest):
|
||||
motor_cursor = collection.find()
|
||||
cursor = motor_cursor.delegate
|
||||
|
||||
self.assertEqual(Nearest(tag_sets=[{"yay": "jesse"}]), cursor._read_preference())
|
||||
self.assertEqual(Nearest(tag_sets=[{"yay": "jesse"}]), cursor._get_read_preference())
|
||||
|
||||
cx.close()
|
||||
|
||||
|
||||
@ -289,6 +289,7 @@ class MotorCollectionTest(MotorTest):
|
||||
self.assertEqual(exc.exception.code, 121)
|
||||
await self.db.drop_collection("testing1", encrypted_fields=ef)
|
||||
|
||||
@env.require_version_min(8, 0, -1, -1)
|
||||
@gen_test
|
||||
async def test_async_encrypt_expression(self):
|
||||
c = self.collection
|
||||
@ -301,12 +302,12 @@ class MotorCollectionTest(MotorTest):
|
||||
"local", key_alt_names=["pymongo_encryption_example_1"]
|
||||
)
|
||||
name = "DoubleNoPrecision"
|
||||
range_opts = RangeOpts(sparsity=1)
|
||||
range_opts = RangeOpts(sparsity=1, trim_factor=1)
|
||||
for i in [6.0, 30.0, 200.0]:
|
||||
insert_payload = await client_encryption.encrypt(
|
||||
float(i),
|
||||
key_id=data_key,
|
||||
algorithm=Algorithm.RANGEPREVIEW,
|
||||
algorithm=Algorithm.RANGE,
|
||||
contention_factor=0,
|
||||
range_opts=range_opts,
|
||||
)
|
||||
@ -325,8 +326,8 @@ class MotorCollectionTest(MotorTest):
|
||||
]
|
||||
},
|
||||
key_id=data_key,
|
||||
algorithm=Algorithm.RANGEPREVIEW,
|
||||
query_type=QueryType.RANGEPREVIEW,
|
||||
algorithm=Algorithm.RANGE,
|
||||
query_type=QueryType.RANGE,
|
||||
contention_factor=0,
|
||||
range_opts=range_opts,
|
||||
)
|
||||
|
||||
@ -33,15 +33,15 @@ pymongo_only = set(["next"])
|
||||
|
||||
motor_client_only = motor_only.union(["open"])
|
||||
|
||||
pymongo_client_only = set([]).union(pymongo_only)
|
||||
pymongo_client_only = set(["bulk_write"]).union(pymongo_only)
|
||||
|
||||
pymongo_database_only = set([]).union(pymongo_only)
|
||||
|
||||
pymongo_collection_only = set([]).union(pymongo_only)
|
||||
|
||||
motor_cursor_only = set(
|
||||
["fetch_next", "to_list", "each", "started", "next_object", "closed"]
|
||||
).union(motor_only)
|
||||
motor_cursor_only = set(["fetch_next", "each", "started", "next_object", "closed"]).union(
|
||||
motor_only
|
||||
)
|
||||
|
||||
pymongo_cursor_only = set(["retrieved"])
|
||||
|
||||
@ -118,7 +118,7 @@ class MotorCoreTestGridFS(MotorTest):
|
||||
)
|
||||
|
||||
def test_gridin_attrs(self):
|
||||
motor_gridin_only = set(["set"]).union(motor_only)
|
||||
motor_gridin_only = set([]).union(motor_only)
|
||||
gridin_only = set(["md5"])
|
||||
|
||||
self.assertEqual(
|
||||
@ -137,6 +137,7 @@ class MotorCoreTestGridFS(MotorTest):
|
||||
"truncate",
|
||||
"flush",
|
||||
"fileno",
|
||||
"open",
|
||||
"closed",
|
||||
"writelines",
|
||||
"isatty",
|
||||
|
||||
@ -138,7 +138,7 @@ class MotorCursorTest(MotorMockServerTest):
|
||||
self.assertTrue(cursor.next_object())
|
||||
|
||||
# Not valid on server, causes CursorNotFound.
|
||||
cursor.delegate._Cursor__id = bson.int64.Int64(1234)
|
||||
cursor.delegate._id = bson.int64.Int64(1234)
|
||||
|
||||
with self.assertRaises(OperationFailure):
|
||||
await cursor.fetch_next
|
||||
@ -309,7 +309,7 @@ class MotorCursorTest(MotorMockServerTest):
|
||||
|
||||
def canceled():
|
||||
try:
|
||||
self.assertFalse(cursor.delegate._Cursor__killed)
|
||||
self.assertFalse(cursor.delegate._killed)
|
||||
self.assertTrue(cursor.alive)
|
||||
|
||||
# Resume iteration
|
||||
|
||||
@ -126,7 +126,7 @@ class MotorGridFileTest(MotorTest):
|
||||
|
||||
# The call tree should include PyMongo code we ran on a thread.
|
||||
formatted = "\n".join(traceback.format_tb(tb))
|
||||
self.assertTrue("_ensure_file" in formatted)
|
||||
self.assertTrue("open" in formatted)
|
||||
|
||||
@gen_test
|
||||
async def test_alternate_collection(self):
|
||||
|
||||
3
tox.ini
3
tox.ini
@ -101,8 +101,7 @@ extras =
|
||||
encryption
|
||||
test
|
||||
commands =
|
||||
# TODO: Use "master" as part of MOTOR-1330
|
||||
pip install git+https://github.com/mongodb/mongo-python-driver.git@v4.8
|
||||
pip install git+https://github.com/mongodb/mongo-python-driver.git
|
||||
pip install -q --pre --prefer-binary pymongocrypt
|
||||
python --version
|
||||
python -c "import pymongo; print('PyMongo %s' % (pymongo.version,))"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user