From e6a4a7145eccb0b6c76c84aa539f29b40f3424b3 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Tue, 15 Apr 2025 08:05:20 -0400 Subject: [PATCH 1/2] PYTHON-5310 - Fix uri_parser AttributeError when used directly (#2283) --- doc/changelog.rst | 1 + pymongo/__init__.py | 3 +++ test/test_default_exports.py | 7 +++++++ 3 files changed, 11 insertions(+) diff --git a/doc/changelog.rst b/doc/changelog.rst index e82804565..597f75f87 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -9,6 +9,7 @@ Version 4.12.1 is a bug fix release. - Fixed a bug that could raise ``UnboundLocalError`` when creating asynchronous connections over SSL. - Fixed a bug causing SRV hostname validation to fail when resolver and resolved hostnames are identical with three domain levels. +- Fixed a bug that caused direct use of ``pymongo.uri_parser`` to raise an ``AttributeError``. Issues Resolved ............... diff --git a/pymongo/__init__.py b/pymongo/__init__.py index e39250891..9a3575081 100644 --- a/pymongo/__init__.py +++ b/pymongo/__init__.py @@ -105,6 +105,9 @@ from pymongo.synchronous.collection import ReturnDocument from pymongo.synchronous.mongo_client import MongoClient from pymongo.write_concern import WriteConcern +# Public module compatibility imports +import pymongo.uri_parser # noqa: F401 # isort: skip + version = __version__ """Current version of PyMongo.""" diff --git a/test/test_default_exports.py b/test/test_default_exports.py index d9301d222..5f3e749d3 100644 --- a/test/test_default_exports.py +++ b/test/test_default_exports.py @@ -209,6 +209,13 @@ class TestDefaultExports(unittest.TestCase): ) from pymongo.write_concern import WriteConcern, validate_boolean + def test_pymongo_submodule_attributes(self): + import pymongo + + self.assertTrue(hasattr(pymongo, "uri_parser")) + self.assertTrue(pymongo.uri_parser) + self.assertTrue(pymongo.uri_parser.parse_uri) + def test_gridfs_imports(self): import gridfs from gridfs.errors import CorruptGridFile, FileExists, GridFSError, NoFile From b83389d6bce914e9b1283edcb1713a89317b300a Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 15 Apr 2025 14:44:09 -0500 Subject: [PATCH 2/2] PYTHON-5311 Create standard linux evergreen tasks (#2282) --- .evergreen/generated_configs/tasks.yml | 631 +++++++++++++++++++--- .evergreen/generated_configs/variants.yml | 6 +- .evergreen/scripts/generate_config.py | 65 +-- 3 files changed, 574 insertions(+), 128 deletions(-) diff --git a/.evergreen/generated_configs/tasks.yml b/.evergreen/generated_configs/tasks.yml index 8d80b113a..5b09ce20f 100644 --- a/.evergreen/generated_configs/tasks.yml +++ b/.evergreen/generated_configs/tasks.yml @@ -727,95 +727,6 @@ tasks: working_dir: src type: test - # Compression tests - - name: test-compression-v4.0-python3.9 - commands: - - func: run server - vars: - VERSION: "4.0" - - func: run tests - tags: [compression, "4.0"] - - name: test-compression-v4.2-python3.9 - commands: - - func: run server - vars: - VERSION: "4.2" - - func: run tests - tags: [compression, "4.2"] - - name: test-compression-v4.4-python3.9 - commands: - - func: run server - vars: - VERSION: "4.4" - - func: run tests - tags: [compression, "4.4"] - - name: test-compression-v5.0-python3.9 - commands: - - func: run server - vars: - VERSION: "5.0" - - func: run tests - tags: [compression, "5.0"] - - name: test-compression-v6.0-python3.9 - commands: - - func: run server - vars: - VERSION: "6.0" - - func: run tests - tags: [compression, "6.0"] - - name: test-compression-v7.0-python3.9 - commands: - - func: run server - vars: - VERSION: "7.0" - - func: run tests - tags: [compression, "7.0"] - - name: test-compression-v8.0-python3.9 - commands: - - func: run server - vars: - VERSION: "8.0" - - func: run tests - tags: [compression, "8.0"] - - name: test-compression-rapid-python3.9 - commands: - - func: run server - vars: - VERSION: rapid - - func: run tests - tags: [compression, rapid] - - name: test-compression-latest-python3.9 - commands: - - func: run server - vars: - VERSION: latest - - func: run tests - tags: [compression, latest] - - name: test-compression-latest-python3.13-no-c - commands: - - func: run server - vars: - VERSION: latest - - func: run tests - vars: - NO_EXT: "1" - tags: [compression, latest] - - name: test-compression-latest-python3.13 - commands: - - func: run server - vars: - VERSION: latest - - func: run tests - vars: {} - tags: [compression, latest] - - name: test-compression-latest-pypy3.10 - commands: - - func: run server - vars: - VERSION: latest - - func: run tests - tags: [compression, latest] - # Coverage report tests - name: coverage-report commands: @@ -8297,6 +8208,548 @@ tasks: SSL: ssl tags: [serverless] + # Standard linux tests + - name: test-v4.0-python3.9-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "4.0" + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "4.0" + PYTHON_VERSION: "3.9" + tags: + - standard-linux + - server-4.0 + - python-3.9 + - standalone-noauth-nossl + - name: test-v4.0-python3.10-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "4.0" + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "4.0" + PYTHON_VERSION: "3.10" + tags: + - standard-linux + - server-4.0 + - python-3.10 + - replica_set-noauth-ssl + - name: test-v4.0-python3.11-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "4.0" + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "4.0" + PYTHON_VERSION: "3.11" + tags: + - standard-linux + - server-4.0 + - python-3.11 + - sharded_cluster-auth-ssl + - name: test-v4.2-python3.12-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "4.2" + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "4.2" + PYTHON_VERSION: "3.12" + tags: + - standard-linux + - server-4.2 + - python-3.12 + - standalone-noauth-nossl + - name: test-v4.2-python3.13-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "4.2" + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "4.2" + PYTHON_VERSION: "3.13" + tags: + - standard-linux + - server-4.2 + - python-3.13 + - replica_set-noauth-ssl + - name: test-v4.2-pypy3.10-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "4.2" + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "4.2" + PYTHON_VERSION: pypy3.10 + tags: + - standard-linux + - server-4.2 + - python-pypy3.10 + - sharded_cluster-auth-ssl + - name: test-v4.4-python3.9-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "4.4" + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "4.4" + PYTHON_VERSION: "3.9" + tags: + - standard-linux + - server-4.4 + - python-3.9 + - standalone-noauth-nossl + - name: test-v4.4-python3.10-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "4.4" + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "4.4" + PYTHON_VERSION: "3.10" + tags: + - standard-linux + - server-4.4 + - python-3.10 + - replica_set-noauth-ssl + - name: test-v4.4-python3.11-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "4.4" + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "4.4" + PYTHON_VERSION: "3.11" + tags: + - standard-linux + - server-4.4 + - python-3.11 + - sharded_cluster-auth-ssl + - name: test-v5.0-python3.12-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "5.0" + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "5.0" + PYTHON_VERSION: "3.12" + tags: + - standard-linux + - server-5.0 + - python-3.12 + - standalone-noauth-nossl + - name: test-v5.0-python3.13-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "5.0" + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "5.0" + PYTHON_VERSION: "3.13" + tags: + - standard-linux + - server-5.0 + - python-3.13 + - replica_set-noauth-ssl + - name: test-v5.0-pypy3.10-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "5.0" + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "5.0" + PYTHON_VERSION: pypy3.10 + tags: + - standard-linux + - server-5.0 + - python-pypy3.10 + - sharded_cluster-auth-ssl + - name: test-v6.0-python3.9-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "6.0" + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "6.0" + PYTHON_VERSION: "3.9" + tags: + - standard-linux + - server-6.0 + - python-3.9 + - standalone-noauth-nossl + - name: test-v6.0-python3.10-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "6.0" + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "6.0" + PYTHON_VERSION: "3.10" + tags: + - standard-linux + - server-6.0 + - python-3.10 + - replica_set-noauth-ssl + - name: test-v6.0-python3.11-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "6.0" + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "6.0" + PYTHON_VERSION: "3.11" + tags: + - standard-linux + - server-6.0 + - python-3.11 + - sharded_cluster-auth-ssl + - name: test-v7.0-python3.12-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "7.0" + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "7.0" + PYTHON_VERSION: "3.12" + tags: + - standard-linux + - server-7.0 + - python-3.12 + - standalone-noauth-nossl + - name: test-v7.0-python3.13-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "7.0" + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "7.0" + PYTHON_VERSION: "3.13" + tags: + - standard-linux + - server-7.0 + - python-3.13 + - replica_set-noauth-ssl + - name: test-v7.0-pypy3.10-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "7.0" + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "7.0" + PYTHON_VERSION: pypy3.10 + tags: + - standard-linux + - server-7.0 + - python-pypy3.10 + - sharded_cluster-auth-ssl + - name: test-v8.0-python3.9-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "8.0" + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: "8.0" + PYTHON_VERSION: "3.9" + tags: + - standard-linux + - server-8.0 + - python-3.9 + - standalone-noauth-nossl + - name: test-v8.0-python3.10-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "8.0" + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: "8.0" + PYTHON_VERSION: "3.10" + tags: + - standard-linux + - server-8.0 + - python-3.10 + - replica_set-noauth-ssl + - name: test-v8.0-python3.11-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "8.0" + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: "8.0" + PYTHON_VERSION: "3.11" + tags: + - standard-linux + - server-8.0 + - python-3.11 + - sharded_cluster-auth-ssl + - name: test-rapid-python3.12-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: rapid + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: rapid + PYTHON_VERSION: "3.12" + tags: + - standard-linux + - server-rapid + - python-3.12 + - standalone-noauth-nossl + - name: test-rapid-python3.13-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: rapid + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: rapid + PYTHON_VERSION: "3.13" + tags: + - standard-linux + - server-rapid + - python-3.13 + - replica_set-noauth-ssl + - name: test-rapid-pypy3.10-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: rapid + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: rapid + PYTHON_VERSION: pypy3.10 + tags: + - standard-linux + - server-rapid + - python-pypy3.10 + - sharded_cluster-auth-ssl + - name: test-latest-python3.9-noauth-nossl-standalone + commands: + - func: run server + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: latest + - func: run tests + vars: + AUTH: noauth + SSL: nossl + TOPOLOGY: standalone + VERSION: latest + PYTHON_VERSION: "3.9" + tags: + - standard-linux + - server-latest + - python-3.9 + - standalone-noauth-nossl + - name: test-latest-python3.10-noauth-ssl-replica-set + commands: + - func: run server + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: latest + - func: run tests + vars: + AUTH: noauth + SSL: ssl + TOPOLOGY: replica_set + VERSION: latest + PYTHON_VERSION: "3.10" + tags: + - standard-linux + - server-latest + - python-3.10 + - replica_set-noauth-ssl + - name: test-latest-python3.11-auth-ssl-sharded-cluster + commands: + - func: run server + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: latest + - func: run tests + vars: + AUTH: auth + SSL: ssl + TOPOLOGY: sharded_cluster + VERSION: latest + PYTHON_VERSION: "3.11" + tags: + - standard-linux + - server-latest + - python-3.11 + - sharded_cluster-auth-ssl + # Standard non linux tests - name: test-v4.0-python3.9-sync-noauth-nossl-standalone commands: diff --git a/.evergreen/generated_configs/variants.yml b/.evergreen/generated_configs/variants.yml index 0ad366dbe..dc46ae6bf 100644 --- a/.evergreen/generated_configs/variants.yml +++ b/.evergreen/generated_configs/variants.yml @@ -163,7 +163,7 @@ buildvariants: # Compression tests - name: compression-snappy-rhel8 tasks: - - name: .compression + - name: .standard-linux display_name: Compression snappy RHEL8 run_on: - rhel87-small @@ -171,7 +171,7 @@ buildvariants: COMPRESSOR: snappy - name: compression-zlib-rhel8 tasks: - - name: .compression + - name: .standard-linux display_name: Compression zlib RHEL8 run_on: - rhel87-small @@ -179,7 +179,7 @@ buildvariants: COMPRESSOR: zlib - name: compression-zstd-rhel8 tasks: - - name: .compression !.4.0 + - name: .standard-linux !.server-4.0 display_name: Compression zstd RHEL8 run_on: - rhel87-small diff --git a/.evergreen/scripts/generate_config.py b/.evergreen/scripts/generate_config.py index e99a9a398..75ee52de6 100644 --- a/.evergreen/scripts/generate_config.py +++ b/.evergreen/scripts/generate_config.py @@ -211,13 +211,15 @@ def create_load_balancer_variants(): def create_compression_variants(): - # Compression tests - standalone versions of each server, across python versions. + # Compression tests - use the standard linux tests. host = DEFAULT_HOST - base_task = ".compression" variants = [] for compressor in "snappy", "zlib", "zstd": expansions = dict(COMPRESSOR=compressor) - tasks = [base_task] if compressor != "zstd" else [f"{base_task} !.4.0"] + if compressor == "zstd": + tasks = [".standard-linux !.server-4.0"] + else: + tasks = [".standard-linux"] display_name = get_variant_name(f"Compression {compressor}", host) variants.append( create_variant( @@ -613,6 +615,30 @@ def create_server_version_tasks(): return tasks +def create_standard_linux_tasks(): + tasks = [] + + for (version, topology), python in zip_cycle( + list(product(ALL_VERSIONS, TOPOLOGIES)), ALL_PYTHONS + ): + auth = "auth" if topology == "sharded_cluster" else "noauth" + ssl = "nossl" if topology == "standalone" else "ssl" + tags = [ + "standard-linux", + f"server-{version}", + f"python-{python}", + f"{topology}-{auth}-{ssl}", + ] + expansions = dict(AUTH=auth, SSL=ssl, TOPOLOGY=topology, VERSION=version) + name = get_task_name("test", python=python, **expansions) + server_func = FunctionCall(func="run server", vars=expansions) + test_vars = expansions.copy() + test_vars["PYTHON_VERSION"] = python + test_func = FunctionCall(func="run tests", vars=test_vars) + tasks.append(EvgTask(name=name, tags=tags, commands=[server_func, test_func])) + return tasks + + def create_standard_non_linux_tasks(): tasks = [] @@ -683,39 +709,6 @@ def create_load_balancer_tasks(): return tasks -def create_compression_tasks(): - tasks = [] - versions = get_versions_from("4.0") - # Test all server versions with min python. - for version in versions: - python = CPYTHONS[0] - tags = ["compression", version] - name = get_task_name("test-compression", python=python, version=version) - server_func = FunctionCall(func="run server", vars=dict(VERSION=version)) - test_func = FunctionCall(func="run tests") - tasks.append(EvgTask(name=name, tags=tags, commands=[server_func, test_func])) - - # Test latest with max python, with and without c exts. - version = "latest" - tags = ["compression", "latest"] - for c_ext in C_EXTS: - python = CPYTHONS[-1] - expansions = dict() - handle_c_ext(c_ext, expansions) - name = get_task_name("test-compression", python=python, version=version, **expansions) - server_func = FunctionCall(func="run server", vars=dict(VERSION=version)) - test_func = FunctionCall(func="run tests", vars=expansions) - tasks.append(EvgTask(name=name, tags=tags, commands=[server_func, test_func])) - - # Test on latest with pypy. - python = PYPYS[-1] - name = get_task_name("test-compression", python=python, version=version) - server_func = FunctionCall(func="run server", vars=dict(VERSION=version)) - test_func = FunctionCall(func="run tests") - tasks.append(EvgTask(name=name, tags=tags, commands=[server_func, test_func])) - return tasks - - def create_kms_tasks(): tasks = [] for kms_type in ["gcp", "azure"]: