Skip to content

Commit 44d1d40

Browse files
PYTHON-5115 Type validation errors should include the invalid type name (mongodb#2085)
Co-authored-by: Iris Ho <[email protected]>
1 parent c42f3d6 commit 44d1d40

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+204
-129
lines changed

bson/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,7 @@ def is_valid(bson: bytes) -> bool:
13861386
:param bson: the data to be validated
13871387
"""
13881388
if not isinstance(bson, bytes):
1389-
raise TypeError("BSON data must be an instance of a subclass of bytes")
1389+
raise TypeError(f"BSON data must be an instance of a subclass of bytes, not {type(bson)}")
13901390

13911391
try:
13921392
_bson_to_dict(bson, DEFAULT_CODEC_OPTIONS)

bson/binary.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ def __new__(
290290
subtype: int = BINARY_SUBTYPE,
291291
) -> Binary:
292292
if not isinstance(subtype, int):
293-
raise TypeError("subtype must be an instance of int")
293+
raise TypeError(f"subtype must be an instance of int, not {type(subtype)}")
294294
if subtype >= 256 or subtype < 0:
295295
raise ValueError("subtype must be contained in [0, 256)")
296296
# Support any type that implements the buffer protocol.
@@ -321,7 +321,7 @@ def from_uuid(
321321
.. versionadded:: 3.11
322322
"""
323323
if not isinstance(uuid, UUID):
324-
raise TypeError("uuid must be an instance of uuid.UUID")
324+
raise TypeError(f"uuid must be an instance of uuid.UUID, not {type(uuid)}")
325325

326326
if uuid_representation not in ALL_UUID_REPRESENTATIONS:
327327
raise ValueError(
@@ -470,7 +470,7 @@ def as_vector(self) -> BinaryVector:
470470
"""
471471

472472
if self.subtype != VECTOR_SUBTYPE:
473-
raise ValueError(f"Cannot decode subtype {self.subtype} as a vector.")
473+
raise ValueError(f"Cannot decode subtype {self.subtype} as a vector")
474474

475475
position = 0
476476
dtype, padding = struct.unpack_from("<sB", self, position)

bson/code.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def __new__(
5656
**kwargs: Any,
5757
) -> Code:
5858
if not isinstance(code, str):
59-
raise TypeError("code must be an instance of str")
59+
raise TypeError(f"code must be an instance of str, not {type(code)}")
6060

6161
self = str.__new__(cls, code)
6262

@@ -67,7 +67,7 @@ def __new__(
6767

6868
if scope is not None:
6969
if not isinstance(scope, _Mapping):
70-
raise TypeError("scope must be an instance of dict")
70+
raise TypeError(f"scope must be an instance of dict, not {type(scope)}")
7171
if self.__scope is not None:
7272
self.__scope.update(scope) # type: ignore
7373
else:

bson/codec_options.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,17 +401,23 @@ def __new__(
401401
"uuid_representation must be a value from bson.binary.UuidRepresentation"
402402
)
403403
if not isinstance(unicode_decode_error_handler, str):
404-
raise ValueError("unicode_decode_error_handler must be a string")
404+
raise ValueError(
405+
f"unicode_decode_error_handler must be a string, not {type(unicode_decode_error_handler)}"
406+
)
405407
if tzinfo is not None:
406408
if not isinstance(tzinfo, datetime.tzinfo):
407-
raise TypeError("tzinfo must be an instance of datetime.tzinfo")
409+
raise TypeError(
410+
f"tzinfo must be an instance of datetime.tzinfo, not {type(tzinfo)}"
411+
)
408412
if not tz_aware:
409413
raise ValueError("cannot specify tzinfo without also setting tz_aware=True")
410414

411415
type_registry = type_registry or TypeRegistry()
412416

413417
if not isinstance(type_registry, TypeRegistry):
414-
raise TypeError("type_registry must be an instance of TypeRegistry")
418+
raise TypeError(
419+
f"type_registry must be an instance of TypeRegistry, not {type(type_registry)}"
420+
)
415421

416422
return tuple.__new__(
417423
cls,

bson/dbref.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ def __init__(
5656
.. seealso:: The MongoDB documentation on `dbrefs <https://dochub.mongodb.org/core/dbrefs>`_.
5757
"""
5858
if not isinstance(collection, str):
59-
raise TypeError("collection must be an instance of str")
59+
raise TypeError(f"collection must be an instance of str, not {type(collection)}")
6060
if database is not None and not isinstance(database, str):
61-
raise TypeError("database must be an instance of str")
61+
raise TypeError(f"database must be an instance of str, not {type(database)}")
6262

6363
self.__collection = collection
6464
self.__id = id

bson/decimal128.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ def from_bid(cls: Type[Decimal128], value: bytes) -> Decimal128:
277277
point in Binary Integer Decimal (BID) format).
278278
"""
279279
if not isinstance(value, bytes):
280-
raise TypeError("value must be an instance of bytes")
280+
raise TypeError(f"value must be an instance of bytes, not {type(value)}")
281281
if len(value) != 16:
282282
raise ValueError("value must be exactly 16 bytes")
283283
return cls((_UNPACK_64(value[8:])[0], _UNPACK_64(value[:8])[0])) # type: ignore

bson/timestamp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ def __init__(self, time: Union[datetime.datetime, int], inc: int) -> None:
5858
time = time - offset
5959
time = int(calendar.timegm(time.timetuple()))
6060
if not isinstance(time, int):
61-
raise TypeError("time must be an instance of int")
61+
raise TypeError(f"time must be an instance of int, not {type(time)}")
6262
if not isinstance(inc, int):
63-
raise TypeError("inc must be an instance of int")
63+
raise TypeError(f"inc must be an instance of int, not {type(inc)}")
6464
if not 0 <= time < UPPERBOUND:
6565
raise ValueError("time must be contained in [0, 2**32)")
6666
if not 0 <= inc < UPPERBOUND:

gridfs/asynchronous/grid_file.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __init__(self, database: AsyncDatabase, collection: str = "fs"):
100100
.. seealso:: The MongoDB documentation on `gridfs <https://dochub.mongodb.org/core/gridfs>`_.
101101
"""
102102
if not isinstance(database, AsyncDatabase):
103-
raise TypeError("database must be an instance of Database")
103+
raise TypeError(f"database must be an instance of Database, not {type(database)}")
104104

105105
database = _clear_entity_type_registry(database)
106106

@@ -503,7 +503,7 @@ def __init__(
503503
.. seealso:: The MongoDB documentation on `gridfs <https://dochub.mongodb.org/core/gridfs>`_.
504504
"""
505505
if not isinstance(db, AsyncDatabase):
506-
raise TypeError("database must be an instance of AsyncDatabase")
506+
raise TypeError(f"database must be an instance of AsyncDatabase, not {type(db)}")
507507

508508
db = _clear_entity_type_registry(db)
509509

@@ -1082,7 +1082,9 @@ def __init__(
10821082
:attr:`~pymongo.collection.AsyncCollection.write_concern`
10831083
"""
10841084
if not isinstance(root_collection, AsyncCollection):
1085-
raise TypeError("root_collection must be an instance of AsyncCollection")
1085+
raise TypeError(
1086+
f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}"
1087+
)
10861088

10871089
if not root_collection.write_concern.acknowledged:
10881090
raise ConfigurationError("root_collection must use acknowledged write_concern")
@@ -1436,7 +1438,9 @@ def __init__(
14361438
from the server. Metadata is fetched when first needed.
14371439
"""
14381440
if not isinstance(root_collection, AsyncCollection):
1439-
raise TypeError("root_collection must be an instance of AsyncCollection")
1441+
raise TypeError(
1442+
f"root_collection must be an instance of AsyncCollection, not {type(root_collection)}"
1443+
)
14401444
_disallow_transactions(session)
14411445

14421446
root_collection = _clear_entity_type_registry(root_collection)

gridfs/synchronous/grid_file.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __init__(self, database: Database, collection: str = "fs"):
100100
.. seealso:: The MongoDB documentation on `gridfs <https://dochub.mongodb.org/core/gridfs>`_.
101101
"""
102102
if not isinstance(database, Database):
103-
raise TypeError("database must be an instance of Database")
103+
raise TypeError(f"database must be an instance of Database, not {type(database)}")
104104

105105
database = _clear_entity_type_registry(database)
106106

@@ -501,7 +501,7 @@ def __init__(
501501
.. seealso:: The MongoDB documentation on `gridfs <https://dochub.mongodb.org/core/gridfs>`_.
502502
"""
503503
if not isinstance(db, Database):
504-
raise TypeError("database must be an instance of Database")
504+
raise TypeError(f"database must be an instance of Database, not {type(db)}")
505505

506506
db = _clear_entity_type_registry(db)
507507

@@ -1076,7 +1076,9 @@ def __init__(
10761076
:attr:`~pymongo.collection.Collection.write_concern`
10771077
"""
10781078
if not isinstance(root_collection, Collection):
1079-
raise TypeError("root_collection must be an instance of Collection")
1079+
raise TypeError(
1080+
f"root_collection must be an instance of Collection, not {type(root_collection)}"
1081+
)
10801082

10811083
if not root_collection.write_concern.acknowledged:
10821084
raise ConfigurationError("root_collection must use acknowledged write_concern")
@@ -1426,7 +1428,9 @@ def __init__(
14261428
from the server. Metadata is fetched when first needed.
14271429
"""
14281430
if not isinstance(root_collection, Collection):
1429-
raise TypeError("root_collection must be an instance of Collection")
1431+
raise TypeError(
1432+
f"root_collection must be an instance of Collection, not {type(root_collection)}"
1433+
)
14301434
_disallow_transactions(session)
14311435

14321436
root_collection = _clear_entity_type_registry(root_collection)

pymongo/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def timeout(seconds: Optional[float]) -> ContextManager[None]:
160160
.. versionadded:: 4.2
161161
"""
162162
if not isinstance(seconds, (int, float, type(None))):
163-
raise TypeError("timeout must be None, an int, or a float")
163+
raise TypeError(f"timeout must be None, an int, or a float, not {type(seconds)}")
164164
if seconds and seconds < 0:
165165
raise ValueError("timeout cannot be negative")
166166
if seconds is not None:

0 commit comments

Comments
 (0)