Merge branch 'master' of github.com:mongodb/mongo-python-driver

This commit is contained in:
Steven Silvester 2024-08-27 16:13:22 -05:00
commit cbc223841a
No known key found for this signature in database
GPG Key ID: B1BF5EC3A8B32F91
6 changed files with 56 additions and 25 deletions

View File

@ -1176,20 +1176,22 @@ class AsyncGridIn:
raise AttributeError("GridIn object has no attribute '%s'" % name)
def __setattr__(self, name: str, value: Any) -> None:
if _IS_SYNC:
# For properties of this instance like _buffer, or descriptors set on
# the class like filename, use regular __setattr__
if name in self.__dict__ or name in self.__class__.__dict__:
object.__setattr__(self, name, value)
else:
# For properties of this instance like _buffer, or descriptors set on
# the class like filename, use regular __setattr__
if name in self.__dict__ or name in self.__class__.__dict__:
object.__setattr__(self, name, value)
else:
if _IS_SYNC:
# All other attributes are part of the document in db.fs.files.
# Store them to be sent to server on close() or if closed, send
# them now.
self._file[name] = value
if self._closed:
self._coll.files.update_one({"_id": self._file["_id"]}, {"$set": {name: value}})
else:
object.__setattr__(self, name, value)
else:
raise AttributeError(
"AsyncGridIn does not support __setattr__. Use AsyncGridIn.set() instead"
)
async def set(self, name: str, value: Any) -> None:
# For properties of this instance like _buffer, or descriptors set on
@ -1484,6 +1486,17 @@ class AsyncGridOut(io.IOBase):
_file: Any
_chunk_iter: Any
async def __anext__(self) -> bytes:
return super().__next__()
def __next__(self) -> bytes: # noqa: F811, RUF100
if _IS_SYNC:
return super().__next__()
else:
raise TypeError(
"AsyncGridOut does not support synchronous iteration. Use `async for` instead"
)
async def open(self) -> None:
if not self._file:
_disallow_transactions(self._session)
@ -1511,6 +1524,7 @@ class AsyncGridOut(io.IOBase):
"""Reads a chunk at a time. If the current position is within a
chunk the remainder of the chunk is returned.
"""
await self.open()
received = len(self._buffer) - self._buffer_pos
chunk_data = EMPTY
chunk_size = int(self.chunk_size)

View File

@ -1166,20 +1166,22 @@ class GridIn:
raise AttributeError("GridIn object has no attribute '%s'" % name)
def __setattr__(self, name: str, value: Any) -> None:
if _IS_SYNC:
# For properties of this instance like _buffer, or descriptors set on
# the class like filename, use regular __setattr__
if name in self.__dict__ or name in self.__class__.__dict__:
object.__setattr__(self, name, value)
else:
# For properties of this instance like _buffer, or descriptors set on
# the class like filename, use regular __setattr__
if name in self.__dict__ or name in self.__class__.__dict__:
object.__setattr__(self, name, value)
else:
if _IS_SYNC:
# All other attributes are part of the document in db.fs.files.
# Store them to be sent to server on close() or if closed, send
# them now.
self._file[name] = value
if self._closed:
self._coll.files.update_one({"_id": self._file["_id"]}, {"$set": {name: value}})
else:
object.__setattr__(self, name, value)
else:
raise AttributeError(
"GridIn does not support __setattr__. Use GridIn.set() instead"
)
def set(self, name: str, value: Any) -> None:
# For properties of this instance like _buffer, or descriptors set on
@ -1472,6 +1474,15 @@ class GridOut(io.IOBase):
_file: Any
_chunk_iter: Any
def __next__(self) -> bytes:
return super().__next__()
def __next__(self) -> bytes: # noqa: F811, RUF100
if _IS_SYNC:
return super().__next__()
else:
raise TypeError("GridOut does not support synchronous iteration. Use `for` instead")
def open(self) -> None:
if not self._file:
_disallow_transactions(self._session)
@ -1499,6 +1510,7 @@ class GridOut(io.IOBase):
"""Reads a chunk at a time. If the current position is within a
chunk the remainder of the chunk is returned.
"""
self.open()
received = len(self._buffer) - self._buffer_pos
chunk_data = EMPTY
chunk_size = int(self.chunk_size)

View File

