Skip to content

Commit f7874fb

Browse files
authored
PYTHON-2287 Improve error message for invalid boolean option (#1236)
1 parent bcfdd20 commit f7874fb

File tree

6 files changed

+23
-17
lines changed

6 files changed

+23
-17
lines changed

bson/codec_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ def __new__(
397397
"subclass of collections.abc.MutableMapping"
398398
)
399399
if not isinstance(tz_aware, bool):
400-
raise TypeError("tz_aware must be True or False")
400+
raise TypeError(f"tz_aware must be True or False, was: tz_aware={tz_aware}")
401401
if uuid_representation not in ALL_UUID_REPRESENTATIONS:
402402
raise ValueError(
403403
"uuid_representation must be a value from bson.binary.UuidRepresentation"

doc/contributors.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,4 @@ The following is a list of people who have contributed to
9696
- Jean-Christophe Fillion-Robin (jcfr)
9797
- Sean Cheah (thalassemia)
9898
- Dainis Gorbunovs (DainisGorbunovs)
99+
- Iris Ho (sleepyStick)

pymongo/common.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
from pymongo.read_concern import ReadConcern
5151
from pymongo.read_preferences import _MONGOS_MODES, _ServerMode
5252
from pymongo.server_api import ServerApi
53-
from pymongo.write_concern import DEFAULT_WRITE_CONCERN, WriteConcern
53+
from pymongo.write_concern import DEFAULT_WRITE_CONCERN, WriteConcern, validate_boolean
5454

5555
ORDERED_TYPES: Sequence[Type] = (SON, OrderedDict)
5656

@@ -170,13 +170,6 @@ def raise_config_error(key: str, dummy: Any) -> NoReturn:
170170
}
171171

172172

173-
def validate_boolean(option: str, value: Any) -> bool:
174-
"""Validates that 'value' is True or False."""
175-
if isinstance(value, bool):
176-
return value
177-
raise TypeError(f"{option} must be True or False")
178-
179-
180173
def validate_boolean_or_string(option: str, value: Any) -> bool:
181174
"""Validates that value is True, False, 'true', or 'false'."""
182175
if isinstance(value, str):

pymongo/pyopenssl_context.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from pymongo.ocsp_support import _load_trusted_ca_certs, _ocsp_callback
3838
from pymongo.socket_checker import SocketChecker as _SocketChecker
3939
from pymongo.socket_checker import _errno_from_exception
40+
from pymongo.write_concern import validate_boolean
4041

4142
try:
4243
import certifi
@@ -228,8 +229,7 @@ def __get_check_hostname(self):
228229
return self._check_hostname
229230

230231
def __set_check_hostname(self, value):
231-
if not isinstance(value, bool):
232-
raise TypeError("check_hostname must be True or False")
232+
validate_boolean("check_hostname", value)
233233
self._check_hostname = value
234234

235235
check_hostname = property(__get_check_hostname, __set_check_hostname)
@@ -238,8 +238,7 @@ def __get_check_ocsp_endpoint(self):
238238
return self._callback_data.check_ocsp_endpoint
239239

240240
def __set_check_ocsp_endpoint(self, value):
241-
if not isinstance(value, bool):
242-
raise TypeError("check_ocsp must be True or False")
241+
validate_boolean("check_ocsp", value)
243242
self._callback_data.check_ocsp_endpoint = value
244243

245244
check_ocsp_endpoint = property(__get_check_ocsp_endpoint, __set_check_ocsp_endpoint)

pymongo/write_concern.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@
1919
from pymongo.errors import ConfigurationError
2020

2121

22+
# Moved here to avoid a circular import.
23+
def validate_boolean(option: str, value: Any) -> bool:
24+
"""Validates that 'value' is True or False."""
25+
if isinstance(value, bool):
26+
return value
27+
raise TypeError(f"{option} must be True or False, was: {option}={value}")
28+
29+
2230
class WriteConcern:
2331
"""WriteConcern
2432
@@ -65,13 +73,11 @@ def __init__(
6573
self.__document["wtimeout"] = wtimeout
6674

6775
if j is not None:
68-
if not isinstance(j, bool):
69-
raise TypeError("j must be True or False")
76+
validate_boolean("j", j)
7077
self.__document["j"] = j
7178

7279
if fsync is not None:
73-
if not isinstance(fsync, bool):
74-
raise TypeError("fsync must be True or False")
80+
validate_boolean("fsync", fsync)
7581
if j and fsync:
7682
raise ConfigurationError("Can't set both j and fsync at the same time")
7783
self.__document["fsync"] = fsync

test/test_common.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ def test_mongo_client(self):
165165
self.assertEqual(direct, direct2)
166166
self.assertFalse(direct != direct2)
167167

168+
def test_validate_boolean(self):
169+
self.db.test.update_one({}, {"$set": {"total": 1}}, upsert=True)
170+
with self.assertRaisesRegex(
171+
TypeError, "upsert must be True or False, was: upsert={'upsert': True}"
172+
):
173+
self.db.test.update_one({}, {"$set": {"total": 1}}, {"upsert": True}) # type: ignore
174+
168175

169176
if __name__ == "__main__":
170177
unittest.main()

0 commit comments

Comments
 (0)