From 083359f95f7ce1c202d54a0a16506ae4c5162b23 Mon Sep 17 00:00:00 2001 From: "Jeffrey A. Clark" Date: Mon, 30 Sep 2024 19:09:57 -0400 Subject: [PATCH] PYTHON-1714 Add c extension use to client metadata (#1874) --- pymongo/__init__.py | 12 +----------- pymongo/common.py | 10 ++++++++++ pymongo/pool_options.py | 6 ++++++ test/asynchronous/test_client.py | 17 +++++++++++++---- test/test_client.py | 17 +++++++++++++---- tools/synchro.py | 1 + 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/pymongo/__init__.py b/pymongo/__init__.py index 8116788bc3..6416f939e8 100644 --- a/pymongo/__init__.py +++ b/pymongo/__init__.py @@ -88,7 +88,7 @@ from pymongo import _csot from pymongo._version import __version__, get_version_string, version_tuple -from pymongo.common import MAX_SUPPORTED_WIRE_VERSION, MIN_SUPPORTED_WIRE_VERSION +from pymongo.common import MAX_SUPPORTED_WIRE_VERSION, MIN_SUPPORTED_WIRE_VERSION, has_c from pymongo.cursor import CursorType from pymongo.operations import ( DeleteMany, @@ -116,16 +116,6 @@ """Current version of PyMongo.""" -def has_c() -> bool: - """Is the C extension installed?""" - try: - from pymongo import _cmessage # type: ignore[attr-defined] # noqa: F401 - - return True - except ImportError: - return False - - def timeout(seconds: Optional[float]) -> ContextManager[None]: """**(Provisional)** Apply the given timeout for a block of operations. diff --git a/pymongo/common.py b/pymongo/common.py index fe8fdd8949..126d0ee46e 100644 --- a/pymongo/common.py +++ b/pymongo/common.py @@ -1060,3 +1060,13 @@ def update(self, other: Mapping[str, Any]) -> None: # type: ignore[override] def cased_key(self, key: str) -> Any: return self.__casedkeys[key.lower()] + + +def has_c() -> bool: + """Is the C extension installed?""" + try: + from pymongo import _cmessage # type: ignore[attr-defined] # noqa: F401 + + return True + except ImportError: + return False diff --git a/pymongo/pool_options.py b/pymongo/pool_options.py index 6ec97d7d1b..61486c91c6 100644 --- a/pymongo/pool_options.py +++ b/pymongo/pool_options.py @@ -33,6 +33,7 @@ MAX_POOL_SIZE, MIN_POOL_SIZE, WAIT_QUEUE_TIMEOUT, + has_c, ) if TYPE_CHECKING: @@ -363,6 +364,11 @@ def __init__( # }, # 'platform': 'CPython 3.8.0|MyPlatform' # } + if has_c(): + self.__metadata["driver"]["name"] = "{}|{}".format( + self.__metadata["driver"]["name"], + "c", + ) if not is_sync: self.__metadata["driver"]["name"] = "{}|{}".format( self.__metadata["driver"]["name"], diff --git a/test/asynchronous/test_client.py b/test/asynchronous/test_client.py index 1926ad74d2..b6324d3bac 100644 --- a/test/asynchronous/test_client.py +++ b/test/asynchronous/test_client.py @@ -99,7 +99,7 @@ from pymongo.asynchronous.settings import TOPOLOGY_TYPE from pymongo.asynchronous.topology import _ErrorContext from pymongo.client_options import ClientOptions -from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT +from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT, has_c from pymongo.compression_support import _have_snappy, _have_zstd from pymongo.driver_info import DriverInfo from pymongo.errors import ( @@ -347,7 +347,10 @@ async def test_read_preference(self): async def test_metadata(self): metadata = copy.deepcopy(_METADATA) - metadata["driver"]["name"] = "PyMongo|async" + if has_c(): + metadata["driver"]["name"] = "PyMongo|c|async" + else: + metadata["driver"]["name"] = "PyMongo|async" metadata["application"] = {"name": "foobar"} client = self.simple_client("mongodb://foo:27017/?appname=foobar&connect=false") options = client.options @@ -370,7 +373,10 @@ async def test_metadata(self): with self.assertRaises(TypeError): self.simple_client(driver=("Foo", "1", "a")) # Test appending to driver info. - metadata["driver"]["name"] = "PyMongo|async|FooDriver" + if has_c(): + metadata["driver"]["name"] = "PyMongo|c|async|FooDriver" + else: + metadata["driver"]["name"] = "PyMongo|async|FooDriver" metadata["driver"]["version"] = "{}|1.2.3".format(_METADATA["driver"]["version"]) client = self.simple_client( "foo", @@ -1931,7 +1937,10 @@ def test_sigstop_sigcont(self): 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 has_c(): + metadata["driver"]["name"] = "PyMongo|c|async" + else: + metadata["driver"]["name"] = "PyMongo|async" if expected_env is not None: metadata["env"] = expected_env diff --git a/test/test_client.py b/test/test_client.py index 2642a87fdf..86b9f41ec9 100644 --- a/test/test_client.py +++ b/test/test_client.py @@ -87,7 +87,7 @@ from bson.tz_util import utc from pymongo import event_loggers, message, monitoring from pymongo.client_options import ClientOptions -from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT +from pymongo.common import _UUID_REPRESENTATIONS, CONNECT_TIMEOUT, has_c from pymongo.compression_support import _have_snappy, _have_zstd from pymongo.driver_info import DriverInfo from pymongo.errors import ( @@ -339,7 +339,10 @@ def test_read_preference(self): def test_metadata(self): metadata = copy.deepcopy(_METADATA) - metadata["driver"]["name"] = "PyMongo" + if has_c(): + metadata["driver"]["name"] = "PyMongo|c" + else: + metadata["driver"]["name"] = "PyMongo" metadata["application"] = {"name": "foobar"} client = self.simple_client("mongodb://foo:27017/?appname=foobar&connect=false") options = client.options @@ -362,7 +365,10 @@ def test_metadata(self): with self.assertRaises(TypeError): self.simple_client(driver=("Foo", "1", "a")) # Test appending to driver info. - metadata["driver"]["name"] = "PyMongo|FooDriver" + if has_c(): + metadata["driver"]["name"] = "PyMongo|c|FooDriver" + else: + metadata["driver"]["name"] = "PyMongo|FooDriver" metadata["driver"]["version"] = "{}|1.2.3".format(_METADATA["driver"]["version"]) client = self.simple_client( "foo", @@ -1889,7 +1895,10 @@ def test_sigstop_sigcont(self): def _test_handshake(self, env_vars, expected_env): with patch.dict("os.environ", env_vars): metadata = copy.deepcopy(_METADATA) - metadata["driver"]["name"] = "PyMongo" + if has_c(): + metadata["driver"]["name"] = "PyMongo|c" + else: + 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 86506b7798..6ce897a0b8 100644 --- a/tools/synchro.py +++ b/tools/synchro.py @@ -101,6 +101,7 @@ "default_async": "default", "aclose": "close", "PyMongo|async": "PyMongo", + "PyMongo|c|async": "PyMongo|c", "AsyncTestGridFile": "TestGridFile", "AsyncTestGridFileNoConnect": "TestGridFileNoConnect", }