diff --git a/pymongo/asynchronous/mongo_client.py b/pymongo/asynchronous/mongo_client.py index e1a9d7735..05e4e80f1 100644 --- a/pymongo/asynchronous/mongo_client.py +++ b/pymongo/asynchronous/mongo_client.py @@ -830,7 +830,7 @@ class AsyncMongoClient(common.BaseObject, Generic[_DocumentType]): # Username and password passed as kwargs override user info in URI. username = opts.get("username", username) password = opts.get("password", password) - self._options = options = ClientOptions(username, password, dbase, opts) + self._options = options = ClientOptions(username, password, dbase, opts, _IS_SYNC) self._default_database_name = dbase self._lock = _ALock(_create_lock()) diff --git a/pymongo/client_options.py b/pymongo/client_options.py index 18f882980..9b9b88a73 100644 --- a/pymongo/client_options.py +++ b/pymongo/client_options.py @@ -144,7 +144,11 @@ def _parse_ssl_options(options: Mapping[str, Any]) -> tuple[Optional[SSLContext] def _parse_pool_options( - username: str, password: str, database: Optional[str], options: Mapping[str, Any] + username: str, + password: str, + database: Optional[str], + options: Mapping[str, Any], + is_sync: bool, ) -> PoolOptions: """Parse connection pool options.""" credentials = _parse_credentials(username, password, database, options) @@ -183,6 +187,7 @@ def _parse_pool_options( server_api=server_api, load_balanced=load_balanced, credentials=credentials, + is_sync=is_sync, ) @@ -195,7 +200,12 @@ class ClientOptions: """ def __init__( - self, username: str, password: str, database: Optional[str], options: Mapping[str, Any] + self, + username: str, + password: str, + database: Optional[str], + options: Mapping[str, Any], + is_sync: bool = True, ): self.__options = options self.__codec_options = _parse_codec_options(options) @@ -206,7 +216,7 @@ class ClientOptions: self.__server_selection_timeout = options.get( "serverselectiontimeoutms", common.SERVER_SELECTION_TIMEOUT ) - self.__pool_options = _parse_pool_options(username, password, database, options) + self.__pool_options = _parse_pool_options(username, password, database, options, is_sync) self.__read_preference = _parse_read_preference(options) self.__replica_set_name = options.get("replicaset") self.__write_concern = _parse_write_concern(options) diff --git a/pymongo/pool_options.py b/pymongo/pool_options.py index ad3200a3f..6ec97d7d1 100644 --- a/pymongo/pool_options.py +++ b/pymongo/pool_options.py @@ -331,6 +331,7 @@ class PoolOptions: server_api: Optional[ServerApi] = None, load_balanced: Optional[bool] = None, credentials: Optional[MongoCredential] = None, + is_sync: Optional[bool] = True, ): self.__max_pool_size = max_pool_size self.__min_pool_size = min_pool_size @@ -350,6 +351,7 @@ class PoolOptions: self.__load_balanced = load_balanced self.__credentials = credentials self.__metadata = copy.deepcopy(_METADATA) + if appname: self.__metadata["application"] = {"name": appname} @@ -361,10 +363,15 @@ class PoolOptions: # }, # 'platform': 'CPython 3.8.0|MyPlatform' # } + if not is_sync: + self.__metadata["driver"]["name"] = "{}|{}".format( + self.__metadata["driver"]["name"], + "async", + ) if driver: if driver.name: self.__metadata["driver"]["name"] = "{}|{}".format( - _METADATA["driver"]["name"], + self.__metadata["driver"]["name"], driver.name, ) if driver.version: diff --git a/pymongo/synchronous/mongo_client.py b/pymongo/synchronous/mongo_client.py index 287ad6af7..f855d9060 100644 --- a/pymongo/synchronous/mongo_client.py +++ b/pymongo/synchronous/mongo_client.py @@ -829,7 +829,7 @@ class MongoClient(common.BaseObject, Generic[_DocumentType]): # Username and password passed as kwargs override user info in URI. username = opts.get("username", username) password = opts.get("password", password) - self._options = options = ClientOptions(username, password, dbase, opts) + self._options = options = ClientOptions(username, password, dbase, opts, _IS_SYNC) self._default_database_name = dbase self._lock = _create_lock() diff --git a/test/asynchronous/test_client.py b/test/asynchronous/test_client.py index 9489de156..d4f09cde3 100644 --- a/test/asynchronous/test_client.py +++ b/test/asynchronous/test_client.py @@ -341,6 +341,7 @@ class AsyncClientUnitTest(AsyncUnitTest): def test_metadata(self): metadata = copy.deepcopy(_METADATA) + metadata["driver"]["name"] = "PyMongo|async" metadata["application"] = {"name": "foobar"} client = AsyncMongoClient("mongodb://foo:27017/?appname=foobar&connect=false") options = client.options @@ -359,7 +360,7 @@ class AsyncClientUnitTest(AsyncUnitTest): self.assertRaises(TypeError, AsyncMongoClient, driver="abc") self.assertRaises(TypeError, AsyncMongoClient, driver=("Foo", "1", "a")) # Test appending to driver info. - metadata["driver"]["name"] = "PyMongo|FooDriver" + metadata["driver"]["name"] = "PyMongo|async|FooDriver" metadata["driver"]["version"] = "{}|1.2.3".format(_METADATA["driver"]["version"]) client = AsyncMongoClient( "foo", @@ -403,6 +404,7 @@ class AsyncClientUnitTest(AsyncUnitTest): @mock.patch.dict("os.environ", {ENV_VAR_K8S: "1"}) def test_container_metadata(self): metadata = copy.deepcopy(_METADATA) + metadata["driver"]["name"] = "PyMongo|async" metadata["env"] = {} metadata["env"]["container"] = {"orchestrator": "kubernetes"} client = AsyncMongoClient("mongodb://foo:27017/?appname=foobar&connect=false") @@ -1938,6 +1940,7 @@ class TestClient(AsyncIntegrationTest): async def _test_handshake(self, env_vars, expected_env): with patch.dict("os.environ", env_vars): metadata = copy.deepcopy(_METADATA) + metadata["driver"]["name"] = "PyMongo|async" if expected_env is not None: metadata["env"] = expected_env diff --git a/test/discovery_and_monitoring/rs/too_old.json b/test/discovery_and_monitoring/rs/too_old.json index 8100a663f..dc8a5b2b9 100644 --- a/test/discovery_and_monitoring/rs/too_old.json +++ b/test/discovery_and_monitoring/rs/too_old.json @@ -30,7 +30,9 @@ "hosts": [ "a:27017", "b:27017" - ] + ], + "minWireVersion": 999, + "maxWireVersion": 1000 } ] ], diff --git a/test/discovery_and_monitoring/sharded/too_new.json b/test/discovery_and_monitoring/sharded/too_new.json index 4b997d216..c4e984dde 100644 --- a/test/discovery_and_monitoring/sharded/too_new.json +++ b/test/discovery_and_monitoring/sharded/too_new.json @@ -21,7 +21,9 @@ "ok": 1, "helloOk": true, "isWritablePrimary": true, - "msg": "isdbgrid" + "msg": "isdbgrid", + "minWireVersion": 7, + "maxWireVersion": 900 } ] ], diff --git a/test/test_client.py b/test/test_client.py index 0c8232643..22e94dcdd 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -337,6 +337,7 @@ class ClientUnitTest(UnitTest): def test_metadata(self): metadata = copy.deepcopy(_METADATA) + metadata["driver"]["name"] = "PyMongo" metadata["application"] = {"name": "foobar"} client = MongoClient("mongodb://foo:27017/?appname=foobar&connect=false") options = client.options @@ -399,6 +400,7 @@ class ClientUnitTest(UnitTest): @mock.patch.dict("os.environ", {ENV_VAR_K8S: "1"}) def test_container_metadata(self): metadata = copy.deepcopy(_METADATA) + metadata["driver"]["name"] = "PyMongo" metadata["env"] = {} metadata["env"]["container"] = {"orchestrator": "kubernetes"} client = MongoClient("mongodb://foo:27017/?appname=foobar&connect=false") @@ -1894,6 +1896,7 @@ class TestClient(IntegrationTest): def _test_handshake(self, env_vars, expected_env): with patch.dict("os.environ", env_vars): metadata = copy.deepcopy(_METADATA) + metadata["driver"]["name"] = "PyMongo" if expected_env is not None: metadata["env"] = expected_env diff --git a/tools/synchro.py b/tools/synchro.py index 65ff3bfe0..f45112c4c 100644 --- a/tools/synchro.py +++ b/tools/synchro.py @@ -96,6 +96,7 @@ replacements = { "async-transactions-ref": "transactions-ref", "async-snapshot-reads-ref": "snapshot-reads-ref", "default_async": "default", + "PyMongo|async": "PyMongo", } docstring_replacements: dict[tuple[str, str], str] = {