From e120b39313ff241afa45d073acf1164394595228 Mon Sep 17 00:00:00 2001 From: sleepyStick Date: Wed, 14 Jun 2023 16:11:54 -0700 Subject: [PATCH 1/4] PYTHON-2287 fixed validate boolean message --- bson/codec_options.py | 2 +- pymongo/common.py | 2 +- pymongo/pyopenssl_context.py | 7 +++---- pymongo/write_concern.py | 7 +++---- test/test_common.py | 7 +++++++ 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/bson/codec_options.py b/bson/codec_options.py index a0bdd0eeb9..45860fa705 100644 --- a/bson/codec_options.py +++ b/bson/codec_options.py @@ -397,7 +397,7 @@ def __new__( "subclass of collections.abc.MutableMapping" ) if not isinstance(tz_aware, bool): - raise TypeError("tz_aware must be True or False") + raise TypeError(f"tz_aware must be True or False, was: tz_aware={tz_aware}") if uuid_representation not in ALL_UUID_REPRESENTATIONS: raise ValueError( "uuid_representation must be a value from bson.binary.UuidRepresentation" diff --git a/pymongo/common.py b/pymongo/common.py index 82c773695a..027bbc14ac 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -174,7 +174,7 @@ def validate_boolean(option: str, value: Any) -> bool: """Validates that 'value' is True or False.""" if isinstance(value, bool): return value - raise TypeError(f"{option} must be True or False") + raise TypeError(f"{option} must be True or False, was: {option}={value}") def validate_boolean_or_string(option: str, value: Any) -> bool: diff --git a/pymongo/pyopenssl_context.py b/pymongo/pyopenssl_context.py index 83d8f853ef..3de8c52b78 100644 --- a/pymongo/pyopenssl_context.py +++ b/pymongo/pyopenssl_context.py @@ -31,6 +31,7 @@ from service_identity.pyopenssl import verify_hostname as _verify_hostname from service_identity.pyopenssl import verify_ip_address as _verify_ip_address +from pymongo.common import validate_boolean from pymongo.errors import ConfigurationError as _ConfigurationError from pymongo.errors import _CertificateError from pymongo.ocsp_cache import _OCSPCache @@ -228,8 +229,7 @@ def __get_check_hostname(self): return self._check_hostname def __set_check_hostname(self, value): - if not isinstance(value, bool): - raise TypeError("check_hostname must be True or False") + validate_boolean("check_hostname", value) self._check_hostname = value check_hostname = property(__get_check_hostname, __set_check_hostname) @@ -238,8 +238,7 @@ def __get_check_ocsp_endpoint(self): return self._callback_data.check_ocsp_endpoint def __set_check_ocsp_endpoint(self, value): - if not isinstance(value, bool): - raise TypeError("check_ocsp must be True or False") + validate_boolean("check_ocsp", value) self._callback_data.check_ocsp_endpoint = value check_ocsp_endpoint = property(__get_check_ocsp_endpoint, __set_check_ocsp_endpoint) diff --git a/pymongo/write_concern.py b/pymongo/write_concern.py index 25f87954b5..6bb2da9035 100644 --- a/pymongo/write_concern.py +++ b/pymongo/write_concern.py @@ -16,6 +16,7 @@ from typing import Any, Dict, Optional, Union +from pymongo.common import validate_boolean from pymongo.errors import ConfigurationError @@ -65,13 +66,11 @@ def __init__( self.__document["wtimeout"] = wtimeout if j is not None: - if not isinstance(j, bool): - raise TypeError("j must be True or False") + validate_boolean("j", j) self.__document["j"] = j if fsync is not None: - if not isinstance(fsync, bool): - raise TypeError("fsync must be True or False") + validate_boolean("fsync", fsync) if j and fsync: raise ConfigurationError("Can't set both j and fsync at the same time") self.__document["fsync"] = fsync diff --git a/test/test_common.py b/test/test_common.py index 76367ffa0c..838a9f5147 100644 --- a/test/test_common.py +++ b/test/test_common.py @@ -165,6 +165,13 @@ def test_mongo_client(self): self.assertEqual(direct, direct2) self.assertFalse(direct != direct2) + def test_validate_boolean(self): + self.db.test.update_one({}, {"$set": {"total": 1}}, upsert=True) + with self.assertRaisesRegex( + TypeError, "upsert must be True or False, was: upsert={'upsert': True}" + ): + self.db.test.update_one({}, {"$set": {"total": 1}}, {"upsert": True}) + if __name__ == "__main__": unittest.main() From d9bdc8c4123d628e5052e23479a94b5a38d563c3 Mon Sep 17 00:00:00 2001 From: sleepyStick Date: Wed, 14 Jun 2023 16:46:32 -0700 Subject: [PATCH 2/4] PYTHON-2287 fixed circular imports --- pymongo/common.py | 9 +-------- pymongo/pyopenssl_context.py | 2 +- pymongo/write_concern.py | 8 +++++++- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/pymongo/common.py b/pymongo/common.py index 027bbc14ac..15a4c6f227 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -50,7 +50,7 @@ from pymongo.read_concern import ReadConcern from pymongo.read_preferences import _MONGOS_MODES, _ServerMode from pymongo.server_api import ServerApi -from pymongo.write_concern import DEFAULT_WRITE_CONCERN, WriteConcern +from pymongo.write_concern import DEFAULT_WRITE_CONCERN, WriteConcern, validate_boolean ORDERED_TYPES: Sequence[Type] = (SON, OrderedDict) @@ -170,13 +170,6 @@ def raise_config_error(key: str, dummy: Any) -> NoReturn: } -def validate_boolean(option: str, value: Any) -> bool: - """Validates that 'value' is True or False.""" - if isinstance(value, bool): - return value - raise TypeError(f"{option} must be True or False, was: {option}={value}") - - def validate_boolean_or_string(option: str, value: Any) -> bool: """Validates that value is True, False, 'true', or 'false'.""" if isinstance(value, str): diff --git a/pymongo/pyopenssl_context.py b/pymongo/pyopenssl_context.py index 3de8c52b78..d6762bcaa2 100644 --- a/pymongo/pyopenssl_context.py +++ b/pymongo/pyopenssl_context.py @@ -31,13 +31,13 @@ from service_identity.pyopenssl import verify_hostname as _verify_hostname from service_identity.pyopenssl import verify_ip_address as _verify_ip_address -from pymongo.common import validate_boolean from pymongo.errors import ConfigurationError as _ConfigurationError from pymongo.errors import _CertificateError from pymongo.ocsp_cache import _OCSPCache from pymongo.ocsp_support import _load_trusted_ca_certs, _ocsp_callback from pymongo.socket_checker import SocketChecker as _SocketChecker from pymongo.socket_checker import _errno_from_exception +from pymongo.write_concern import validate_boolean try: import certifi diff --git a/pymongo/write_concern.py b/pymongo/write_concern.py index 6bb2da9035..51745a3260 100644 --- a/pymongo/write_concern.py +++ b/pymongo/write_concern.py @@ -16,10 +16,16 @@ from typing import Any, Dict, Optional, Union -from pymongo.common import validate_boolean from pymongo.errors import ConfigurationError +def validate_boolean(option: str, value: Any) -> bool: + """Validates that 'value' is True or False.""" + if isinstance(value, bool): + return value + raise TypeError(f"{option} must be True or False, was: {option}={value}") + + class WriteConcern: """WriteConcern From 9a93b980448dcca35dae05dd30e31c9df29a044c Mon Sep 17 00:00:00 2001 From: sleepyStick Date: Wed, 14 Jun 2023 16:53:45 -0700 Subject: [PATCH 3/4] PYTHON-2287 add type ignore --- test/test_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_common.py b/test/test_common.py index 838a9f5147..f1769cb214 100644 --- a/test/test_common.py +++ b/test/test_common.py @@ -170,7 +170,7 @@ def test_validate_boolean(self): with self.assertRaisesRegex( TypeError, "upsert must be True or False, was: upsert={'upsert': True}" ): - self.db.test.update_one({}, {"$set": {"total": 1}}, {"upsert": True}) + self.db.test.update_one({}, {"$set": {"total": 1}}, {"upsert": True}) # type: ignore if __name__ == "__main__": From a3d1663e2a5c621e1c3cc32661569fe91983fd2a Mon Sep 17 00:00:00 2001 From: sleepyStick Date: Thu, 15 Jun 2023 11:12:16 -0700 Subject: [PATCH 4/4] PYTHON-2287 add comment about removing circular import --- doc/contributors.rst | 1 + pymongo/write_concern.py | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/contributors.rst b/doc/contributors.rst index 17ae4784e2..e6d5e5310d 100644 --- a/doc/contributors.rst +++ b/doc/contributors.rst @@ -96,3 +96,4 @@ The following is a list of people who have contributed to - Jean-Christophe Fillion-Robin (jcfr) - Sean Cheah (thalassemia) - Dainis Gorbunovs (DainisGorbunovs) +- Iris Ho (sleepyStick) diff --git a/pymongo/write_concern.py b/pymongo/write_concern.py index 51745a3260..d62c3c3117 100644 --- a/pymongo/write_concern.py +++ b/pymongo/write_concern.py @@ -19,6 +19,7 @@ from pymongo.errors import ConfigurationError +# Moved here to avoid a circular import. def validate_boolean(option: str, value: Any) -> bool: """Validates that 'value' is True or False.""" if isinstance(value, bool):