@ -304,7 +304,7 @@ class _EncryptionIO(AsyncMongoCryptCallback): # type: ignore[misc]
class RewrapManyDataKeyResult:
"""Result object returned by a :meth:`~ClientEncryption.rewrap_many_data_key` operation.
"""Result object returned by a :meth:`~AsyncClientEncryption.rewrap_many_data_key` operation.
.. versionadded:: 4.2
"""
@ -316,7 +316,7 @@ class RewrapManyDataKeyResult:
def bulk_write_result(self) -> Optional[BulkWriteResult]:
"""The result of the bulk write operation used to update the key vault
collection with one or more rewrapped data keys. If
:meth:`~ClientEncryption.rewrap_many_data_key` does not find any matching keys to rewrap,
:meth:`~AsyncClientEncryption.rewrap_many_data_key` does not find any matching keys to rewrap,
no bulk write operation will be executed and this field will be
``None``.
"""
@ -506,7 +506,7 @@ def _create_mongocrypt_options(**kwargs: Any) -> MongoCryptOptions:
return opts
class ClientEncryption(Generic[_DocumentType]):
class AsyncClientEncryption(Generic[_DocumentType]):
"""Explicit client-side field level encryption."""
def __init__(
@ -519,7 +519,7 @@ class ClientEncryption(Generic[_DocumentType]):
) -> None:
"""Explicit client-side field level encryption.
The ClientEncryption class encapsulates explicit operations on a key
The AsyncClientEncryption class encapsulates explicit operations on a key
vault collection that cannot be done directly on an AsyncMongoClient. Similar
to configuring auto encryption on an AsyncMongoClient, it is constructed with
an AsyncMongoClient (to a MongoDB cluster containing the key vault
@ -1126,7 +1126,7 @@ class ClientEncryption(Generic[_DocumentType]):
result = await self._key_vault_coll.bulk_write(replacements)
return RewrapManyDataKeyResult(result)
async def __aenter__(self) -> ClientEncryption[_DocumentType]:
async def __aenter__(self) -> AsyncClientEncryption[_DocumentType]:
return self
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
@ -1134,7 +1134,7 @@ class ClientEncryption(Generic[_DocumentType]):
def _check_closed(self) -> None:
if self._encryption is None:
raise InvalidOperation("Cannot use closed ClientEncryption")
raise InvalidOperation("Cannot use closed AsyncClientEncryption")
async def close(self) -> None:
"""Release resources.
@ -1142,7 +1142,7 @@ class ClientEncryption(Generic[_DocumentType]):
Note that using this class in a with-statement will automatically call
:meth:`close`::
with ClientEncryption(...) as client_encryption:
with AsyncClientEncryption(...) as client_encryption:
encrypted = client_encryption.encrypt(value, ...)
decrypted = client_encryption.decrypt(encrypted)

View File

@ -70,7 +70,7 @@ class AutoEncryptionOpts:
users. To configure automatic *decryption* without automatic
*encryption* set ``bypass_auto_encryption=True``. Explicit
encryption and explicit decryption is also supported for all users
with the :class:`~pymongo.encryption.ClientEncryption` class.
with the :class:`~pymongo.asynchronous.encryption.AsyncClientEncryption` and :class:`~pymongo.encryption.ClientEncryption` classes.
See :ref:`automatic-client-side-encryption` for an example.

View File

@ -126,7 +126,7 @@ module = ["service_identity.*"]
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = ["pymongo.synchronous.*", "gridfs.synchronous.*"]
module = ["pymongo.synchronous.*"]
warn_unused_ignores = false
disable_error_code = ["unused-coroutine"]
@ -134,6 +134,10 @@ disable_error_code = ["unused-coroutine"]
module = ["pymongo.asynchronous.*"]
warn_unused_ignores = false
[[tool.mypy.overrides]]
module = ["gridfs.synchronous.*"]
warn_unused_ignores = false
disable_error_code = ["unused-coroutine", "no-redef"]
[tool.ruff]
target-version = "py37"

View File

@ -58,6 +58,7 @@ replacements = {
"_AsyncGridOutChunkIterator": "GridOutChunkIterator",
"_a_grid_in_property": "_grid_in_property",
"_a_grid_out_property": "_grid_out_property",
"AsyncClientEncryption": "ClientEncryption",
"AsyncMongoCryptCallback": "MongoCryptCallback",
"AsyncExplicitEncrypter": "ExplicitEncrypter",
"AsyncAutoEncrypter": "AutoEncrypter",