diff --git a/.evergreen/run-tests.sh b/.evergreen/run-tests.sh index a9f2ba2b5c..ec3746b29c 100755 --- a/.evergreen/run-tests.sh +++ b/.evergreen/run-tests.sh @@ -25,11 +25,7 @@ else exit 1 fi -# List the packages. -uv sync ${UV_ARGS} --reinstall --quiet -uv pip list - # Start the test runner. -uv run ${UV_ARGS} .evergreen/scripts/run_tests.py "$@" +uv run ${UV_ARGS} --reinstall .evergreen/scripts/run_tests.py "$@" popd diff --git a/.evergreen/scripts/generate_config_utils.py b/.evergreen/scripts/generate_config_utils.py index 632d34ea6f..26fe753e8c 100644 --- a/.evergreen/scripts/generate_config_utils.py +++ b/.evergreen/scripts/generate_config_utils.py @@ -273,7 +273,7 @@ def generate_yaml(tasks=None, variants=None): out = ShrubService.generate_yaml(project) # Dedent by two spaces to match what we use in config.yml lines = [line[2:] for line in out.splitlines()] - print("\n".join(lines)) # noqa: T201 + print("\n".join(lines)) ################## diff --git a/.evergreen/scripts/resync-all-specs.py b/.evergreen/scripts/resync-all-specs.py index 0817e2fc3b..80aafa8af1 100644 --- a/.evergreen/scripts/resync-all-specs.py +++ b/.evergreen/scripts/resync-all-specs.py @@ -11,7 +11,7 @@ def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> None: """Actually sync the specs""" - print("Beginning to sync specs") # noqa: T201 + print("Beginning to sync specs") for spec in os.scandir(directory): if not spec.is_dir(): continue @@ -27,11 +27,11 @@ def resync_specs(directory: pathlib.Path, errored: dict[str, str]) -> None: ) except CalledProcessError as exc: errored[spec.name] = exc.stderr - print("Done syncing specs") # noqa: T201 + print("Done syncing specs") def apply_patches(): - print("Beginning to apply patches") # noqa: T201 + print("Beginning to apply patches") subprocess.run(["bash", "./.evergreen/remove-unimplemented-tests.sh"], check=True) # noqa: S603, S607 subprocess.run( ["git apply -R --allow-empty --whitespace=fix ./.evergreen/spec-patch/*"], # noqa: S607 @@ -96,7 +96,7 @@ def write_summary(errored: dict[str, str], new: list[str], filename: Optional[st pr_body += "\n" if pr_body != "": if filename is None: - print(f"\n{pr_body}") # noqa: T201 + print(f"\n{pr_body}") else: with open(filename, "w") as f: # replacements made for proper json diff --git a/.evergreen/scripts/run_tests.py b/.evergreen/scripts/run_tests.py index 5c1ba25a97..3a1c15a41b 100644 --- a/.evergreen/scripts/run_tests.py +++ b/.evergreen/scripts/run_tests.py @@ -10,6 +10,12 @@ from pathlib import Path from shutil import which +try: + import importlib_metadata +except ImportError: + from importlib import metadata as importlib_metadata + + import pytest from utils import DRIVERS_TOOLS, LOGGER, ROOT, run_command @@ -23,6 +29,21 @@ SUB_TEST_NAME = os.environ.get("SUB_TEST_NAME") +def list_packages(): + packages = dict() + for distribution in importlib_metadata.distributions(): + packages[distribution.name] = distribution + print("Package Version URL") + print("------------------- ----------- ----------------------------------------------------") + for name in sorted(packages): + distribution = packages[name] + url = "" + if distribution.origin is not None: + url = distribution.origin.url + print(f"{name:20s}{distribution.version:12s}{url}") + print("------------------- ----------- ----------------------------------------------------\n") + + def handle_perf(start_time: datetime): end_time = datetime.now() elapsed_secs = (end_time - start_time).total_seconds() @@ -121,6 +142,9 @@ def handle_aws_lambda() -> None: def run() -> None: + # List the installed packages. + list_packages() + # Handle green framework first so they can patch modules. if GREEN_FRAMEWORK: handle_green_framework() diff --git a/.evergreen/scripts/setup_tests.py b/.evergreen/scripts/setup_tests.py index 9f383d9425..9c0d824ced 100644 --- a/.evergreen/scripts/setup_tests.py +++ b/.evergreen/scripts/setup_tests.py @@ -356,7 +356,9 @@ def handle_test_env() -> None: setup_libmongocrypt() # TODO: Test with 'pip install pymongocrypt' - UV_ARGS.append("--group pymongocrypt_source") + UV_ARGS.append( + "--with pymongocrypt@git+https://github.com/mongodb/libmongocrypt@master#subdirectory=bindings/python" + ) # Use the nocrypto build to avoid dependency issues with older windows/python versions. BASE = ROOT / "libmongocrypt/nocrypto" diff --git a/pyproject.toml b/pyproject.toml index fe277d8ed0..cc3e4e8582 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,9 +60,6 @@ coverage = [ mockupdb = [ "mockupdb@git+https://github.com/mongodb-labs/mongo-mockup-db@master" ] -pymongocrypt_source = [ - "pymongocrypt@git+https://github.com/mongodb/libmongocrypt@master#subdirectory=bindings/python" -] perf = ["simplejson"] typing = [ "mypy==1.18.1", @@ -239,6 +236,7 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?)|dummy.*)$" [tool.ruff.lint.per-file-ignores] "pymongo/__init__.py" = ["E402"] +".evergreen/scripts/*.py" = ["T201"] "test/*.py" = ["PT", "E402", "PLW", "SIM", "E741", "PTH", "S", "B904", "E722", "T201", "RET", "ARG", "F405", "B028", "PGH001", "B018", "F403", "RUF015", "E731", "B007", "UP031", "F401", "B023", "F811"] diff --git a/requirements/test.txt b/requirements/test.txt index 135114feff..566cade7ec 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,2 +1,3 @@ pytest>=8.2 pytest-asyncio>=0.24.0 +importlib_metadata>=7.0;python_version < "3.13" diff --git a/uv.lock b/uv.lock index ff7bd6fe24..ce0367e872 100644 --- a/uv.lock +++ b/uv.lock @@ -932,7 +932,7 @@ name = "importlib-metadata" version = "8.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "zipp", marker = "python_full_version < '3.10'" }, + { name = "zipp", marker = "python_full_version != '3.14.*'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } wheels = [ @@ -1261,6 +1261,7 @@ snappy = [ { name = "python-snappy" }, ] test = [ + { name = "importlib-metadata", marker = "python_full_version < '3.13'" }, { name = "pytest" }, { name = "pytest-asyncio" }, ] @@ -1292,9 +1293,6 @@ perf = [ pip = [ { name = "pip" }, ] -pymongocrypt-source = [ - { name = "pymongocrypt" }, -] typing = [ { name = "mypy" }, { name = "pip" }, @@ -1309,6 +1307,7 @@ requires-dist = [ { name = "cryptography", marker = "extra == 'ocsp'", specifier = ">=2.5" }, { name = "dnspython", specifier = ">=1.16.0,<3.0.0" }, { name = "furo", marker = "extra == 'docs'", specifier = "==2025.7.19" }, + { name = "importlib-metadata", marker = "python_full_version < '3.13' and extra == 'test'", specifier = ">=7.0" }, { name = "pykerberos", marker = "os_name != 'nt' and extra == 'gssapi'" }, { name = "pymongo-auth-aws", marker = "extra == 'aws'", specifier = ">=1.1.0,<2.0.0" }, { name = "pymongo-auth-aws", marker = "extra == 'encryption'", specifier = ">=1.1.0,<2.0.0" }, @@ -1343,7 +1342,6 @@ gevent = [ mockupdb = [{ name = "mockupdb", git = "https://github.com/mongodb-labs/mongo-mockup-db?rev=master" }] perf = [{ name = "simplejson" }] pip = [{ name = "pip" }] -pymongocrypt-source = [{ name = "pymongocrypt", git = "https://github.com/mongodb/libmongocrypt?subdirectory=bindings%2Fpython&rev=master" }] typing = [ { name = "mypy", specifier = "==1.18.1" }, { name = "pip" }, @@ -1366,8 +1364,8 @@ wheels = [ [[package]] name = "pymongocrypt" -version = "1.17.0.dev0" -source = { git = "https://github.com/mongodb/libmongocrypt?subdirectory=bindings%2Fpython&rev=master#36a6beafc99efdbe990ece675573ef581d151c92" } +version = "1.16.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version != '3.14.*'" }, { name = "cffi", version = "2.0.0b1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.14.*'" }, @@ -1375,6 +1373,13 @@ dependencies = [ { name = "httpx" }, { name = "packaging" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/dd9ed710e8fd4eec127dac1db3b3e9156ffcf340a0463a82087a12ae924e/pymongocrypt-1.16.0.tar.gz", hash = "sha256:0db0812055d00e6f5562a8d66711c4cba4b75014c363306c9b298a9fd68fccdd", size = 65354, upload-time = "2025-09-09T18:54:25.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/8b/dda0f19ce16f7b257e4aa2a8831a1a1307c1ea124a00f571cda83a04adcb/pymongocrypt-1.16.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:fbd85534880ea8525956b96e583a7021c721abbf3b51a6dbe48a57d7eba8e74a", size = 4721169, upload-time = "2025-09-09T18:54:18.642Z" }, + { url = "https://files.pythonhosted.org/packages/99/48/512a5b597d71407f9b06a14cd8e5ac376e06b780d4d54a4e69726bd48703/pymongocrypt-1.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:85df0a78480e91bdd3a5a6da3e4cdc7d9700de8a871aa8168588981c041f1914", size = 4038242, upload-time = "2025-09-09T18:54:20.496Z" }, + { url = "https://files.pythonhosted.org/packages/3f/67/3bdeda347191d6c1ee257eb3da8c85f1278d86dfb493cc9bc26352a41d0a/pymongocrypt-1.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8d2ebeb1b5e4f4554bf44f726e8009c59c4d7d0b412beebfece875991714676", size = 3775742, upload-time = "2025-09-09T18:54:22.254Z" }, + { url = "https://files.pythonhosted.org/packages/dc/81/70f6947afbd1ac7be54482b44cb1b99e8e9b9cac41985e6250c4fc279e58/pymongocrypt-1.16.0-py3-none-win_amd64.whl", hash = "sha256:c20afcd89ec5fc53305e924c05c4a0321ddc73f1e4e7c8240ee2fd0123e23609", size = 1607917, upload-time = "2025-09-09T18:54:24.182Z" }, +] [[package]] name = "pyopenssl"