From d76366402d5f3070ae3605312c843c4678b690b9 Mon Sep 17 00:00:00 2001 From: Tejas Chauhan Date: Tue, 28 Jan 2025 23:01:42 +0530 Subject: [PATCH 1/4] Detailed error message for better debugging --- bson/__init__.py | 2 +- bson/binary.py | 4 +-- bson/code.py | 4 +-- bson/codec_options.py | 12 ++++++-- bson/dbref.py | 4 +-- bson/decimal128.py | 2 +- bson/timestamp.py | 4 +-- gridfs/asynchronous/grid_file.py | 12 +++++--- pymongo/__init__.py | 2 +- pymongo/asynchronous/auth.py | 2 +- pymongo/asynchronous/auth_oidc.py | 4 ++- pymongo/asynchronous/client_session.py | 12 ++++++-- pymongo/asynchronous/collection.py | 10 +++---- pymongo/asynchronous/command_cursor.py | 6 ++-- pymongo/asynchronous/cursor.py | 28 ++++++++++--------- pymongo/asynchronous/database.py | 8 ++++-- pymongo/asynchronous/encryption.py | 8 ++++-- pymongo/asynchronous/mongo_client.py | 12 +++++--- pymongo/common.py | 38 +++++++++++++++++--------- pymongo/driver_info.py | 2 +- pymongo/encryption_options.py | 4 ++- pymongo/helpers_shared.py | 9 ++++-- pymongo/monitoring.py | 8 ++++-- pymongo/read_concern.py | 2 +- pymongo/write_concern.py | 4 +-- 25 files changed, 127 insertions(+), 76 deletions(-) diff --git a/bson/__init__.py b/bson/__init__.py index fc6efe0d59..69c227c70d 100644 --- a/bson/__init__.py +++ b/bson/__init__.py @@ -1386,7 +1386,7 @@ def is_valid(bson: bytes) -> bool: :param bson: the data to be validated """ if not isinstance(bson, bytes): - raise TypeError("BSON data must be an instance of a subclass of bytes") + raise TypeError(f"BSON data must be an instance of a subclass of bytes, not {type(bson)}.") try: _bson_to_dict(bson, DEFAULT_CODEC_OPTIONS) diff --git a/bson/binary.py b/bson/binary.py index f90dce226c..59eb89caa4 100644 --- a/bson/binary.py +++ b/bson/binary.py @@ -290,7 +290,7 @@ def __new__( subtype: int = BINARY_SUBTYPE, ) -> Binary: if not isinstance(subtype, int): - raise TypeError("subtype must be an instance of int") + raise TypeError(f"subtype must be an instance of int, not {type(subtype)}.") if subtype >= 256 or subtype < 0: raise ValueError("subtype must be contained in [0, 256)") # Support any type that implements the buffer protocol. @@ -321,7 +321,7 @@ def from_uuid( .. versionadded:: 3.11 """ if not isinstance(uuid, UUID): - raise TypeError("uuid must be an instance of uuid.UUID") + raise TypeError(f"uuid must be an instance of uuid.UUID, not {type(uuid)}.") if uuid_representation not in ALL_UUID_REPRESENTATIONS: raise ValueError( diff --git a/bson/code.py b/bson/code.py index 6b4541d0ff..f924af0e18 100644 --- a/bson/code.py +++ b/bson/code.py @@ -56,7 +56,7 @@ def __new__( **kwargs: Any, ) -> Code: if not isinstance(code, str): - raise TypeError("code must be an instance of str") + raise TypeError(f"code must be an instance of str, not {type(code)}.") self = str.__new__(cls, code) @@ -67,7 +67,7 @@ def __new__( if scope is not None: if not isinstance(scope, _Mapping): - raise TypeError("scope must be an instance of dict") + raise TypeError(f"scope must be an instance of dict, not {type(scope)}.") if self.__scope is not None: self.__scope.update(scope) # type: ignore else: diff --git a/bson/codec_options.py b/bson/codec_options.py index 3a0b83b7be..01b78c06e1 100644 --- a/bson/codec_options.py +++ b/bson/codec_options.py @@ -401,17 +401,23 @@ def __new__( "uuid_representation must be a value from bson.binary.UuidRepresentation" ) if not isinstance(unicode_decode_error_handler, str): - raise ValueError("unicode_decode_error_handler must be a string") + raise ValueError( + f"unicode_decode_error_handler must be a string, not {type(unicode_decode_error_handler)}." + ) if tzinfo is not None: if not isinstance(tzinfo, datetime.tzinfo): - raise TypeError("tzinfo must be an instance of datetime.tzinfo") + raise TypeError( + f"tzinfo must be an instance of datetime.tzinfo, not {type(tzinfo)}." + ) if not tz_aware: raise ValueError("cannot specify tzinfo without also setting tz_aware=True") type_registry = type_registry or TypeRegistry() if not isinstance(type_registry, TypeRegistry): - raise TypeError("type_registry must be an instance of TypeRegistry") + raise TypeError( + f"type_registry must be an instance of TypeRegistry, not {type(type_registry)}." + ) return tuple.__new__( cls, diff --git a/bson/dbref.py b/bson/dbref.py index 6c21b8162c..a05f35f9de 100644 --- a/bson/dbref.py +++ b/bson/dbref.py @@ -56,9 +56,9 @@ def __init__( .. seealso:: The MongoDB documentation on `dbrefs `_. """ if not isinstance(collection, str): - raise TypeError("collection must be an instance of str") + raise TypeError(f"collection must be an instance of str, not {type(collection)}.") if database is not None and not isinstance(database, str): - raise TypeError("database must be an instance of str") + raise TypeError(f"database must be an instance of str, not {type(database)}.") self.__collection = collection self.__id = id diff --git a/bson/decimal128.py b/bson/decimal128.py index 016afb5eb8..c9e9daf732 100644 --- a/bson/decimal128.py +++ b/bson/decimal128.py @@ -277,7 +277,7 @@ def from_bid(cls: Type[Decimal128], value: bytes) -> Decimal128: point in Binary Integer Decimal (BID) format). """ if not isinstance(value, bytes): - raise TypeError("value must be an instance of bytes") + raise TypeError(f"value must be an instance of bytes, not {type(value)}.") if len(value) != 16: raise ValueError("value must be exactly 16 bytes") return cls((_UNPACK_64(value[8:])[0], _UNPACK_64(value[:8])[0])) # type: ignore diff --git a/bson/timestamp.py b/bson/timestamp.py index 3e76e7baad..fdd89639d5 100644 --- a/bson/timestamp.py +++ b/bson/timestamp.py @@ -58,9 +58,9 @@ def __init__(self, time: Union[datetime.datetime, int], inc: int) -> None: time = time - offset time = int(calendar.timegm(time.timetuple())) if not isinstance(time, int): - raise TypeError("time must be an instance of int") + raise TypeError(f"time must be an instance of int, not {type(time)}.") if not isinstance(inc, int): - raise TypeError("inc must be an instance of int") + raise TypeError(f"inc must be an instance of int, not {type(inc)}.") if not 0 <= time < UPPERBOUND: raise ValueError("time must be contained in [0, 2**32)") if not 0 <= inc < UPPERBOUND: diff --git a/gridfs/asynchronous/grid_file.py b/gridfs/asynchronous/grid_file.py index a49d51d304..f0e2aa43e8 100644 --- a/gridfs/asynchronous/grid_file.py +++ b/gridfs/asynchronous/grid_file.py @@ -100,7 +100,7 @@ def __init__(self, database: AsyncDatabase, collection: str = "fs"): .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(database, AsyncDatabase): - raise TypeError("database must be an instance of Database") + raise TypeError(f"database must be an instance of Database, not {type(database)}.") database = _clear_entity_type_registry(database) @@ -503,7 +503,7 @@ def __init__( .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(db, AsyncDatabase): - raise TypeError("database must be an instance of AsyncDatabase") + raise TypeError(f"database must be an instance of AsyncDatabase, not {type(db)}.") db = _clear_entity_type_registry(db) @@ -1082,7 +1082,9 @@ def __init__( :attr:`~pymongo.collection.AsyncCollection.write_concern` """ if not isinstance(root_collection, AsyncCollection): - raise TypeError("root_collection must be an instance of AsyncCollection") + raise TypeError( + f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}." + ) if not root_collection.write_concern.acknowledged: raise ConfigurationError("root_collection must use acknowledged write_concern") @@ -1436,7 +1438,9 @@ def __init__( from the server. Metadata is fetched when first needed. """ if not isinstance(root_collection, AsyncCollection): - raise TypeError("root_collection must be an instance of AsyncCollection") + raise TypeError( + f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}." + ) _disallow_transactions(session) root_collection = _clear_entity_type_registry(root_collection) diff --git a/pymongo/__init__.py b/pymongo/__init__.py index 58f6ff338b..f2b6b52a6e 100644 --- a/pymongo/__init__.py +++ b/pymongo/__init__.py @@ -160,7 +160,7 @@ def timeout(seconds: Optional[float]) -> ContextManager[None]: .. versionadded:: 4.2 """ if not isinstance(seconds, (int, float, type(None))): - raise TypeError("timeout must be None, an int, or a float") + raise TypeError(f"timeout must be None, an int, or a float, not {type(seconds)}.") if seconds and seconds < 0: raise ValueError("timeout cannot be negative") if seconds is not None: diff --git a/pymongo/asynchronous/auth.py b/pymongo/asynchronous/auth.py index b1e6d0125b..d844804453 100644 --- a/pymongo/asynchronous/auth.py +++ b/pymongo/asynchronous/auth.py @@ -161,7 +161,7 @@ def _password_digest(username: str, password: str) -> str: if len(password) == 0: raise ValueError("password can't be empty") if not isinstance(username, str): - raise TypeError("username must be an instance of str") + raise TypeError(f"username must be an instance of str, not {type(username)}.") md5hash = hashlib.md5() # noqa: S324 data = f"{username}:mongo:{password}" diff --git a/pymongo/asynchronous/auth_oidc.py b/pymongo/asynchronous/auth_oidc.py index f1c15045de..44ea2b01d1 100644 --- a/pymongo/asynchronous/auth_oidc.py +++ b/pymongo/asynchronous/auth_oidc.py @@ -213,7 +213,9 @@ def _get_access_token(self) -> Optional[str]: ) resp = cb.fetch(context) if not isinstance(resp, OIDCCallbackResult): - raise ValueError("Callback result must be of type OIDCCallbackResult") + raise ValueError( + f"Callback result must be of type OIDCCallbackResult, not {type(resp)}." + ) self.refresh_token = resp.refresh_token self.access_token = resp.access_token self.token_gen_id += 1 diff --git a/pymongo/asynchronous/client_session.py b/pymongo/asynchronous/client_session.py index d80495d804..7f8841d84f 100644 --- a/pymongo/asynchronous/client_session.py +++ b/pymongo/asynchronous/client_session.py @@ -310,7 +310,9 @@ def __init__( ) if max_commit_time_ms is not None: if not isinstance(max_commit_time_ms, int): - raise TypeError("max_commit_time_ms must be an integer or None") + raise TypeError( + f"max_commit_time_ms must be an integer or None, not {type(max_commit_time_ms)}." + ) @property def read_concern(self) -> Optional[ReadConcern]: @@ -902,7 +904,9 @@ def advance_cluster_time(self, cluster_time: Mapping[str, Any]) -> None: another `AsyncClientSession` instance. """ if not isinstance(cluster_time, _Mapping): - raise TypeError("cluster_time must be a subclass of collections.Mapping") + raise TypeError( + f"cluster_time must be a subclass of collections.Mapping, not {type(cluster_time)}." + ) if not isinstance(cluster_time.get("clusterTime"), Timestamp): raise ValueError("Invalid cluster_time") self._advance_cluster_time(cluster_time) @@ -923,7 +927,9 @@ def advance_operation_time(self, operation_time: Timestamp) -> None: another `AsyncClientSession` instance. """ if not isinstance(operation_time, Timestamp): - raise TypeError("operation_time must be an instance of bson.timestamp.Timestamp") + raise TypeError( + f"operation_time must be an instance of bson.timestamp.Timestamp, not {type(operation_time)}." + ) self._advance_operation_time(operation_time) def _process_response(self, reply: Mapping[str, Any]) -> None: diff --git a/pymongo/asynchronous/collection.py b/pymongo/asynchronous/collection.py index 9b73423627..8689e8bc0b 100644 --- a/pymongo/asynchronous/collection.py +++ b/pymongo/asynchronous/collection.py @@ -228,7 +228,7 @@ def __init__( read_concern or database.read_concern, ) if not isinstance(name, str): - raise TypeError("name must be an instance of str") + raise TypeError(f"name must be an instance of str, not {type(name)}.") from pymongo.asynchronous.database import AsyncDatabase if not isinstance(database, AsyncDatabase): @@ -2475,7 +2475,7 @@ async def _drop_index( name = helpers_shared._gen_index_name(index_or_name) if not isinstance(name, str): - raise TypeError("index_or_name must be an instance of str or list") + raise TypeError(f"index_or_name must be an instance of str or list, not {type(name)}.") cmd = {"dropIndexes": self._name, "index": name} cmd.update(kwargs) @@ -3078,7 +3078,7 @@ async def rename( """ if not isinstance(new_name, str): - raise TypeError("new_name must be an instance of str") + raise TypeError(f"new_name must be an instance of str, not {type(new_name)}.") if not new_name or ".." in new_name: raise InvalidName("collection names cannot be empty") @@ -3148,7 +3148,7 @@ async def distinct( """ if not isinstance(key, str): - raise TypeError("key must be an instance of str") + raise TypeError(f"key must be an instance of str, not {type(key)}.") cmd = {"distinct": self._name, "key": key} if filter is not None: if "query" in kwargs: @@ -3196,7 +3196,7 @@ async def _find_and_modify( common.validate_is_mapping("filter", filter) if not isinstance(return_document, bool): raise ValueError( - "return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER" + f"return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER, not {type(return_document)}." ) collation = validate_collation_or_none(kwargs.pop("collation", None)) cmd = {"findAndModify": self._name, "query": filter, "new": return_document} diff --git a/pymongo/asynchronous/command_cursor.py b/pymongo/asynchronous/command_cursor.py index 5a4559bd77..4b83de2c23 100644 --- a/pymongo/asynchronous/command_cursor.py +++ b/pymongo/asynchronous/command_cursor.py @@ -94,7 +94,9 @@ def __init__( self.batch_size(batch_size) if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: - raise TypeError("max_await_time_ms must be an integer or None") + raise TypeError( + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + ) def __del__(self) -> None: self._die_no_lock() @@ -115,7 +117,7 @@ def batch_size(self, batch_size: int) -> AsyncCommandCursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError("batch_size must be an integer") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") if batch_size < 0: raise ValueError("batch_size must be >= 0") diff --git a/pymongo/asynchronous/cursor.py b/pymongo/asynchronous/cursor.py index 8193e53282..d578cbefe3 100644 --- a/pymongo/asynchronous/cursor.py +++ b/pymongo/asynchronous/cursor.py @@ -146,9 +146,9 @@ def __init__( spec: Mapping[str, Any] = filter or {} validate_is_mapping("filter", spec) if not isinstance(skip, int): - raise TypeError("skip must be an instance of int") + raise TypeError(f"skip must be an instance of int, not {type(skip)}.") if not isinstance(limit, int): - raise TypeError("limit must be an instance of int") + raise TypeError(f"limit must be an instance of int, not {type(limit)}.") validate_boolean("no_cursor_timeout", no_cursor_timeout) if no_cursor_timeout and not self._explicit_session: warnings.warn( @@ -171,7 +171,7 @@ def __init__( validate_boolean("allow_partial_results", allow_partial_results) validate_boolean("oplog_replay", oplog_replay) if not isinstance(batch_size, int): - raise TypeError("batch_size must be an integer") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") if batch_size < 0: raise ValueError("batch_size must be >= 0") # Only set if allow_disk_use is provided by the user, else None. @@ -388,7 +388,7 @@ async def add_option(self, mask: int) -> AsyncCursor[_DocumentType]: cursor.add_option(2) """ if not isinstance(mask, int): - raise TypeError("mask must be an int") + raise TypeError(f"mask must be an int, not {type(mask)}.") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -408,7 +408,7 @@ def remove_option(self, mask: int) -> AsyncCursor[_DocumentType]: cursor.remove_option(2) """ if not isinstance(mask, int): - raise TypeError("mask must be an int") + raise TypeError(f"mask must be an int, not {type(mask)}.") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -432,7 +432,7 @@ def allow_disk_use(self, allow_disk_use: bool) -> AsyncCursor[_DocumentType]: .. versionadded:: 3.11 """ if not isinstance(allow_disk_use, bool): - raise TypeError("allow_disk_use must be a bool") + raise TypeError(f"allow_disk_use must be a bool, not {type(allow_disk_use)}.") self._check_okay_to_chain() self._allow_disk_use = allow_disk_use @@ -451,7 +451,7 @@ def limit(self, limit: int) -> AsyncCursor[_DocumentType]: .. seealso:: The MongoDB documentation on `limit `_. """ if not isinstance(limit, int): - raise TypeError("limit must be an integer") + raise TypeError(f"limit must be an integer, not {type(limit)}.") if self._exhaust: raise InvalidOperation("Can't use limit and exhaust together.") self._check_okay_to_chain() @@ -479,7 +479,7 @@ def batch_size(self, batch_size: int) -> AsyncCursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError("batch_size must be an integer") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") if batch_size < 0: raise ValueError("batch_size must be >= 0") self._check_okay_to_chain() @@ -499,7 +499,7 @@ def skip(self, skip: int) -> AsyncCursor[_DocumentType]: :param skip: the number of results to skip """ if not isinstance(skip, int): - raise TypeError("skip must be an integer") + raise TypeError(f"skip must be an integer, not {type(skip)}.") if skip < 0: raise ValueError("skip must be >= 0") self._check_okay_to_chain() @@ -520,7 +520,7 @@ def max_time_ms(self, max_time_ms: Optional[int]) -> AsyncCursor[_DocumentType]: :param max_time_ms: the time limit after which the operation is aborted """ if not isinstance(max_time_ms, int) and max_time_ms is not None: - raise TypeError("max_time_ms must be an integer or None") + raise TypeError(f"max_time_ms must be an integer or None, not {type(max_time_ms)}.") self._check_okay_to_chain() self._max_time_ms = max_time_ms @@ -543,7 +543,9 @@ def max_await_time_ms(self, max_await_time_ms: Optional[int]) -> AsyncCursor[_Do .. versionadded:: 3.2 """ if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: - raise TypeError("max_await_time_ms must be an integer or None") + raise TypeError( + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + ) self._check_okay_to_chain() # Ignore max_await_time_ms if not tailable or await_data is False. @@ -679,7 +681,7 @@ def max(self, spec: _Sort) -> AsyncCursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError("spec must be an instance of list or tuple") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") self._check_okay_to_chain() self._max = dict(spec) @@ -701,7 +703,7 @@ def min(self, spec: _Sort) -> AsyncCursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError("spec must be an instance of list or tuple") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") self._check_okay_to_chain() self._min = dict(spec) diff --git a/pymongo/asynchronous/database.py b/pymongo/asynchronous/database.py index 98a0a6ff3b..ff8c599dd6 100644 --- a/pymongo/asynchronous/database.py +++ b/pymongo/asynchronous/database.py @@ -122,7 +122,7 @@ def __init__( from pymongo.asynchronous.mongo_client import AsyncMongoClient if not isinstance(name, str): - raise TypeError("name must be an instance of str") + raise TypeError(f"name must be an instance of str, not {type(name)}.") if not isinstance(client, AsyncMongoClient): # This is for compatibility with mocked and subclassed types, such as in Motor. @@ -1310,7 +1310,7 @@ async def drop_collection( name = name.name if not isinstance(name, str): - raise TypeError("name_or_collection must be an instance of str") + raise TypeError(f"name_or_collection must be an instance of str, not {type(name)}.") encrypted_fields = await self._get_encrypted_fields( {"encryptedFields": encrypted_fields}, name, @@ -1374,7 +1374,9 @@ async def validate_collection( name = name.name if not isinstance(name, str): - raise TypeError("name_or_collection must be an instance of str or AsyncCollection") + raise TypeError( + f"name_or_collection must be an instance of str or AsyncCollection, not {type(name)}." + ) cmd = {"validate": name, "scandata": scandata, "full": full} if comment is not None: cmd["comment"] = comment diff --git a/pymongo/asynchronous/encryption.py b/pymongo/asynchronous/encryption.py index 98ab68527c..f71875538b 100644 --- a/pymongo/asynchronous/encryption.py +++ b/pymongo/asynchronous/encryption.py @@ -322,7 +322,9 @@ async def insert_data_key(self, data_key: bytes) -> Binary: raw_doc = RawBSONDocument(data_key, _KEY_VAULT_OPTS) data_key_id = raw_doc.get("_id") if not isinstance(data_key_id, Binary) or data_key_id.subtype != UUID_SUBTYPE: - raise TypeError("data_key _id must be Binary with a UUID subtype") + raise TypeError( + f"data_key _id must be Binary with a UUID subtype, not {type(data_key_id)}." + ) assert self.key_vault_coll is not None await self.key_vault_coll.insert_one(raw_doc) @@ -644,7 +646,9 @@ def __init__( ) if not isinstance(codec_options, CodecOptions): - raise TypeError("codec_options must be an instance of bson.codec_options.CodecOptions") + raise TypeError( + f"codec_options must be an instance of bson.codec_options.CodecOptions, not {type(codec_options)}." + ) if not isinstance(key_vault_client, AsyncMongoClient): # This is for compatibility with mocked and subclassed types, such as in Motor. diff --git a/pymongo/asynchronous/mongo_client.py b/pymongo/asynchronous/mongo_client.py index 1600e50628..b2c44d4215 100644 --- a/pymongo/asynchronous/mongo_client.py +++ b/pymongo/asynchronous/mongo_client.py @@ -750,7 +750,7 @@ def __init__( if port is None: port = self.PORT if not isinstance(port, int): - raise TypeError("port must be an instance of int") + raise TypeError(f"port must be an instance of int, not {type(port)}.") # _pool_class, _monitor_class, and _condition_class are for deep # customization of PyMongo, e.g. Motor. @@ -1971,7 +1971,7 @@ async def _close_cursor_now( The cursor is closed synchronously on the current thread. """ if not isinstance(cursor_id, int): - raise TypeError("cursor_id must be an instance of int") + raise TypeError(f"cursor_id must be an instance of int, not {type(cursor_id)}.") try: if conn_mgr: @@ -2093,7 +2093,9 @@ async def _tmp_session( """If provided session is None, lend a temporary session.""" if session is not None: if not isinstance(session, client_session.AsyncClientSession): - raise ValueError("'session' argument must be an AsyncClientSession or None.") + raise ValueError( + f"'session' argument must be an AsyncClientSession or None, not {type(session)}." + ) # Don't call end_session. yield session return @@ -2247,7 +2249,9 @@ async def drop_database( name = name.name if not isinstance(name, str): - raise TypeError("name_or_database must be an instance of str or a AsyncDatabase") + raise TypeError( + f"name_or_database must be an instance of str or a AsyncDatabase, not {type(name)}." + ) async with await self._conn_for_writes(session, operation=_Op.DROP_DATABASE) as conn: await self[name]._command( diff --git a/pymongo/common.py b/pymongo/common.py index b442da6a3e..3ed0005ce2 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -202,7 +202,7 @@ def validate_integer(option: str, value: Any) -> int: return int(value) except ValueError: raise ValueError(f"The value of {option} must be an integer") from None - raise TypeError(f"Wrong type for {option}, value must be an integer") + raise TypeError(f"Wrong type for {option}, value must be an integer, not {type(value)}.") def validate_positive_integer(option: str, value: Any) -> int: @@ -250,7 +250,9 @@ def validate_string(option: str, value: Any) -> str: """Validates that 'value' is an instance of `str`.""" if isinstance(value, str): return value - raise TypeError(f"Wrong type for {option}, value must be an instance of str") + raise TypeError( + f"Wrong type for {option}, value must be an instance of str, not {type(value)}." + ) def validate_string_or_none(option: str, value: Any) -> Optional[str]: @@ -269,7 +271,9 @@ def validate_int_or_basestring(option: str, value: Any) -> Union[int, str]: return int(value) except ValueError: return value - raise TypeError(f"Wrong type for {option}, value must be an integer or a string") + raise TypeError( + f"Wrong type for {option}, value must be an integer or a string, not {type(value)}." + ) def validate_non_negative_int_or_basestring(option: Any, value: Any) -> Union[int, str]: @@ -282,7 +286,9 @@ def validate_non_negative_int_or_basestring(option: Any, value: Any) -> Union[in except ValueError: return value return validate_non_negative_integer(option, val) - raise TypeError(f"Wrong type for {option}, value must be an non negative integer or a string") + raise TypeError( + f"Wrong type for {option}, value must be an non negative integer or a string, not {type(value)}." + ) def validate_positive_float(option: str, value: Any) -> float: @@ -441,7 +447,9 @@ def validate_auth_mechanism_properties(option: str, value: Any) -> dict[str, Uni props: dict[str, Any] = {} if not isinstance(value, str): if not isinstance(value, dict): - raise ValueError("Auth mechanism properties must be given as a string or a dictionary") + raise ValueError( + f"Auth mechanism properties must be given as a string or a dictionary, not {type(value)}." + ) for key, value in value.items(): # noqa: B020 if isinstance(value, str): props[key] = value @@ -453,7 +461,7 @@ def validate_auth_mechanism_properties(option: str, value: Any) -> dict[str, Uni from pymongo.auth_oidc_shared import OIDCCallback if not isinstance(value, OIDCCallback): - raise ValueError("callback must be an OIDCCallback object") + raise ValueError(f"callback must be an OIDCCallback object, not {type(value)}.") props[key] = value else: raise ValueError(f"Invalid type for auth mechanism property {key}, {type(value)}") @@ -520,7 +528,7 @@ def validate_type_registry(option: Any, value: Any) -> Optional[TypeRegistry]: def validate_list(option: str, value: Any) -> list: """Validates that 'value' is a list.""" if not isinstance(value, list): - raise TypeError(f"{option} must be a list") + raise TypeError(f"{option} must be a list, not {type(value)}.") return value @@ -587,7 +595,7 @@ def validate_server_api_or_none(option: Any, value: Any) -> Optional[ServerApi]: if value is None: return value if not isinstance(value, ServerApi): - raise TypeError(f"{option} must be an instance of ServerApi") + raise TypeError(f"{option} must be an instance of ServerApi, not {type(value)}.") return value @@ -596,7 +604,7 @@ def validate_is_callable_or_none(option: Any, value: Any) -> Optional[Callable]: if value is None: return value if not callable(value): - raise ValueError(f"{option} must be a callable") + raise ValueError(f"{option} must be a callable, not {type(value)}.") return value @@ -651,7 +659,7 @@ def validate_auto_encryption_opts_or_none(option: Any, value: Any) -> Optional[A from pymongo.encryption_options import AutoEncryptionOpts if not isinstance(value, AutoEncryptionOpts): - raise TypeError(f"{option} must be an instance of AutoEncryptionOpts") + raise TypeError(f"{option} must be an instance of AutoEncryptionOpts, not {type(value)}.") return value @@ -668,7 +676,9 @@ def validate_datetime_conversion(option: Any, value: Any) -> Optional[DatetimeCo elif isinstance(value, int): return DatetimeConversion(value) - raise TypeError(f"{option} must be a str or int representing DatetimeConversion") + raise TypeError( + f"{option} must be a str or int representing DatetimeConversion, not {type(value)}." + ) def validate_server_monitoring_mode(option: str, value: str) -> str: @@ -928,12 +938,14 @@ def __init__( if not isinstance(write_concern, WriteConcern): raise TypeError( - "write_concern must be an instance of pymongo.write_concern.WriteConcern" + f"write_concern must be an instance of pymongo.write_concern.WriteConcern, not {type(write_concern)}." ) self._write_concern = write_concern if not isinstance(read_concern, ReadConcern): - raise TypeError("read_concern must be an instance of pymongo.read_concern.ReadConcern") + raise TypeError( + f"read_concern must be an instance of pymongo.read_concern.ReadConcern, not {type(read_concern)}." + ) self._read_concern = read_concern @property diff --git a/pymongo/driver_info.py b/pymongo/driver_info.py index 5ca3f952cd..93c58ad2a9 100644 --- a/pymongo/driver_info.py +++ b/pymongo/driver_info.py @@ -39,7 +39,7 @@ def __new__( for key, value in self._asdict().items(): if value is not None and not isinstance(value, str): raise TypeError( - f"Wrong type for DriverInfo {key} option, value must be an instance of str" + f"Wrong type for DriverInfo {key} option, value must be an instance of str, not {type(value)}." ) return self diff --git a/pymongo/encryption_options.py b/pymongo/encryption_options.py index ee749e7ac1..d8a3e3d1b4 100644 --- a/pymongo/encryption_options.py +++ b/pymongo/encryption_options.py @@ -225,7 +225,9 @@ def __init__( mongocryptd_spawn_args = ["--idleShutdownTimeoutSecs=60"] self._mongocryptd_spawn_args = mongocryptd_spawn_args if not isinstance(self._mongocryptd_spawn_args, list): - raise TypeError("mongocryptd_spawn_args must be a list") + raise TypeError( + f"mongocryptd_spawn_args must be a list, not {type(self._mongocryptd_spawn_args)}." + ) if not any("idleShutdownTimeoutSecs" in s for s in self._mongocryptd_spawn_args): self._mongocryptd_spawn_args.append("--idleShutdownTimeoutSecs=60") # Maps KMS provider name to a SSLContext. diff --git a/pymongo/helpers_shared.py b/pymongo/helpers_shared.py index 83ea2ddf78..54ea332447 100644 --- a/pymongo/helpers_shared.py +++ b/pymongo/helpers_shared.py @@ -122,7 +122,7 @@ def _index_list( """ if direction is not None: if not isinstance(key_or_list, str): - raise TypeError("Expected a string and a direction") + raise TypeError(f"Expected a string and a direction, not {type(key_or_list)}.") return [(key_or_list, direction)] else: if isinstance(key_or_list, str): @@ -132,7 +132,9 @@ def _index_list( elif isinstance(key_or_list, abc.Mapping): return list(key_or_list.items()) elif not isinstance(key_or_list, (list, tuple)): - raise TypeError("if no direction is specified, key_or_list must be an instance of list") + raise TypeError( + f"if no direction is specified, key_or_list must be an instance of list, not {type(key_or_list)}." + ) values: list[tuple[str, int]] = [] for item in key_or_list: if isinstance(item, str): @@ -172,11 +174,12 @@ def _index_document(index_list: _IndexList) -> dict[str, Any]: def _validate_index_key_pair(key: Any, value: Any) -> None: if not isinstance(key, str): - raise TypeError("first item in each key pair must be an instance of str") + raise TypeError(f"first item in each key pair must be an instance of str, not {type(key)}.") if not isinstance(value, (str, int, abc.Mapping)): raise TypeError( "second item in each key pair must be 1, -1, " "'2d', or another valid MongoDB index specifier." + f", not {type(value)}." ) diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index 96f88597d2..aab8e27d04 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -472,14 +472,15 @@ def _validate_event_listeners( ) -> Sequence[_EventListeners]: """Validate event listeners""" if not isinstance(listeners, abc.Sequence): - raise TypeError(f"{option} must be a list or tuple") + raise TypeError(f"{option} must be a list or tuple, not {type(listeners)}.") for listener in listeners: if not isinstance(listener, _EventListener): raise TypeError( f"Listeners for {option} must be either a " "CommandListener, ServerHeartbeatListener, " "ServerListener, TopologyListener, or " - "ConnectionPoolListener." + "ConnectionPoolListener," + f"not {type(listener)}." ) return listeners @@ -496,7 +497,8 @@ def register(listener: _EventListener) -> None: f"Listeners for {listener} must be either a " "CommandListener, ServerHeartbeatListener, " "ServerListener, TopologyListener, or " - "ConnectionPoolListener." + "ConnectionPoolListener," + f"not {type(listener)}." ) if isinstance(listener, CommandListener): _LISTENERS.command_listeners.append(listener) diff --git a/pymongo/read_concern.py b/pymongo/read_concern.py index fa2f4a318a..89f4430ef6 100644 --- a/pymongo/read_concern.py +++ b/pymongo/read_concern.py @@ -38,7 +38,7 @@ def __init__(self, level: Optional[str] = None) -> None: if level is None or isinstance(level, str): self.__level = level else: - raise TypeError("level must be a string or None.") + raise TypeError(f"level must be a string or None, not {type(level)}.") @property def level(self) -> Optional[str]: diff --git a/pymongo/write_concern.py b/pymongo/write_concern.py index 67c9549897..90a88a5d83 100644 --- a/pymongo/write_concern.py +++ b/pymongo/write_concern.py @@ -74,7 +74,7 @@ def __init__( if wtimeout is not None: if not isinstance(wtimeout, int): - raise TypeError("wtimeout must be an integer") + raise TypeError(f"wtimeout must be an integer, not {type(wtimeout)}.") if wtimeout < 0: raise ValueError("wtimeout cannot be less than 0") self.__document["wtimeout"] = wtimeout @@ -98,7 +98,7 @@ def __init__( raise ValueError("w cannot be less than 0") self.__acknowledged = w > 0 elif not isinstance(w, str): - raise TypeError("w must be an integer or string") + raise TypeError(f"w must be an integer or string, not {type(w)}.") self.__document["w"] = w self.__server_default = not self.__document From 712bf92626f5105e90a65ec4b751fc4e58cf33f1 Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Wed, 29 Jan 2025 09:43:00 -0800 Subject: [PATCH 2/4] run pre-commit --- gridfs/synchronous/grid_file.py | 12 ++++++++---- pymongo/synchronous/auth.py | 2 +- pymongo/synchronous/auth_oidc.py | 4 +++- pymongo/synchronous/client_session.py | 12 +++++++++--- pymongo/synchronous/collection.py | 10 +++++----- pymongo/synchronous/command_cursor.py | 6 ++++-- pymongo/synchronous/cursor.py | 28 ++++++++++++++------------- pymongo/synchronous/database.py | 8 +++++--- pymongo/synchronous/encryption.py | 8 ++++++-- pymongo/synchronous/mongo_client.py | 12 ++++++++---- 10 files changed, 64 insertions(+), 38 deletions(-) diff --git a/gridfs/synchronous/grid_file.py b/gridfs/synchronous/grid_file.py index 655f05f57a..0ec3a28bed 100644 --- a/gridfs/synchronous/grid_file.py +++ b/gridfs/synchronous/grid_file.py @@ -100,7 +100,7 @@ def __init__(self, database: Database, collection: str = "fs"): .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(database, Database): - raise TypeError("database must be an instance of Database") + raise TypeError(f"database must be an instance of Database, not {type(database)}.") database = _clear_entity_type_registry(database) @@ -501,7 +501,7 @@ def __init__( .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(db, Database): - raise TypeError("database must be an instance of Database") + raise TypeError(f"database must be an instance of Database, not {type(db)}.") db = _clear_entity_type_registry(db) @@ -1076,7 +1076,9 @@ def __init__( :attr:`~pymongo.collection.Collection.write_concern` """ if not isinstance(root_collection, Collection): - raise TypeError("root_collection must be an instance of Collection") + raise TypeError( + f"root_collection must be an instance of Collection, not {type(root_collection)}." + ) if not root_collection.write_concern.acknowledged: raise ConfigurationError("root_collection must use acknowledged write_concern") @@ -1426,7 +1428,9 @@ def __init__( from the server. Metadata is fetched when first needed. """ if not isinstance(root_collection, Collection): - raise TypeError("root_collection must be an instance of Collection") + raise TypeError( + f"root_collection must be an instance of Collection, not {type(root_collection)}." + ) _disallow_transactions(session) root_collection = _clear_entity_type_registry(root_collection) diff --git a/pymongo/synchronous/auth.py b/pymongo/synchronous/auth.py index 56860eff3b..a1b82a4dab 100644 --- a/pymongo/synchronous/auth.py +++ b/pymongo/synchronous/auth.py @@ -158,7 +158,7 @@ def _password_digest(username: str, password: str) -> str: if len(password) == 0: raise ValueError("password can't be empty") if not isinstance(username, str): - raise TypeError("username must be an instance of str") + raise TypeError(f"username must be an instance of str, not {type(username)}.") md5hash = hashlib.md5() # noqa: S324 data = f"{username}:mongo:{password}" diff --git a/pymongo/synchronous/auth_oidc.py b/pymongo/synchronous/auth_oidc.py index 5a8967d96b..e64a844f7b 100644 --- a/pymongo/synchronous/auth_oidc.py +++ b/pymongo/synchronous/auth_oidc.py @@ -213,7 +213,9 @@ def _get_access_token(self) -> Optional[str]: ) resp = cb.fetch(context) if not isinstance(resp, OIDCCallbackResult): - raise ValueError("Callback result must be of type OIDCCallbackResult") + raise ValueError( + f"Callback result must be of type OIDCCallbackResult, not {type(resp)}." + ) self.refresh_token = resp.refresh_token self.access_token = resp.access_token self.token_gen_id += 1 diff --git a/pymongo/synchronous/client_session.py b/pymongo/synchronous/client_session.py index f1d680fc0a..7d8946718d 100644 --- a/pymongo/synchronous/client_session.py +++ b/pymongo/synchronous/client_session.py @@ -309,7 +309,9 @@ def __init__( ) if max_commit_time_ms is not None: if not isinstance(max_commit_time_ms, int): - raise TypeError("max_commit_time_ms must be an integer or None") + raise TypeError( + f"max_commit_time_ms must be an integer or None, not {type(max_commit_time_ms)}." + ) @property def read_concern(self) -> Optional[ReadConcern]: @@ -897,7 +899,9 @@ def advance_cluster_time(self, cluster_time: Mapping[str, Any]) -> None: another `ClientSession` instance. """ if not isinstance(cluster_time, _Mapping): - raise TypeError("cluster_time must be a subclass of collections.Mapping") + raise TypeError( + f"cluster_time must be a subclass of collections.Mapping, not {type(cluster_time)}." + ) if not isinstance(cluster_time.get("clusterTime"), Timestamp): raise ValueError("Invalid cluster_time") self._advance_cluster_time(cluster_time) @@ -918,7 +922,9 @@ def advance_operation_time(self, operation_time: Timestamp) -> None: another `ClientSession` instance. """ if not isinstance(operation_time, Timestamp): - raise TypeError("operation_time must be an instance of bson.timestamp.Timestamp") + raise TypeError( + f"operation_time must be an instance of bson.timestamp.Timestamp, not {type(operation_time)}." + ) self._advance_operation_time(operation_time) def _process_response(self, reply: Mapping[str, Any]) -> None: diff --git a/pymongo/synchronous/collection.py b/pymongo/synchronous/collection.py index 6edfddc9a9..34f517e96d 100644 --- a/pymongo/synchronous/collection.py +++ b/pymongo/synchronous/collection.py @@ -231,7 +231,7 @@ def __init__( read_concern or database.read_concern, ) if not isinstance(name, str): - raise TypeError("name must be an instance of str") + raise TypeError(f"name must be an instance of str, not {type(name)}.") from pymongo.synchronous.database import Database if not isinstance(database, Database): @@ -2472,7 +2472,7 @@ def _drop_index( name = helpers_shared._gen_index_name(index_or_name) if not isinstance(name, str): - raise TypeError("index_or_name must be an instance of str or list") + raise TypeError(f"index_or_name must be an instance of str or list, not {type(name)}.") cmd = {"dropIndexes": self._name, "index": name} cmd.update(kwargs) @@ -3071,7 +3071,7 @@ def rename( """ if not isinstance(new_name, str): - raise TypeError("new_name must be an instance of str") + raise TypeError(f"new_name must be an instance of str, not {type(new_name)}.") if not new_name or ".." in new_name: raise InvalidName("collection names cannot be empty") @@ -3141,7 +3141,7 @@ def distinct( """ if not isinstance(key, str): - raise TypeError("key must be an instance of str") + raise TypeError(f"key must be an instance of str, not {type(key)}.") cmd = {"distinct": self._name, "key": key} if filter is not None: if "query" in kwargs: @@ -3189,7 +3189,7 @@ def _find_and_modify( common.validate_is_mapping("filter", filter) if not isinstance(return_document, bool): raise ValueError( - "return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER" + f"return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER, not {type(return_document)}." ) collation = validate_collation_or_none(kwargs.pop("collation", None)) cmd = {"findAndModify": self._name, "query": filter, "new": return_document} diff --git a/pymongo/synchronous/command_cursor.py b/pymongo/synchronous/command_cursor.py index 3a4372856a..50fa4c9180 100644 --- a/pymongo/synchronous/command_cursor.py +++ b/pymongo/synchronous/command_cursor.py @@ -94,7 +94,9 @@ def __init__( self.batch_size(batch_size) if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: - raise TypeError("max_await_time_ms must be an integer or None") + raise TypeError( + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + ) def __del__(self) -> None: self._die_no_lock() @@ -115,7 +117,7 @@ def batch_size(self, batch_size: int) -> CommandCursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError("batch_size must be an integer") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") if batch_size < 0: raise ValueError("batch_size must be >= 0") diff --git a/pymongo/synchronous/cursor.py b/pymongo/synchronous/cursor.py index b35098a327..cc66b61d32 100644 --- a/pymongo/synchronous/cursor.py +++ b/pymongo/synchronous/cursor.py @@ -146,9 +146,9 @@ def __init__( spec: Mapping[str, Any] = filter or {} validate_is_mapping("filter", spec) if not isinstance(skip, int): - raise TypeError("skip must be an instance of int") + raise TypeError(f"skip must be an instance of int, not {type(skip)}.") if not isinstance(limit, int): - raise TypeError("limit must be an instance of int") + raise TypeError(f"limit must be an instance of int, not {type(limit)}.") validate_boolean("no_cursor_timeout", no_cursor_timeout) if no_cursor_timeout and not self._explicit_session: warnings.warn( @@ -171,7 +171,7 @@ def __init__( validate_boolean("allow_partial_results", allow_partial_results) validate_boolean("oplog_replay", oplog_replay) if not isinstance(batch_size, int): - raise TypeError("batch_size must be an integer") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") if batch_size < 0: raise ValueError("batch_size must be >= 0") # Only set if allow_disk_use is provided by the user, else None. @@ -388,7 +388,7 @@ def add_option(self, mask: int) -> Cursor[_DocumentType]: cursor.add_option(2) """ if not isinstance(mask, int): - raise TypeError("mask must be an int") + raise TypeError(f"mask must be an int, not {type(mask)}.") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -408,7 +408,7 @@ def remove_option(self, mask: int) -> Cursor[_DocumentType]: cursor.remove_option(2) """ if not isinstance(mask, int): - raise TypeError("mask must be an int") + raise TypeError(f"mask must be an int, not {type(mask)}.") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -432,7 +432,7 @@ def allow_disk_use(self, allow_disk_use: bool) -> Cursor[_DocumentType]: .. versionadded:: 3.11 """ if not isinstance(allow_disk_use, bool): - raise TypeError("allow_disk_use must be a bool") + raise TypeError(f"allow_disk_use must be a bool, not {type(allow_disk_use)}.") self._check_okay_to_chain() self._allow_disk_use = allow_disk_use @@ -451,7 +451,7 @@ def limit(self, limit: int) -> Cursor[_DocumentType]: .. seealso:: The MongoDB documentation on `limit `_. """ if not isinstance(limit, int): - raise TypeError("limit must be an integer") + raise TypeError(f"limit must be an integer, not {type(limit)}.") if self._exhaust: raise InvalidOperation("Can't use limit and exhaust together.") self._check_okay_to_chain() @@ -479,7 +479,7 @@ def batch_size(self, batch_size: int) -> Cursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError("batch_size must be an integer") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") if batch_size < 0: raise ValueError("batch_size must be >= 0") self._check_okay_to_chain() @@ -499,7 +499,7 @@ def skip(self, skip: int) -> Cursor[_DocumentType]: :param skip: the number of results to skip """ if not isinstance(skip, int): - raise TypeError("skip must be an integer") + raise TypeError(f"skip must be an integer, not {type(skip)}.") if skip < 0: raise ValueError("skip must be >= 0") self._check_okay_to_chain() @@ -520,7 +520,7 @@ def max_time_ms(self, max_time_ms: Optional[int]) -> Cursor[_DocumentType]: :param max_time_ms: the time limit after which the operation is aborted """ if not isinstance(max_time_ms, int) and max_time_ms is not None: - raise TypeError("max_time_ms must be an integer or None") + raise TypeError(f"max_time_ms must be an integer or None, not {type(max_time_ms)}.") self._check_okay_to_chain() self._max_time_ms = max_time_ms @@ -543,7 +543,9 @@ def max_await_time_ms(self, max_await_time_ms: Optional[int]) -> Cursor[_Documen .. versionadded:: 3.2 """ if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: - raise TypeError("max_await_time_ms must be an integer or None") + raise TypeError( + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + ) self._check_okay_to_chain() # Ignore max_await_time_ms if not tailable or await_data is False. @@ -677,7 +679,7 @@ def max(self, spec: _Sort) -> Cursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError("spec must be an instance of list or tuple") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") self._check_okay_to_chain() self._max = dict(spec) @@ -699,7 +701,7 @@ def min(self, spec: _Sort) -> Cursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError("spec must be an instance of list or tuple") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") self._check_okay_to_chain() self._min = dict(spec) diff --git a/pymongo/synchronous/database.py b/pymongo/synchronous/database.py index a0bef55343..2f53a2b8fc 100644 --- a/pymongo/synchronous/database.py +++ b/pymongo/synchronous/database.py @@ -122,7 +122,7 @@ def __init__( from pymongo.synchronous.mongo_client import MongoClient if not isinstance(name, str): - raise TypeError("name must be an instance of str") + raise TypeError(f"name must be an instance of str, not {type(name)}.") if not isinstance(client, MongoClient): # This is for compatibility with mocked and subclassed types, such as in Motor. @@ -1303,7 +1303,7 @@ def drop_collection( name = name.name if not isinstance(name, str): - raise TypeError("name_or_collection must be an instance of str") + raise TypeError(f"name_or_collection must be an instance of str, not {type(name)}.") encrypted_fields = self._get_encrypted_fields( {"encryptedFields": encrypted_fields}, name, @@ -1367,7 +1367,9 @@ def validate_collection( name = name.name if not isinstance(name, str): - raise TypeError("name_or_collection must be an instance of str or Collection") + raise TypeError( + f"name_or_collection must be an instance of str or Collection, not {type(name)}." + ) cmd = {"validate": name, "scandata": scandata, "full": full} if comment is not None: cmd["comment"] = comment diff --git a/pymongo/synchronous/encryption.py b/pymongo/synchronous/encryption.py index d41169861f..bd878d75a9 100644 --- a/pymongo/synchronous/encryption.py +++ b/pymongo/synchronous/encryption.py @@ -320,7 +320,9 @@ def insert_data_key(self, data_key: bytes) -> Binary: raw_doc = RawBSONDocument(data_key, _KEY_VAULT_OPTS) data_key_id = raw_doc.get("_id") if not isinstance(data_key_id, Binary) or data_key_id.subtype != UUID_SUBTYPE: - raise TypeError("data_key _id must be Binary with a UUID subtype") + raise TypeError( + f"data_key _id must be Binary with a UUID subtype, not {type(data_key_id)}." + ) assert self.key_vault_coll is not None self.key_vault_coll.insert_one(raw_doc) @@ -642,7 +644,9 @@ def __init__( ) if not isinstance(codec_options, CodecOptions): - raise TypeError("codec_options must be an instance of bson.codec_options.CodecOptions") + raise TypeError( + f"codec_options must be an instance of bson.codec_options.CodecOptions, not {type(codec_options)}." + ) if not isinstance(key_vault_client, MongoClient): # This is for compatibility with mocked and subclassed types, such as in Motor. diff --git a/pymongo/synchronous/mongo_client.py b/pymongo/synchronous/mongo_client.py index a694a58c1e..f486a47e5e 100644 --- a/pymongo/synchronous/mongo_client.py +++ b/pymongo/synchronous/mongo_client.py @@ -748,7 +748,7 @@ def __init__( if port is None: port = self.PORT if not isinstance(port, int): - raise TypeError("port must be an instance of int") + raise TypeError(f"port must be an instance of int, not {type(port)}.") # _pool_class, _monitor_class, and _condition_class are for deep # customization of PyMongo, e.g. Motor. @@ -1965,7 +1965,7 @@ def _close_cursor_now( The cursor is closed synchronously on the current thread. """ if not isinstance(cursor_id, int): - raise TypeError("cursor_id must be an instance of int") + raise TypeError(f"cursor_id must be an instance of int, not {type(cursor_id)}.") try: if conn_mgr: @@ -2087,7 +2087,9 @@ def _tmp_session( """If provided session is None, lend a temporary session.""" if session is not None: if not isinstance(session, client_session.ClientSession): - raise ValueError("'session' argument must be a ClientSession or None.") + raise ValueError( + f"'session' argument must be a ClientSession or None, not {type(session)}." + ) # Don't call end_session. yield session return @@ -2235,7 +2237,9 @@ def drop_database( name = name.name if not isinstance(name, str): - raise TypeError("name_or_database must be an instance of str or a Database") + raise TypeError( + f"name_or_database must be an instance of str or a Database, not {type(name)}." + ) with self._conn_for_writes(session, operation=_Op.DROP_DATABASE) as conn: self[name]._command( From 9127774b8a2aa18130de9ca136823b7213ad24ae Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 30 Jan 2025 14:54:37 -0800 Subject: [PATCH 3/4] remove periods from end of error messages --- bson/__init__.py | 2 +- bson/binary.py | 6 +++--- bson/code.py | 4 ++-- bson/codec_options.py | 6 +++--- bson/dbref.py | 4 ++-- bson/decimal128.py | 2 +- bson/timestamp.py | 4 ++-- gridfs/asynchronous/grid_file.py | 8 +++---- gridfs/synchronous/grid_file.py | 8 +++---- pymongo/__init__.py | 2 +- pymongo/_asyncio_lock.py | 2 +- pymongo/_azure_helpers.py | 2 +- pymongo/asynchronous/auth.py | 2 +- pymongo/asynchronous/auth_oidc.py | 2 +- pymongo/asynchronous/client_session.py | 6 +++--- pymongo/asynchronous/collection.py | 10 ++++----- pymongo/asynchronous/command_cursor.py | 4 ++-- pymongo/asynchronous/cursor.py | 26 +++++++++++----------- pymongo/asynchronous/database.py | 6 +++--- pymongo/asynchronous/encryption.py | 4 ++-- pymongo/asynchronous/mongo_client.py | 8 +++---- pymongo/auth_shared.py | 4 ++-- pymongo/collation.py | 2 +- pymongo/common.py | 30 +++++++++++++------------- pymongo/compression_support.py | 2 +- pymongo/driver_info.py | 2 +- pymongo/encryption_options.py | 2 +- pymongo/helpers_shared.py | 8 +++---- pymongo/monitoring.py | 6 +++--- pymongo/read_concern.py | 2 +- pymongo/ssl_support.py | 2 +- pymongo/synchronous/auth.py | 2 +- pymongo/synchronous/auth_oidc.py | 2 +- pymongo/synchronous/client_session.py | 6 +++--- pymongo/synchronous/collection.py | 10 ++++----- pymongo/synchronous/command_cursor.py | 4 ++-- pymongo/synchronous/cursor.py | 26 +++++++++++----------- pymongo/synchronous/database.py | 6 +++--- pymongo/synchronous/encryption.py | 4 ++-- pymongo/synchronous/mongo_client.py | 8 +++---- pymongo/uri_parser.py | 10 ++++----- pymongo/write_concern.py | 4 ++-- 42 files changed, 130 insertions(+), 130 deletions(-) diff --git a/bson/__init__.py b/bson/__init__.py index 69c227c70d..790ac06ef1 100644 --- a/bson/__init__.py +++ b/bson/__init__.py @@ -1386,7 +1386,7 @@ def is_valid(bson: bytes) -> bool: :param bson: the data to be validated """ if not isinstance(bson, bytes): - raise TypeError(f"BSON data must be an instance of a subclass of bytes, not {type(bson)}.") + raise TypeError(f"BSON data must be an instance of a subclass of bytes, not {type(bson)}") try: _bson_to_dict(bson, DEFAULT_CODEC_OPTIONS) diff --git a/bson/binary.py b/bson/binary.py index 59eb89caa4..aab59cccbc 100644 --- a/bson/binary.py +++ b/bson/binary.py @@ -290,7 +290,7 @@ def __new__( subtype: int = BINARY_SUBTYPE, ) -> Binary: if not isinstance(subtype, int): - raise TypeError(f"subtype must be an instance of int, not {type(subtype)}.") + raise TypeError(f"subtype must be an instance of int, not {type(subtype)}") if subtype >= 256 or subtype < 0: raise ValueError("subtype must be contained in [0, 256)") # Support any type that implements the buffer protocol. @@ -321,7 +321,7 @@ def from_uuid( .. versionadded:: 3.11 """ if not isinstance(uuid, UUID): - raise TypeError(f"uuid must be an instance of uuid.UUID, not {type(uuid)}.") + raise TypeError(f"uuid must be an instance of uuid.UUID, not {type(uuid)}") if uuid_representation not in ALL_UUID_REPRESENTATIONS: raise ValueError( @@ -470,7 +470,7 @@ def as_vector(self) -> BinaryVector: """ if self.subtype != VECTOR_SUBTYPE: - raise ValueError(f"Cannot decode subtype {self.subtype} as a vector.") + raise ValueError(f"Cannot decode subtype {self.subtype} as a vector") position = 0 dtype, padding = struct.unpack_from(" Code: if not isinstance(code, str): - raise TypeError(f"code must be an instance of str, not {type(code)}.") + raise TypeError(f"code must be an instance of str, not {type(code)}") self = str.__new__(cls, code) @@ -67,7 +67,7 @@ def __new__( if scope is not None: if not isinstance(scope, _Mapping): - raise TypeError(f"scope must be an instance of dict, not {type(scope)}.") + raise TypeError(f"scope must be an instance of dict, not {type(scope)}") if self.__scope is not None: self.__scope.update(scope) # type: ignore else: diff --git a/bson/codec_options.py b/bson/codec_options.py index 01b78c06e1..258a777a1b 100644 --- a/bson/codec_options.py +++ b/bson/codec_options.py @@ -402,12 +402,12 @@ def __new__( ) if not isinstance(unicode_decode_error_handler, str): raise ValueError( - f"unicode_decode_error_handler must be a string, not {type(unicode_decode_error_handler)}." + f"unicode_decode_error_handler must be a string, not {type(unicode_decode_error_handler)}" ) if tzinfo is not None: if not isinstance(tzinfo, datetime.tzinfo): raise TypeError( - f"tzinfo must be an instance of datetime.tzinfo, not {type(tzinfo)}." + f"tzinfo must be an instance of datetime.tzinfo, not {type(tzinfo)}" ) if not tz_aware: raise ValueError("cannot specify tzinfo without also setting tz_aware=True") @@ -416,7 +416,7 @@ def __new__( if not isinstance(type_registry, TypeRegistry): raise TypeError( - f"type_registry must be an instance of TypeRegistry, not {type(type_registry)}." + f"type_registry must be an instance of TypeRegistry, not {type(type_registry)}" ) return tuple.__new__( diff --git a/bson/dbref.py b/bson/dbref.py index a05f35f9de..40bdb73cff 100644 --- a/bson/dbref.py +++ b/bson/dbref.py @@ -56,9 +56,9 @@ def __init__( .. seealso:: The MongoDB documentation on `dbrefs `_. """ if not isinstance(collection, str): - raise TypeError(f"collection must be an instance of str, not {type(collection)}.") + raise TypeError(f"collection must be an instance of str, not {type(collection)}") if database is not None and not isinstance(database, str): - raise TypeError(f"database must be an instance of str, not {type(database)}.") + raise TypeError(f"database must be an instance of str, not {type(database)}") self.__collection = collection self.__id = id diff --git a/bson/decimal128.py b/bson/decimal128.py index c9e9daf732..92c054d878 100644 --- a/bson/decimal128.py +++ b/bson/decimal128.py @@ -277,7 +277,7 @@ def from_bid(cls: Type[Decimal128], value: bytes) -> Decimal128: point in Binary Integer Decimal (BID) format). """ if not isinstance(value, bytes): - raise TypeError(f"value must be an instance of bytes, not {type(value)}.") + raise TypeError(f"value must be an instance of bytes, not {type(value)}") if len(value) != 16: raise ValueError("value must be exactly 16 bytes") return cls((_UNPACK_64(value[8:])[0], _UNPACK_64(value[:8])[0])) # type: ignore diff --git a/bson/timestamp.py b/bson/timestamp.py index fdd89639d5..949bd7b36c 100644 --- a/bson/timestamp.py +++ b/bson/timestamp.py @@ -58,9 +58,9 @@ def __init__(self, time: Union[datetime.datetime, int], inc: int) -> None: time = time - offset time = int(calendar.timegm(time.timetuple())) if not isinstance(time, int): - raise TypeError(f"time must be an instance of int, not {type(time)}.") + raise TypeError(f"time must be an instance of int, not {type(time)}") if not isinstance(inc, int): - raise TypeError(f"inc must be an instance of int, not {type(inc)}.") + raise TypeError(f"inc must be an instance of int, not {type(inc)}") if not 0 <= time < UPPERBOUND: raise ValueError("time must be contained in [0, 2**32)") if not 0 <= inc < UPPERBOUND: diff --git a/gridfs/asynchronous/grid_file.py b/gridfs/asynchronous/grid_file.py index f0e2aa43e8..d15713c51b 100644 --- a/gridfs/asynchronous/grid_file.py +++ b/gridfs/asynchronous/grid_file.py @@ -100,7 +100,7 @@ def __init__(self, database: AsyncDatabase, collection: str = "fs"): .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(database, AsyncDatabase): - raise TypeError(f"database must be an instance of Database, not {type(database)}.") + raise TypeError(f"database must be an instance of Database, not {type(database)}") database = _clear_entity_type_registry(database) @@ -503,7 +503,7 @@ def __init__( .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(db, AsyncDatabase): - raise TypeError(f"database must be an instance of AsyncDatabase, not {type(db)}.") + raise TypeError(f"database must be an instance of AsyncDatabase, not {type(db)}") db = _clear_entity_type_registry(db) @@ -1083,7 +1083,7 @@ def __init__( """ if not isinstance(root_collection, AsyncCollection): raise TypeError( - f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}." + f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}" ) if not root_collection.write_concern.acknowledged: @@ -1439,7 +1439,7 @@ def __init__( """ if not isinstance(root_collection, AsyncCollection): raise TypeError( - f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}." + f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}" ) _disallow_transactions(session) diff --git a/gridfs/synchronous/grid_file.py b/gridfs/synchronous/grid_file.py index 0ec3a28bed..ea0b53cfb7 100644 --- a/gridfs/synchronous/grid_file.py +++ b/gridfs/synchronous/grid_file.py @@ -100,7 +100,7 @@ def __init__(self, database: Database, collection: str = "fs"): .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(database, Database): - raise TypeError(f"database must be an instance of Database, not {type(database)}.") + raise TypeError(f"database must be an instance of Database, not {type(database)}") database = _clear_entity_type_registry(database) @@ -501,7 +501,7 @@ def __init__( .. seealso:: The MongoDB documentation on `gridfs `_. """ if not isinstance(db, Database): - raise TypeError(f"database must be an instance of Database, not {type(db)}.") + raise TypeError(f"database must be an instance of Database, not {type(db)}") db = _clear_entity_type_registry(db) @@ -1077,7 +1077,7 @@ def __init__( """ if not isinstance(root_collection, Collection): raise TypeError( - f"root_collection must be an instance of Collection, not {type(root_collection)}." + f"root_collection must be an instance of Collection, not {type(root_collection)}" ) if not root_collection.write_concern.acknowledged: @@ -1429,7 +1429,7 @@ def __init__( """ if not isinstance(root_collection, Collection): raise TypeError( - f"root_collection must be an instance of Collection, not {type(root_collection)}." + f"root_collection must be an instance of Collection, not {type(root_collection)}" ) _disallow_transactions(session) diff --git a/pymongo/__init__.py b/pymongo/__init__.py index f2b6b52a6e..8d6def1606 100644 --- a/pymongo/__init__.py +++ b/pymongo/__init__.py @@ -160,7 +160,7 @@ def timeout(seconds: Optional[float]) -> ContextManager[None]: .. versionadded:: 4.2 """ if not isinstance(seconds, (int, float, type(None))): - raise TypeError(f"timeout must be None, an int, or a float, not {type(seconds)}.") + raise TypeError(f"timeout must be None, an int, or a float, not {type(seconds)}") if seconds and seconds < 0: raise ValueError("timeout cannot be negative") if seconds is not None: diff --git a/pymongo/_asyncio_lock.py b/pymongo/_asyncio_lock.py index 669b0f63a7..a9c409d486 100644 --- a/pymongo/_asyncio_lock.py +++ b/pymongo/_asyncio_lock.py @@ -160,7 +160,7 @@ def release(self) -> None: self._locked = False self._wake_up_first() else: - raise RuntimeError("Lock is not acquired.") + raise RuntimeError("Lock is not acquired") def _wake_up_first(self) -> None: """Ensure that the first waiter will wake up.""" diff --git a/pymongo/_azure_helpers.py b/pymongo/_azure_helpers.py index 704c561cd5..6e86ab5670 100644 --- a/pymongo/_azure_helpers.py +++ b/pymongo/_azure_helpers.py @@ -46,7 +46,7 @@ def _get_azure_response( try: data = json.loads(body) except Exception: - raise ValueError("Azure IMDS response must be in JSON format.") from None + raise ValueError("Azure IMDS response must be in JSON format") from None for key in ["access_token", "expires_in"]: if not data.get(key): diff --git a/pymongo/asynchronous/auth.py b/pymongo/asynchronous/auth.py index d844804453..8cc4edf19c 100644 --- a/pymongo/asynchronous/auth.py +++ b/pymongo/asynchronous/auth.py @@ -161,7 +161,7 @@ def _password_digest(username: str, password: str) -> str: if len(password) == 0: raise ValueError("password can't be empty") if not isinstance(username, str): - raise TypeError(f"username must be an instance of str, not {type(username)}.") + raise TypeError(f"username must be an instance of str, not {type(username)}") md5hash = hashlib.md5() # noqa: S324 data = f"{username}:mongo:{password}" diff --git a/pymongo/asynchronous/auth_oidc.py b/pymongo/asynchronous/auth_oidc.py index 44ea2b01d1..38346648c5 100644 --- a/pymongo/asynchronous/auth_oidc.py +++ b/pymongo/asynchronous/auth_oidc.py @@ -214,7 +214,7 @@ def _get_access_token(self) -> Optional[str]: resp = cb.fetch(context) if not isinstance(resp, OIDCCallbackResult): raise ValueError( - f"Callback result must be of type OIDCCallbackResult, not {type(resp)}." + f"Callback result must be of type OIDCCallbackResult, not {type(resp)}" ) self.refresh_token = resp.refresh_token self.access_token = resp.access_token diff --git a/pymongo/asynchronous/client_session.py b/pymongo/asynchronous/client_session.py index 7f8841d84f..4c5171a350 100644 --- a/pymongo/asynchronous/client_session.py +++ b/pymongo/asynchronous/client_session.py @@ -311,7 +311,7 @@ def __init__( if max_commit_time_ms is not None: if not isinstance(max_commit_time_ms, int): raise TypeError( - f"max_commit_time_ms must be an integer or None, not {type(max_commit_time_ms)}." + f"max_commit_time_ms must be an integer or None, not {type(max_commit_time_ms)}" ) @property @@ -905,7 +905,7 @@ def advance_cluster_time(self, cluster_time: Mapping[str, Any]) -> None: """ if not isinstance(cluster_time, _Mapping): raise TypeError( - f"cluster_time must be a subclass of collections.Mapping, not {type(cluster_time)}." + f"cluster_time must be a subclass of collections.Mapping, not {type(cluster_time)}" ) if not isinstance(cluster_time.get("clusterTime"), Timestamp): raise ValueError("Invalid cluster_time") @@ -928,7 +928,7 @@ def advance_operation_time(self, operation_time: Timestamp) -> None: """ if not isinstance(operation_time, Timestamp): raise TypeError( - f"operation_time must be an instance of bson.timestamp.Timestamp, not {type(operation_time)}." + f"operation_time must be an instance of bson.timestamp.Timestamp, not {type(operation_time)}" ) self._advance_operation_time(operation_time) diff --git a/pymongo/asynchronous/collection.py b/pymongo/asynchronous/collection.py index 8689e8bc0b..e83a391439 100644 --- a/pymongo/asynchronous/collection.py +++ b/pymongo/asynchronous/collection.py @@ -228,7 +228,7 @@ def __init__( read_concern or database.read_concern, ) if not isinstance(name, str): - raise TypeError(f"name must be an instance of str, not {type(name)}.") + raise TypeError(f"name must be an instance of str, not {type(name)}") from pymongo.asynchronous.database import AsyncDatabase if not isinstance(database, AsyncDatabase): @@ -2475,7 +2475,7 @@ async def _drop_index( name = helpers_shared._gen_index_name(index_or_name) if not isinstance(name, str): - raise TypeError(f"index_or_name must be an instance of str or list, not {type(name)}.") + raise TypeError(f"index_or_name must be an instance of str or list, not {type(name)}") cmd = {"dropIndexes": self._name, "index": name} cmd.update(kwargs) @@ -3078,7 +3078,7 @@ async def rename( """ if not isinstance(new_name, str): - raise TypeError(f"new_name must be an instance of str, not {type(new_name)}.") + raise TypeError(f"new_name must be an instance of str, not {type(new_name)}") if not new_name or ".." in new_name: raise InvalidName("collection names cannot be empty") @@ -3148,7 +3148,7 @@ async def distinct( """ if not isinstance(key, str): - raise TypeError(f"key must be an instance of str, not {type(key)}.") + raise TypeError(f"key must be an instance of str, not {type(key)}") cmd = {"distinct": self._name, "key": key} if filter is not None: if "query" in kwargs: @@ -3196,7 +3196,7 @@ async def _find_and_modify( common.validate_is_mapping("filter", filter) if not isinstance(return_document, bool): raise ValueError( - f"return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER, not {type(return_document)}." + f"return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER, not {type(return_document)}" ) collation = validate_collation_or_none(kwargs.pop("collation", None)) cmd = {"findAndModify": self._name, "query": filter, "new": return_document} diff --git a/pymongo/asynchronous/command_cursor.py b/pymongo/asynchronous/command_cursor.py index 4b83de2c23..353c5e91c2 100644 --- a/pymongo/asynchronous/command_cursor.py +++ b/pymongo/asynchronous/command_cursor.py @@ -95,7 +95,7 @@ def __init__( if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: raise TypeError( - f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}" ) def __del__(self) -> None: @@ -117,7 +117,7 @@ def batch_size(self, batch_size: int) -> AsyncCommandCursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}") if batch_size < 0: raise ValueError("batch_size must be >= 0") diff --git a/pymongo/asynchronous/cursor.py b/pymongo/asynchronous/cursor.py index d578cbefe3..9101197ce2 100644 --- a/pymongo/asynchronous/cursor.py +++ b/pymongo/asynchronous/cursor.py @@ -146,9 +146,9 @@ def __init__( spec: Mapping[str, Any] = filter or {} validate_is_mapping("filter", spec) if not isinstance(skip, int): - raise TypeError(f"skip must be an instance of int, not {type(skip)}.") + raise TypeError(f"skip must be an instance of int, not {type(skip)}") if not isinstance(limit, int): - raise TypeError(f"limit must be an instance of int, not {type(limit)}.") + raise TypeError(f"limit must be an instance of int, not {type(limit)}") validate_boolean("no_cursor_timeout", no_cursor_timeout) if no_cursor_timeout and not self._explicit_session: warnings.warn( @@ -171,7 +171,7 @@ def __init__( validate_boolean("allow_partial_results", allow_partial_results) validate_boolean("oplog_replay", oplog_replay) if not isinstance(batch_size, int): - raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}") if batch_size < 0: raise ValueError("batch_size must be >= 0") # Only set if allow_disk_use is provided by the user, else None. @@ -388,7 +388,7 @@ async def add_option(self, mask: int) -> AsyncCursor[_DocumentType]: cursor.add_option(2) """ if not isinstance(mask, int): - raise TypeError(f"mask must be an int, not {type(mask)}.") + raise TypeError(f"mask must be an int, not {type(mask)}") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -408,7 +408,7 @@ def remove_option(self, mask: int) -> AsyncCursor[_DocumentType]: cursor.remove_option(2) """ if not isinstance(mask, int): - raise TypeError(f"mask must be an int, not {type(mask)}.") + raise TypeError(f"mask must be an int, not {type(mask)}") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -432,7 +432,7 @@ def allow_disk_use(self, allow_disk_use: bool) -> AsyncCursor[_DocumentType]: .. versionadded:: 3.11 """ if not isinstance(allow_disk_use, bool): - raise TypeError(f"allow_disk_use must be a bool, not {type(allow_disk_use)}.") + raise TypeError(f"allow_disk_use must be a bool, not {type(allow_disk_use)}") self._check_okay_to_chain() self._allow_disk_use = allow_disk_use @@ -451,7 +451,7 @@ def limit(self, limit: int) -> AsyncCursor[_DocumentType]: .. seealso:: The MongoDB documentation on `limit `_. """ if not isinstance(limit, int): - raise TypeError(f"limit must be an integer, not {type(limit)}.") + raise TypeError(f"limit must be an integer, not {type(limit)}") if self._exhaust: raise InvalidOperation("Can't use limit and exhaust together.") self._check_okay_to_chain() @@ -479,7 +479,7 @@ def batch_size(self, batch_size: int) -> AsyncCursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}") if batch_size < 0: raise ValueError("batch_size must be >= 0") self._check_okay_to_chain() @@ -499,7 +499,7 @@ def skip(self, skip: int) -> AsyncCursor[_DocumentType]: :param skip: the number of results to skip """ if not isinstance(skip, int): - raise TypeError(f"skip must be an integer, not {type(skip)}.") + raise TypeError(f"skip must be an integer, not {type(skip)}") if skip < 0: raise ValueError("skip must be >= 0") self._check_okay_to_chain() @@ -520,7 +520,7 @@ def max_time_ms(self, max_time_ms: Optional[int]) -> AsyncCursor[_DocumentType]: :param max_time_ms: the time limit after which the operation is aborted """ if not isinstance(max_time_ms, int) and max_time_ms is not None: - raise TypeError(f"max_time_ms must be an integer or None, not {type(max_time_ms)}.") + raise TypeError(f"max_time_ms must be an integer or None, not {type(max_time_ms)}") self._check_okay_to_chain() self._max_time_ms = max_time_ms @@ -544,7 +544,7 @@ def max_await_time_ms(self, max_await_time_ms: Optional[int]) -> AsyncCursor[_Do """ if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: raise TypeError( - f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}" ) self._check_okay_to_chain() @@ -681,7 +681,7 @@ def max(self, spec: _Sort) -> AsyncCursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}") self._check_okay_to_chain() self._max = dict(spec) @@ -703,7 +703,7 @@ def min(self, spec: _Sort) -> AsyncCursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}") self._check_okay_to_chain() self._min = dict(spec) diff --git a/pymongo/asynchronous/database.py b/pymongo/asynchronous/database.py index ff8c599dd6..4aba9ab0e9 100644 --- a/pymongo/asynchronous/database.py +++ b/pymongo/asynchronous/database.py @@ -122,7 +122,7 @@ def __init__( from pymongo.asynchronous.mongo_client import AsyncMongoClient if not isinstance(name, str): - raise TypeError(f"name must be an instance of str, not {type(name)}.") + raise TypeError(f"name must be an instance of str, not {type(name)}") if not isinstance(client, AsyncMongoClient): # This is for compatibility with mocked and subclassed types, such as in Motor. @@ -1310,7 +1310,7 @@ async def drop_collection( name = name.name if not isinstance(name, str): - raise TypeError(f"name_or_collection must be an instance of str, not {type(name)}.") + raise TypeError(f"name_or_collection must be an instance of str, not {type(name)}") encrypted_fields = await self._get_encrypted_fields( {"encryptedFields": encrypted_fields}, name, @@ -1375,7 +1375,7 @@ async def validate_collection( if not isinstance(name, str): raise TypeError( - f"name_or_collection must be an instance of str or AsyncCollection, not {type(name)}." + f"name_or_collection must be an instance of str or AsyncCollection, not {type(name)}" ) cmd = {"validate": name, "scandata": scandata, "full": full} if comment is not None: diff --git a/pymongo/asynchronous/encryption.py b/pymongo/asynchronous/encryption.py index f71875538b..f777104cf5 100644 --- a/pymongo/asynchronous/encryption.py +++ b/pymongo/asynchronous/encryption.py @@ -323,7 +323,7 @@ async def insert_data_key(self, data_key: bytes) -> Binary: data_key_id = raw_doc.get("_id") if not isinstance(data_key_id, Binary) or data_key_id.subtype != UUID_SUBTYPE: raise TypeError( - f"data_key _id must be Binary with a UUID subtype, not {type(data_key_id)}." + f"data_key _id must be Binary with a UUID subtype, not {type(data_key_id)}" ) assert self.key_vault_coll is not None @@ -647,7 +647,7 @@ def __init__( if not isinstance(codec_options, CodecOptions): raise TypeError( - f"codec_options must be an instance of bson.codec_options.CodecOptions, not {type(codec_options)}." + f"codec_options must be an instance of bson.codec_options.CodecOptions, not {type(codec_options)}" ) if not isinstance(key_vault_client, AsyncMongoClient): diff --git a/pymongo/asynchronous/mongo_client.py b/pymongo/asynchronous/mongo_client.py index b2c44d4215..cf7de19c2f 100644 --- a/pymongo/asynchronous/mongo_client.py +++ b/pymongo/asynchronous/mongo_client.py @@ -750,7 +750,7 @@ def __init__( if port is None: port = self.PORT if not isinstance(port, int): - raise TypeError(f"port must be an instance of int, not {type(port)}.") + raise TypeError(f"port must be an instance of int, not {type(port)}") # _pool_class, _monitor_class, and _condition_class are for deep # customization of PyMongo, e.g. Motor. @@ -1971,7 +1971,7 @@ async def _close_cursor_now( The cursor is closed synchronously on the current thread. """ if not isinstance(cursor_id, int): - raise TypeError(f"cursor_id must be an instance of int, not {type(cursor_id)}.") + raise TypeError(f"cursor_id must be an instance of int, not {type(cursor_id)}") try: if conn_mgr: @@ -2094,7 +2094,7 @@ async def _tmp_session( if session is not None: if not isinstance(session, client_session.AsyncClientSession): raise ValueError( - f"'session' argument must be an AsyncClientSession or None, not {type(session)}." + f"'session' argument must be an AsyncClientSession or None, not {type(session)}" ) # Don't call end_session. yield session @@ -2250,7 +2250,7 @@ async def drop_database( if not isinstance(name, str): raise TypeError( - f"name_or_database must be an instance of str or a AsyncDatabase, not {type(name)}." + f"name_or_database must be an instance of str or a AsyncDatabase, not {type(name)}" ) async with await self._conn_for_writes(session, operation=_Op.DROP_DATABASE) as conn: diff --git a/pymongo/auth_shared.py b/pymongo/auth_shared.py index 9534bd74ad..410521d73a 100644 --- a/pymongo/auth_shared.py +++ b/pymongo/auth_shared.py @@ -107,7 +107,7 @@ def _build_credentials_tuple( ) -> MongoCredential: """Build and return a mechanism specific credentials tuple.""" if mech not in ("MONGODB-X509", "MONGODB-AWS", "MONGODB-OIDC") and user is None: - raise ConfigurationError(f"{mech} requires a username.") + raise ConfigurationError(f"{mech} requires a username") if mech == "GSSAPI": if source is not None and source != "$external": raise ValueError("authentication source must be $external or None for GSSAPI") @@ -219,7 +219,7 @@ def _build_credentials_tuple( else: source_database = source or database or "admin" if passwd is None: - raise ConfigurationError("A password is required.") + raise ConfigurationError("A password is required") return MongoCredential(mech, source_database, user, passwd, None, _Cache()) diff --git a/pymongo/collation.py b/pymongo/collation.py index 9adcb2e408..fc84b937f2 100644 --- a/pymongo/collation.py +++ b/pymongo/collation.py @@ -223,4 +223,4 @@ def validate_collation_or_none( return value.document if isinstance(value, dict): return value - raise TypeError("collation must be a dict, an instance of collation.Collation, or None.") + raise TypeError("collation must be a dict, an instance of collation.Collation, or None") diff --git a/pymongo/common.py b/pymongo/common.py index 3ed0005ce2..b6f7e34b3b 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -202,7 +202,7 @@ def validate_integer(option: str, value: Any) -> int: return int(value) except ValueError: raise ValueError(f"The value of {option} must be an integer") from None - raise TypeError(f"Wrong type for {option}, value must be an integer, not {type(value)}.") + raise TypeError(f"Wrong type for {option}, value must be an integer, not {type(value)}") def validate_positive_integer(option: str, value: Any) -> int: @@ -251,7 +251,7 @@ def validate_string(option: str, value: Any) -> str: if isinstance(value, str): return value raise TypeError( - f"Wrong type for {option}, value must be an instance of str, not {type(value)}." + f"Wrong type for {option}, value must be an instance of str, not {type(value)}" ) @@ -272,7 +272,7 @@ def validate_int_or_basestring(option: str, value: Any) -> Union[int, str]: except ValueError: return value raise TypeError( - f"Wrong type for {option}, value must be an integer or a string, not {type(value)}." + f"Wrong type for {option}, value must be an integer or a string, not {type(value)}" ) @@ -287,7 +287,7 @@ def validate_non_negative_int_or_basestring(option: Any, value: Any) -> Union[in return value return validate_non_negative_integer(option, val) raise TypeError( - f"Wrong type for {option}, value must be an non negative integer or a string, not {type(value)}." + f"Wrong type for {option}, value must be an non negative integer or a string, not {type(value)}" ) @@ -371,7 +371,7 @@ def validate_max_staleness(option: str, value: Any) -> int: def validate_read_preference(dummy: Any, value: Any) -> _ServerMode: """Validate a read preference.""" if not isinstance(value, _ServerMode): - raise TypeError(f"{value!r} is not a read preference.") + raise TypeError(f"{value!r} is not a read preference") return value @@ -448,7 +448,7 @@ def validate_auth_mechanism_properties(option: str, value: Any) -> dict[str, Uni if not isinstance(value, str): if not isinstance(value, dict): raise ValueError( - f"Auth mechanism properties must be given as a string or a dictionary, not {type(value)}." + f"Auth mechanism properties must be given as a string or a dictionary, not {type(value)}" ) for key, value in value.items(): # noqa: B020 if isinstance(value, str): @@ -461,7 +461,7 @@ def validate_auth_mechanism_properties(option: str, value: Any) -> dict[str, Uni from pymongo.auth_oidc_shared import OIDCCallback if not isinstance(value, OIDCCallback): - raise ValueError(f"callback must be an OIDCCallback object, not {type(value)}.") + raise ValueError(f"callback must be an OIDCCallback object, not {type(value)}") props[key] = value else: raise ValueError(f"Invalid type for auth mechanism property {key}, {type(value)}") @@ -484,7 +484,7 @@ def validate_auth_mechanism_properties(option: str, value: Any) -> dict[str, Uni raise ValueError( f"{key} is not a supported auth " "mechanism property. Must be one of " - f"{tuple(_MECHANISM_PROPS)}." + f"{tuple(_MECHANISM_PROPS)}" ) if key == "CANONICALIZE_HOST_NAME": @@ -528,7 +528,7 @@ def validate_type_registry(option: Any, value: Any) -> Optional[TypeRegistry]: def validate_list(option: str, value: Any) -> list: """Validates that 'value' is a list.""" if not isinstance(value, list): - raise TypeError(f"{option} must be a list, not {type(value)}.") + raise TypeError(f"{option} must be a list, not {type(value)}") return value @@ -595,7 +595,7 @@ def validate_server_api_or_none(option: Any, value: Any) -> Optional[ServerApi]: if value is None: return value if not isinstance(value, ServerApi): - raise TypeError(f"{option} must be an instance of ServerApi, not {type(value)}.") + raise TypeError(f"{option} must be an instance of ServerApi, not {type(value)}") return value @@ -604,7 +604,7 @@ def validate_is_callable_or_none(option: Any, value: Any) -> Optional[Callable]: if value is None: return value if not callable(value): - raise ValueError(f"{option} must be a callable, not {type(value)}.") + raise ValueError(f"{option} must be a callable, not {type(value)}") return value @@ -659,7 +659,7 @@ def validate_auto_encryption_opts_or_none(option: Any, value: Any) -> Optional[A from pymongo.encryption_options import AutoEncryptionOpts if not isinstance(value, AutoEncryptionOpts): - raise TypeError(f"{option} must be an instance of AutoEncryptionOpts, not {type(value)}.") + raise TypeError(f"{option} must be an instance of AutoEncryptionOpts, not {type(value)}") return value @@ -677,7 +677,7 @@ def validate_datetime_conversion(option: Any, value: Any) -> Optional[DatetimeCo return DatetimeConversion(value) raise TypeError( - f"{option} must be a str or int representing DatetimeConversion, not {type(value)}." + f"{option} must be a str or int representing DatetimeConversion, not {type(value)}" ) @@ -938,13 +938,13 @@ def __init__( if not isinstance(write_concern, WriteConcern): raise TypeError( - f"write_concern must be an instance of pymongo.write_concern.WriteConcern, not {type(write_concern)}." + f"write_concern must be an instance of pymongo.write_concern.WriteConcern, not {type(write_concern)}" ) self._write_concern = write_concern if not isinstance(read_concern, ReadConcern): raise TypeError( - f"read_concern must be an instance of pymongo.read_concern.ReadConcern, not {type(read_concern)}." + f"read_concern must be an instance of pymongo.read_concern.ReadConcern, not {type(read_concern)}" ) self._read_concern = read_concern diff --git a/pymongo/compression_support.py b/pymongo/compression_support.py index f49b56cc96..7486451730 100644 --- a/pymongo/compression_support.py +++ b/pymongo/compression_support.py @@ -91,7 +91,7 @@ def validate_zlib_compression_level(option: str, value: Any) -> int: try: level = int(value) except Exception: - raise TypeError(f"{option} must be an integer, not {value!r}.") from None + raise TypeError(f"{option} must be an integer, not {value!r}") from None if level < -1 or level > 9: raise ValueError("%s must be between -1 and 9, not %d." % (option, level)) return level diff --git a/pymongo/driver_info.py b/pymongo/driver_info.py index 93c58ad2a9..724a6f20d5 100644 --- a/pymongo/driver_info.py +++ b/pymongo/driver_info.py @@ -39,7 +39,7 @@ def __new__( for key, value in self._asdict().items(): if value is not None and not isinstance(value, str): raise TypeError( - f"Wrong type for DriverInfo {key} option, value must be an instance of str, not {type(value)}." + f"Wrong type for DriverInfo {key} option, value must be an instance of str, not {type(value)}" ) return self diff --git a/pymongo/encryption_options.py b/pymongo/encryption_options.py index d8a3e3d1b4..26dfbf5f03 100644 --- a/pymongo/encryption_options.py +++ b/pymongo/encryption_options.py @@ -226,7 +226,7 @@ def __init__( self._mongocryptd_spawn_args = mongocryptd_spawn_args if not isinstance(self._mongocryptd_spawn_args, list): raise TypeError( - f"mongocryptd_spawn_args must be a list, not {type(self._mongocryptd_spawn_args)}." + f"mongocryptd_spawn_args must be a list, not {type(self._mongocryptd_spawn_args)}" ) if not any("idleShutdownTimeoutSecs" in s for s in self._mongocryptd_spawn_args): self._mongocryptd_spawn_args.append("--idleShutdownTimeoutSecs=60") diff --git a/pymongo/helpers_shared.py b/pymongo/helpers_shared.py index 54ea332447..c6b820c1c2 100644 --- a/pymongo/helpers_shared.py +++ b/pymongo/helpers_shared.py @@ -122,7 +122,7 @@ def _index_list( """ if direction is not None: if not isinstance(key_or_list, str): - raise TypeError(f"Expected a string and a direction, not {type(key_or_list)}.") + raise TypeError(f"Expected a string and a direction, not {type(key_or_list)}") return [(key_or_list, direction)] else: if isinstance(key_or_list, str): @@ -133,7 +133,7 @@ def _index_list( return list(key_or_list.items()) elif not isinstance(key_or_list, (list, tuple)): raise TypeError( - f"if no direction is specified, key_or_list must be an instance of list, not {type(key_or_list)}." + f"if no direction is specified, key_or_list must be an instance of list, not {type(key_or_list)}" ) values: list[tuple[str, int]] = [] for item in key_or_list: @@ -174,12 +174,12 @@ def _index_document(index_list: _IndexList) -> dict[str, Any]: def _validate_index_key_pair(key: Any, value: Any) -> None: if not isinstance(key, str): - raise TypeError(f"first item in each key pair must be an instance of str, not {type(key)}.") + raise TypeError(f"first item in each key pair must be an instance of str, not {type(key)}") if not isinstance(value, (str, int, abc.Mapping)): raise TypeError( "second item in each key pair must be 1, -1, " "'2d', or another valid MongoDB index specifier." - f", not {type(value)}." + f", not {type(value)}" ) diff --git a/pymongo/monitoring.py b/pymongo/monitoring.py index aab8e27d04..38d6e3a22a 100644 --- a/pymongo/monitoring.py +++ b/pymongo/monitoring.py @@ -472,7 +472,7 @@ def _validate_event_listeners( ) -> Sequence[_EventListeners]: """Validate event listeners""" if not isinstance(listeners, abc.Sequence): - raise TypeError(f"{option} must be a list or tuple, not {type(listeners)}.") + raise TypeError(f"{option} must be a list or tuple, not {type(listeners)}") for listener in listeners: if not isinstance(listener, _EventListener): raise TypeError( @@ -480,7 +480,7 @@ def _validate_event_listeners( "CommandListener, ServerHeartbeatListener, " "ServerListener, TopologyListener, or " "ConnectionPoolListener," - f"not {type(listener)}." + f"not {type(listener)}" ) return listeners @@ -498,7 +498,7 @@ def register(listener: _EventListener) -> None: "CommandListener, ServerHeartbeatListener, " "ServerListener, TopologyListener, or " "ConnectionPoolListener," - f"not {type(listener)}." + f"not {type(listener)}" ) if isinstance(listener, CommandListener): _LISTENERS.command_listeners.append(listener) diff --git a/pymongo/read_concern.py b/pymongo/read_concern.py index 89f4430ef6..17f3a46edb 100644 --- a/pymongo/read_concern.py +++ b/pymongo/read_concern.py @@ -38,7 +38,7 @@ def __init__(self, level: Optional[str] = None) -> None: if level is None or isinstance(level, str): self.__level = level else: - raise TypeError(f"level must be a string or None, not {type(level)}.") + raise TypeError(f"level must be a string or None, not {type(level)}") @property def level(self) -> Optional[str]: diff --git a/pymongo/ssl_support.py b/pymongo/ssl_support.py index 580d71f9b0..0faf21ba8f 100644 --- a/pymongo/ssl_support.py +++ b/pymongo/ssl_support.py @@ -115,4 +115,4 @@ class SSLError(Exception): # type: ignore def get_ssl_context(*dummy): # type: ignore """No ssl module, raise ConfigurationError.""" - raise ConfigurationError("The ssl module is not available.") + raise ConfigurationError("The ssl module is not available") diff --git a/pymongo/synchronous/auth.py b/pymongo/synchronous/auth.py index a1b82a4dab..6041ebdbe3 100644 --- a/pymongo/synchronous/auth.py +++ b/pymongo/synchronous/auth.py @@ -158,7 +158,7 @@ def _password_digest(username: str, password: str) -> str: if len(password) == 0: raise ValueError("password can't be empty") if not isinstance(username, str): - raise TypeError(f"username must be an instance of str, not {type(username)}.") + raise TypeError(f"username must be an instance of str, not {type(username)}") md5hash = hashlib.md5() # noqa: S324 data = f"{username}:mongo:{password}" diff --git a/pymongo/synchronous/auth_oidc.py b/pymongo/synchronous/auth_oidc.py index e64a844f7b..c5efdd5fcc 100644 --- a/pymongo/synchronous/auth_oidc.py +++ b/pymongo/synchronous/auth_oidc.py @@ -214,7 +214,7 @@ def _get_access_token(self) -> Optional[str]: resp = cb.fetch(context) if not isinstance(resp, OIDCCallbackResult): raise ValueError( - f"Callback result must be of type OIDCCallbackResult, not {type(resp)}." + f"Callback result must be of type OIDCCallbackResult, not {type(resp)}" ) self.refresh_token = resp.refresh_token self.access_token = resp.access_token diff --git a/pymongo/synchronous/client_session.py b/pymongo/synchronous/client_session.py index 7d8946718d..298dd7b357 100644 --- a/pymongo/synchronous/client_session.py +++ b/pymongo/synchronous/client_session.py @@ -310,7 +310,7 @@ def __init__( if max_commit_time_ms is not None: if not isinstance(max_commit_time_ms, int): raise TypeError( - f"max_commit_time_ms must be an integer or None, not {type(max_commit_time_ms)}." + f"max_commit_time_ms must be an integer or None, not {type(max_commit_time_ms)}" ) @property @@ -900,7 +900,7 @@ def advance_cluster_time(self, cluster_time: Mapping[str, Any]) -> None: """ if not isinstance(cluster_time, _Mapping): raise TypeError( - f"cluster_time must be a subclass of collections.Mapping, not {type(cluster_time)}." + f"cluster_time must be a subclass of collections.Mapping, not {type(cluster_time)}" ) if not isinstance(cluster_time.get("clusterTime"), Timestamp): raise ValueError("Invalid cluster_time") @@ -923,7 +923,7 @@ def advance_operation_time(self, operation_time: Timestamp) -> None: """ if not isinstance(operation_time, Timestamp): raise TypeError( - f"operation_time must be an instance of bson.timestamp.Timestamp, not {type(operation_time)}." + f"operation_time must be an instance of bson.timestamp.Timestamp, not {type(operation_time)}" ) self._advance_operation_time(operation_time) diff --git a/pymongo/synchronous/collection.py b/pymongo/synchronous/collection.py index 34f517e96d..b956ac58a5 100644 --- a/pymongo/synchronous/collection.py +++ b/pymongo/synchronous/collection.py @@ -231,7 +231,7 @@ def __init__( read_concern or database.read_concern, ) if not isinstance(name, str): - raise TypeError(f"name must be an instance of str, not {type(name)}.") + raise TypeError(f"name must be an instance of str, not {type(name)}") from pymongo.synchronous.database import Database if not isinstance(database, Database): @@ -2472,7 +2472,7 @@ def _drop_index( name = helpers_shared._gen_index_name(index_or_name) if not isinstance(name, str): - raise TypeError(f"index_or_name must be an instance of str or list, not {type(name)}.") + raise TypeError(f"index_or_name must be an instance of str or list, not {type(name)}") cmd = {"dropIndexes": self._name, "index": name} cmd.update(kwargs) @@ -3071,7 +3071,7 @@ def rename( """ if not isinstance(new_name, str): - raise TypeError(f"new_name must be an instance of str, not {type(new_name)}.") + raise TypeError(f"new_name must be an instance of str, not {type(new_name)}") if not new_name or ".." in new_name: raise InvalidName("collection names cannot be empty") @@ -3141,7 +3141,7 @@ def distinct( """ if not isinstance(key, str): - raise TypeError(f"key must be an instance of str, not {type(key)}.") + raise TypeError(f"key must be an instance of str, not {type(key)}") cmd = {"distinct": self._name, "key": key} if filter is not None: if "query" in kwargs: @@ -3189,7 +3189,7 @@ def _find_and_modify( common.validate_is_mapping("filter", filter) if not isinstance(return_document, bool): raise ValueError( - f"return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER, not {type(return_document)}." + f"return_document must be ReturnDocument.BEFORE or ReturnDocument.AFTER, not {type(return_document)}" ) collation = validate_collation_or_none(kwargs.pop("collation", None)) cmd = {"findAndModify": self._name, "query": filter, "new": return_document} diff --git a/pymongo/synchronous/command_cursor.py b/pymongo/synchronous/command_cursor.py index 50fa4c9180..e23519d740 100644 --- a/pymongo/synchronous/command_cursor.py +++ b/pymongo/synchronous/command_cursor.py @@ -95,7 +95,7 @@ def __init__( if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: raise TypeError( - f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}" ) def __del__(self) -> None: @@ -117,7 +117,7 @@ def batch_size(self, batch_size: int) -> CommandCursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}") if batch_size < 0: raise ValueError("batch_size must be >= 0") diff --git a/pymongo/synchronous/cursor.py b/pymongo/synchronous/cursor.py index cc66b61d32..cda093ee19 100644 --- a/pymongo/synchronous/cursor.py +++ b/pymongo/synchronous/cursor.py @@ -146,9 +146,9 @@ def __init__( spec: Mapping[str, Any] = filter or {} validate_is_mapping("filter", spec) if not isinstance(skip, int): - raise TypeError(f"skip must be an instance of int, not {type(skip)}.") + raise TypeError(f"skip must be an instance of int, not {type(skip)}") if not isinstance(limit, int): - raise TypeError(f"limit must be an instance of int, not {type(limit)}.") + raise TypeError(f"limit must be an instance of int, not {type(limit)}") validate_boolean("no_cursor_timeout", no_cursor_timeout) if no_cursor_timeout and not self._explicit_session: warnings.warn( @@ -171,7 +171,7 @@ def __init__( validate_boolean("allow_partial_results", allow_partial_results) validate_boolean("oplog_replay", oplog_replay) if not isinstance(batch_size, int): - raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}") if batch_size < 0: raise ValueError("batch_size must be >= 0") # Only set if allow_disk_use is provided by the user, else None. @@ -388,7 +388,7 @@ def add_option(self, mask: int) -> Cursor[_DocumentType]: cursor.add_option(2) """ if not isinstance(mask, int): - raise TypeError(f"mask must be an int, not {type(mask)}.") + raise TypeError(f"mask must be an int, not {type(mask)}") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -408,7 +408,7 @@ def remove_option(self, mask: int) -> Cursor[_DocumentType]: cursor.remove_option(2) """ if not isinstance(mask, int): - raise TypeError(f"mask must be an int, not {type(mask)}.") + raise TypeError(f"mask must be an int, not {type(mask)}") self._check_okay_to_chain() if mask & _QUERY_OPTIONS["exhaust"]: @@ -432,7 +432,7 @@ def allow_disk_use(self, allow_disk_use: bool) -> Cursor[_DocumentType]: .. versionadded:: 3.11 """ if not isinstance(allow_disk_use, bool): - raise TypeError(f"allow_disk_use must be a bool, not {type(allow_disk_use)}.") + raise TypeError(f"allow_disk_use must be a bool, not {type(allow_disk_use)}") self._check_okay_to_chain() self._allow_disk_use = allow_disk_use @@ -451,7 +451,7 @@ def limit(self, limit: int) -> Cursor[_DocumentType]: .. seealso:: The MongoDB documentation on `limit `_. """ if not isinstance(limit, int): - raise TypeError(f"limit must be an integer, not {type(limit)}.") + raise TypeError(f"limit must be an integer, not {type(limit)}") if self._exhaust: raise InvalidOperation("Can't use limit and exhaust together.") self._check_okay_to_chain() @@ -479,7 +479,7 @@ def batch_size(self, batch_size: int) -> Cursor[_DocumentType]: :param batch_size: The size of each batch of results requested. """ if not isinstance(batch_size, int): - raise TypeError(f"batch_size must be an integer, not {type(batch_size)}.") + raise TypeError(f"batch_size must be an integer, not {type(batch_size)}") if batch_size < 0: raise ValueError("batch_size must be >= 0") self._check_okay_to_chain() @@ -499,7 +499,7 @@ def skip(self, skip: int) -> Cursor[_DocumentType]: :param skip: the number of results to skip """ if not isinstance(skip, int): - raise TypeError(f"skip must be an integer, not {type(skip)}.") + raise TypeError(f"skip must be an integer, not {type(skip)}") if skip < 0: raise ValueError("skip must be >= 0") self._check_okay_to_chain() @@ -520,7 +520,7 @@ def max_time_ms(self, max_time_ms: Optional[int]) -> Cursor[_DocumentType]: :param max_time_ms: the time limit after which the operation is aborted """ if not isinstance(max_time_ms, int) and max_time_ms is not None: - raise TypeError(f"max_time_ms must be an integer or None, not {type(max_time_ms)}.") + raise TypeError(f"max_time_ms must be an integer or None, not {type(max_time_ms)}") self._check_okay_to_chain() self._max_time_ms = max_time_ms @@ -544,7 +544,7 @@ def max_await_time_ms(self, max_await_time_ms: Optional[int]) -> Cursor[_Documen """ if not isinstance(max_await_time_ms, int) and max_await_time_ms is not None: raise TypeError( - f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}." + f"max_await_time_ms must be an integer or None, not {type(max_await_time_ms)}" ) self._check_okay_to_chain() @@ -679,7 +679,7 @@ def max(self, spec: _Sort) -> Cursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}") self._check_okay_to_chain() self._max = dict(spec) @@ -701,7 +701,7 @@ def min(self, spec: _Sort) -> Cursor[_DocumentType]: .. versionadded:: 2.7 """ if not isinstance(spec, (list, tuple)): - raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}.") + raise TypeError(f"spec must be an instance of list or tuple, not {type(spec)}") self._check_okay_to_chain() self._min = dict(spec) diff --git a/pymongo/synchronous/database.py b/pymongo/synchronous/database.py index 2f53a2b8fc..0dc03cb746 100644 --- a/pymongo/synchronous/database.py +++ b/pymongo/synchronous/database.py @@ -122,7 +122,7 @@ def __init__( from pymongo.synchronous.mongo_client import MongoClient if not isinstance(name, str): - raise TypeError(f"name must be an instance of str, not {type(name)}.") + raise TypeError(f"name must be an instance of str, not {type(name)}") if not isinstance(client, MongoClient): # This is for compatibility with mocked and subclassed types, such as in Motor. @@ -1303,7 +1303,7 @@ def drop_collection( name = name.name if not isinstance(name, str): - raise TypeError(f"name_or_collection must be an instance of str, not {type(name)}.") + raise TypeError(f"name_or_collection must be an instance of str, not {type(name)}") encrypted_fields = self._get_encrypted_fields( {"encryptedFields": encrypted_fields}, name, @@ -1368,7 +1368,7 @@ def validate_collection( if not isinstance(name, str): raise TypeError( - f"name_or_collection must be an instance of str or Collection, not {type(name)}." + f"name_or_collection must be an instance of str or Collection, not {type(name)}" ) cmd = {"validate": name, "scandata": scandata, "full": full} if comment is not None: diff --git a/pymongo/synchronous/encryption.py b/pymongo/synchronous/encryption.py index bd878d75a9..59f38e1913 100644 --- a/pymongo/synchronous/encryption.py +++ b/pymongo/synchronous/encryption.py @@ -321,7 +321,7 @@ def insert_data_key(self, data_key: bytes) -> Binary: data_key_id = raw_doc.get("_id") if not isinstance(data_key_id, Binary) or data_key_id.subtype != UUID_SUBTYPE: raise TypeError( - f"data_key _id must be Binary with a UUID subtype, not {type(data_key_id)}." + f"data_key _id must be Binary with a UUID subtype, not {type(data_key_id)}" ) assert self.key_vault_coll is not None @@ -645,7 +645,7 @@ def __init__( if not isinstance(codec_options, CodecOptions): raise TypeError( - f"codec_options must be an instance of bson.codec_options.CodecOptions, not {type(codec_options)}." + f"codec_options must be an instance of bson.codec_options.CodecOptions, not {type(codec_options)}" ) if not isinstance(key_vault_client, MongoClient): diff --git a/pymongo/synchronous/mongo_client.py b/pymongo/synchronous/mongo_client.py index f486a47e5e..706623c214 100644 --- a/pymongo/synchronous/mongo_client.py +++ b/pymongo/synchronous/mongo_client.py @@ -748,7 +748,7 @@ def __init__( if port is None: port = self.PORT if not isinstance(port, int): - raise TypeError(f"port must be an instance of int, not {type(port)}.") + raise TypeError(f"port must be an instance of int, not {type(port)}") # _pool_class, _monitor_class, and _condition_class are for deep # customization of PyMongo, e.g. Motor. @@ -1965,7 +1965,7 @@ def _close_cursor_now( The cursor is closed synchronously on the current thread. """ if not isinstance(cursor_id, int): - raise TypeError(f"cursor_id must be an instance of int, not {type(cursor_id)}.") + raise TypeError(f"cursor_id must be an instance of int, not {type(cursor_id)}") try: if conn_mgr: @@ -2088,7 +2088,7 @@ def _tmp_session( if session is not None: if not isinstance(session, client_session.ClientSession): raise ValueError( - f"'session' argument must be a ClientSession or None, not {type(session)}." + f"'session' argument must be a ClientSession or None, not {type(session)}" ) # Don't call end_session. yield session @@ -2238,7 +2238,7 @@ def drop_database( if not isinstance(name, str): raise TypeError( - f"name_or_database must be an instance of str or a Database, not {type(name)}." + f"name_or_database must be an instance of str or a Database, not {type(name)}" ) with self._conn_for_writes(session, operation=_Op.DROP_DATABASE) as conn: diff --git a/pymongo/uri_parser.py b/pymongo/uri_parser.py index 7018dad7d8..8f56ae4093 100644 --- a/pymongo/uri_parser.py +++ b/pymongo/uri_parser.py @@ -91,7 +91,7 @@ def parse_userinfo(userinfo: str) -> tuple[str, str]: user, _, passwd = userinfo.partition(":") # No password is expected with GSSAPI authentication. if not user: - raise InvalidURI("The empty string is not valid username.") + raise InvalidURI("The empty string is not valid username") return unquote_plus(user), unquote_plus(passwd) @@ -347,7 +347,7 @@ def split_options( semi_idx = opts.find(";") try: if and_idx >= 0 and semi_idx >= 0: - raise InvalidURI("Can not mix '&' and ';' for option separators.") + raise InvalidURI("Can not mix '&' and ';' for option separators") elif and_idx >= 0: options = _parse_options(opts, "&") elif semi_idx >= 0: @@ -357,7 +357,7 @@ def split_options( else: raise ValueError except ValueError: - raise InvalidURI("MongoDB URI options are key=value pairs.") from None + raise InvalidURI("MongoDB URI options are key=value pairs") from None options = _handle_security_options(options) @@ -389,7 +389,7 @@ def split_hosts(hosts: str, default_port: Optional[int] = DEFAULT_PORT) -> list[ nodes = [] for entity in hosts.split(","): if not entity: - raise ConfigurationError("Empty host (or extra comma in host list).") + raise ConfigurationError("Empty host (or extra comma in host list)") port = default_port # Unix socket entities don't have ports if entity.endswith(".sock"): @@ -502,7 +502,7 @@ def parse_uri( raise InvalidURI(f"Invalid URI scheme: URI must begin with '{SCHEME}' or '{SRV_SCHEME}'") if not scheme_free: - raise InvalidURI("Must provide at least one hostname or IP.") + raise InvalidURI("Must provide at least one hostname or IP") user = None passwd = None diff --git a/pymongo/write_concern.py b/pymongo/write_concern.py index 90a88a5d83..21faeebed0 100644 --- a/pymongo/write_concern.py +++ b/pymongo/write_concern.py @@ -74,7 +74,7 @@ def __init__( if wtimeout is not None: if not isinstance(wtimeout, int): - raise TypeError(f"wtimeout must be an integer, not {type(wtimeout)}.") + raise TypeError(f"wtimeout must be an integer, not {type(wtimeout)}") if wtimeout < 0: raise ValueError("wtimeout cannot be less than 0") self.__document["wtimeout"] = wtimeout @@ -98,7 +98,7 @@ def __init__( raise ValueError("w cannot be less than 0") self.__acknowledged = w > 0 elif not isinstance(w, str): - raise TypeError(f"w must be an integer or string, not {type(w)}.") + raise TypeError(f"w must be an integer or string, not {type(w)}") self.__document["w"] = w self.__server_default = not self.__document From c071b083a083a1d678ea2cee713be872de864f2d Mon Sep 17 00:00:00 2001 From: Iris Ho Date: Thu, 30 Jan 2025 15:03:02 -0800 Subject: [PATCH 4/4] run pre-commit --- pymongo/common.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pymongo/common.py b/pymongo/common.py index b6f7e34b3b..4be7a3122a 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -250,9 +250,7 @@ def validate_string(option: str, value: Any) -> str: """Validates that 'value' is an instance of `str`.""" if isinstance(value, str): return value - raise TypeError( - f"Wrong type for {option}, value must be an instance of str, not {type(value)}" - ) + raise TypeError(f"Wrong type for {option}, value must be an instance of str, not {type(value)}") def validate_string_or_none(option: str, value: Any) -> Optional[str]: