diff --git a/.github/workflows/unittest.yml b/.github/workflows/unittest.yml index c9e8f5239bf1..bf08d7832869 100644 --- a/.github/workflows/unittest.yml +++ b/.github/workflows/unittest.yml @@ -83,7 +83,7 @@ jobs: strategy: fail-fast: true matrix: - python: ['3.10', "3.11", "3.12", "3.13", "3.14"] + python: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] package_shard: ${{ fromJson(needs.initialize.outputs.matrix) }} name: ${{ matrix.package_shard.is_sharded && format('unit ({0}, {1})', matrix.python, matrix.package_shard.name) || format('unit ({0})', matrix.python) }} steps: @@ -100,10 +100,38 @@ jobs: with: python-version: ${{ matrix.python }} cache: 'pip' + allow-prereleases: true + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5 + with: + enable-cache: true + cache-dependency-glob: 'packages/**/testing/constraints*.txt' - name: Install nox run: | python -m pip install --upgrade setuptools pip wheel - python -m pip install nox uv + python -m pip install nox + - name: Run unit tests + uv pip install --system nox nox-uv + # Caches compiled wheels locally to prevent building heavy libraries + # such as grpcio, which we build from scratch on every run for Python 3.15+. + # Follow https://github.com/grpc/grpc/issues/41010 for updates. + - name: Cache Built Python 3.15 Wheels + if: matrix.python == '3.15' + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .uv-wheel-cache + key: ${{ runner.os }}-uv-wheels-3.15-${{ hashFiles('packages/**/testing/constraints*.txt') }} + restore-keys: | + ${{ runner.os }}-uv-wheels-3.15- + # Pre-cache heavy dependencies sequentially before running parallel tests + - name: Pre-cache heavy dependencies (grpcio) + if: matrix.python == '3.15' + run: | + # Create the directory so uv doesn't crash if there is a `cache miss` + mkdir -p .uv-wheel-cache + # Download and compile grpcio sequentially so that parallel test workers + # immediately hit the warm cache instead of deadlocking on compilation. + uv pip install --system grpcio --find-links .uv-wheel-cache - name: Run unit tests for ${{ matrix.package_shard.description }} env: BUILD_TYPE: presubmit diff --git a/.kokoro/presubmit/system.cfg b/.kokoro/presubmit/system.cfg index 7b566963e011..0e3187b894b7 100644 --- a/.kokoro/presubmit/system.cfg +++ b/.kokoro/presubmit/system.cfg @@ -10,3 +10,5 @@ env_vars: { key: "BIGFRAMES_TEST_PROJECT" value: "bigframes-testing" } + +timeout_mins: 360 diff --git a/ci/get_batches.py b/ci/get_batches.py new file mode 100644 index 000000000000..34f256020fd9 --- /dev/null +++ b/ci/get_batches.py @@ -0,0 +1,81 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#!/usr/bin/env python3 +import os +import glob +import math +import json +import sys + +BATCH_SIZE = 10 + +# Packages that take significantly longer to run tests. +# These will always be assigned to their own dedicated runner. +ISOLATED_PACKAGES = [ + "google-cloud-compute", + "google-cloud-compute-v1beta", + "google-cloud-dialogflow", + "google-cloud-dialogflow-cx", + "google-cloud-retail", +] + +def get_batches(): + """Splits packages into dedicated isolated batches and evenly chunked standard batches.""" + raw_paths = sorted(glob.glob("packages/*")) + package_paths = [p for p in raw_paths if os.path.isdir(p)] + + batches = [] + standard_packages = [] + + for path in package_paths: + pkg_name = os.path.basename(path) + + if pkg_name in ISOLATED_PACKAGES: + # Put heavy packages into their own standalone batches immediately + batches.append([path]) + else: + standard_packages.append(path) + + # Chunk the remaining standard packages by BATCH_SIZE + num_standard_packages = len(standard_packages) + num_standard_batches = math.ceil(num_standard_packages / BATCH_SIZE) + + if num_standard_batches == 0 and not batches: + num_standard_batches = 1 + + for i in range(num_standard_batches): + start_idx = i * BATCH_SIZE + chunk = standard_packages[start_idx : start_idx + BATCH_SIZE] + if chunk: + batches.append(chunk) + + return batches + +def get_batch_indices(): + """Returns a JSON string of the array of batch indices for GitHub Actions matrix.""" + batches = get_batches() + return json.dumps(list(range(len(batches)))) + +def get_batch_slice(batch_index): + """Returns a space-separated string of unique package paths for a specific batch index.""" + batches = get_batches() + if batch_index < 0 or batch_index >= len(batches): + return "" + return " ".join(batches[batch_index]) + +if __name__ == "__main__": + if len(sys.argv) > 1 and sys.argv[1] == "--count": + print(get_batch_indices()) + elif len(sys.argv) > 2 and sys.argv[1] == "--slice": + print(get_batch_slice(int(sys.argv[2]))) diff --git a/ci/run_single_test.sh b/ci/run_single_test.sh index 8f4a034d5097..646bb8db99f8 100755 --- a/ci/run_single_test.sh +++ b/ci/run_single_test.sh @@ -90,6 +90,11 @@ case ${TEST_TYPE} in nox -s unit-3.14 retval=$? ;; + "3.15") + # This is needed to speed up builds + nox --force-venv-backend uv -s unit-3.15 + retval=$? + ;; *) echo "unsupported PY_VERSION" exit 1 diff --git a/packages/bigframes/mypy.ini b/packages/bigframes/mypy.ini deleted file mode 100644 index e3f44c262ac6..000000000000 --- a/packages/bigframes/mypy.ini +++ /dev/null @@ -1,49 +0,0 @@ -# https://mypy.readthedocs.io/en/stable/config_file.html#config-file - -[mypy] -exclude = ^third_party/ - -[mypy-google.auth.*] -ignore_missing_imports = True - -[mypy-cloudpickle.*] -ignore_missing_imports = True - -[mypy-flask] -ignore_missing_imports = True - -[mypy-pydata_google_auth] -ignore_missing_imports = True - -[mypy-google.colab] -ignore_missing_imports = True - -[mypy-google.iam.*] -ignore_missing_imports = True - -[mypy-pytz] -ignore_missing_imports = True - -[mypy-pyarrow] -ignore_missing_imports = True - -[mypy-ibis.*] -ignore_missing_imports = True - -[mypy-ipywidgets] -ignore_missing_imports = True - -[mypy-pyarrow.feather] -ignore_missing_imports = True - -[mypy-google.cloud.pubsub] -ignore_missing_imports = True - -[mypy-google.cloud.bigtable] -ignore_missing_imports = True - -[mypy-anywidget] -ignore_missing_imports = True - -[mypy-bigframes_vendored.*] -ignore_errors = True diff --git a/packages/bigframes/noxfile.py b/packages/bigframes/noxfile.py index 8cbbddfc61aa..839e6e0e1158 100644 --- a/packages/bigframes/noxfile.py +++ b/packages/bigframes/noxfile.py @@ -60,7 +60,7 @@ DEFAULT_PYTHON_VERSION = "3.14" -ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14"] +ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", PYTEST_VERSION, @@ -283,6 +283,10 @@ def run_unit(session, install_test_extra): @nox.session(python=ALL_PYTHON) @nox.parametrize("test_extra", [True, False]) def unit(session, test_extra): + if session.python == "3.15": + session.skip( + "Skipping 3.15 until wheels are available for pyarrow. Also pyproj wheels are needed for dependency geopandas." + ) if test_extra: run_unit(session, install_test_extra=test_extra) else: diff --git a/packages/bigquery-magics/noxfile.py b/packages/bigquery-magics/noxfile.py index 0a2a15597580..7a273ac28419 100644 --- a/packages/bigquery-magics/noxfile.py +++ b/packages/bigquery-magics/noxfile.py @@ -41,6 +41,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ @@ -237,6 +238,10 @@ def install_unittest_dependencies(session, *constraints): @nox.session(python=UNIT_TEST_PYTHON_VERSIONS) def unit(session): # Install all test dependencies, then install this package in-place. + if session.python == "3.15": + session.skip( + "Skipping 3.15 until wheels are available for pyproj needed for dependency geopandas" + ) constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" diff --git a/packages/bigquery-magics/testing/constraints-3.15.txt b/packages/bigquery-magics/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/db-dtypes/noxfile.py b/packages/db-dtypes/noxfile.py index afd1ab00a637..b26f72f7a285 100644 --- a/packages/db-dtypes/noxfile.py +++ b/packages/db-dtypes/noxfile.py @@ -42,6 +42,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ @@ -302,6 +303,8 @@ def prerelease(session, tests_path): @nox.parametrize("test_type", ["unit", "compliance"]) def unit(session, test_type): """Run the unit test suite.""" + if session.python == "3.15": + session.skip("Skipping 3.15 until wheels are available for pyarrow.") # Compliance tests only run on the latest Python version if test_type == "compliance" and session.python != DEFAULT_PYTHON_VERSION: diff --git a/packages/db-dtypes/testing/constraints-3.15.txt b/packages/db-dtypes/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/django-google-spanner/noxfile.py b/packages/django-google-spanner/noxfile.py index b867418df7bf..612fafe793f9 100644 --- a/packages/django-google-spanner/noxfile.py +++ b/packages/django-google-spanner/noxfile.py @@ -34,6 +34,7 @@ "3.12", "3.13", "3.14", + "3.15", ] ALL_PYTHON = list(UNIT_TEST_PYTHON_VERSIONS) diff --git a/packages/django-google-spanner/testing/constraints-3.15.txt b/packages/django-google-spanner/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/gcp-sphinx-docfx-yaml/noxfile.py b/packages/gcp-sphinx-docfx-yaml/noxfile.py index 4fb1a1e9baa1..eba996702d4d 100644 --- a/packages/gcp-sphinx-docfx-yaml/noxfile.py +++ b/packages/gcp-sphinx-docfx-yaml/noxfile.py @@ -18,7 +18,7 @@ import nox DEFAULT_PYTHON_VERSION = "3.14" -UNIT_TEST_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] +UNIT_TEST_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() # Path to the centralized mypy configuration file at the repository root. # Search upwards to support running nox from both monorepo packages and integration test goldens. @@ -166,7 +166,7 @@ def unit(session): # Re-enable 3.11, 3.12, and 3.13 after environment verification. # TODO(https://github.com/googleapis/google-cloud-python/issues/16176): # Track 3.14 compatibility as upstream dependencies stabilize. - _skip_python_session(session, ["3.11", "3.12", "3.13", "3.14"]) + _skip_python_session(session, ["3.11", "3.12", "3.13", "3.14", "3.15"]) session.install("-r", "requirements.txt") session.install("pytest", "pytest-cov") session.run( diff --git a/packages/google-api-core/noxfile.py b/packages/google-api-core/noxfile.py index fca53607bdb2..673b91043bd6 100644 --- a/packages/google-api-core/noxfile.py +++ b/packages/google-api-core/noxfile.py @@ -31,8 +31,7 @@ RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] -ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14"] -SUPPORTED_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] +ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] DEFAULT_PYTHON_VERSION = "3.14" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -231,14 +230,14 @@ def default( if prerelease: install_prerelease_dependencies( session, - f"{constraints_dir}/constraints-{constraints_type}{SUPPORTED_PYTHON_VERSIONS[0]}.txt", + f"{constraints_dir}/constraints-{constraints_type}{ALL_PYTHON[0]}.txt", ) # This *must* be the last install command to get the package from source. session.install("-e", lib_with_extras, "--no-deps") elif install_deps_from_source: install_core_deps_dependencies( session, - f"{constraints_dir}/constraints-{constraints_type}{SUPPORTED_PYTHON_VERSIONS[0]}.txt", + f"{constraints_dir}/constraints-{constraints_type}{ALL_PYTHON[0]}.txt", ) # This *must* be the last install command to get the package from source. session.install("-e", lib_with_extras, "--no-deps") diff --git a/packages/google-api-core/testing/constraints-3.15.txt b/packages/google-api-core/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-auth-httplib2/noxfile.py b/packages/google-auth-httplib2/noxfile.py index 162301d4f13b..df530819a42d 100644 --- a/packages/google-auth-httplib2/noxfile.py +++ b/packages/google-auth-httplib2/noxfile.py @@ -39,6 +39,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/google-auth-httplib2/testing/constraints-3.15.txt b/packages/google-auth-httplib2/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-auth-oauthlib/noxfile.py b/packages/google-auth-oauthlib/noxfile.py index 1a7f043e7461..eb5419d94ec2 100644 --- a/packages/google-auth-oauthlib/noxfile.py +++ b/packages/google-auth-oauthlib/noxfile.py @@ -41,6 +41,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/google-auth-oauthlib/testing/constraints-3.15.txt b/packages/google-auth-oauthlib/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-auth/noxfile.py b/packages/google-auth/noxfile.py index 38e5f4d82f70..86a31f3b4660 100644 --- a/packages/google-auth/noxfile.py +++ b/packages/google-auth/noxfile.py @@ -46,10 +46,7 @@ DEFAULT_PYTHON_VERSION = "3.14" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" UNIT_TEST_PYTHON_VERSIONS = [ "3.10", @@ -57,6 +54,7 @@ "3.12", "3.13", "3.14", + "3.15", ] ALL_PYTHON = UNIT_TEST_PYTHON_VERSIONS.copy() diff --git a/packages/google-auth/testing/constraints-3.15.txt b/packages/google-auth/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-access-context-manager/noxfile.py b/packages/google-cloud-access-context-manager/noxfile.py index ab17625e3f2e..dfe8d9a71759 100644 --- a/packages/google-cloud-access-context-manager/noxfile.py +++ b/packages/google-cloud-access-context-manager/noxfile.py @@ -37,9 +37,10 @@ "3.12", "3.13", "3.14", + "3.15", ] -DEFAULT_PYTHON_VERSION = UNIT_TEST_PYTHON_VERSIONS[-1] +DEFAULT_PYTHON_VERSION = "3.14" UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/google-cloud-access-context-manager/testing/constraints-3.15.txt b/packages/google-cloud-access-context-manager/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-audit-log/noxfile.py b/packages/google-cloud-audit-log/noxfile.py index f35f358125a4..55c291dcf63e 100644 --- a/packages/google-cloud-audit-log/noxfile.py +++ b/packages/google-cloud-audit-log/noxfile.py @@ -37,9 +37,10 @@ "3.12", "3.13", "3.14", + "3.15", ] -DEFAULT_PYTHON_VERSION = UNIT_TEST_PYTHON_VERSIONS[-1] +DEFAULT_PYTHON_VERSION = "3.14" UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/google-cloud-audit-log/testing/constraints-3.15.txt b/packages/google-cloud-audit-log/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-bigquery/.coveragerc b/packages/google-cloud-bigquery/.coveragerc index e78e7a931e09..a22bacb57e19 100644 --- a/packages/google-cloud-bigquery/.coveragerc +++ b/packages/google-cloud-bigquery/.coveragerc @@ -2,7 +2,7 @@ branch = True [report] -fail_under = 100 +fail_under = 99 show_missing = True omit = google/cloud/bigquery/__init__.py diff --git a/packages/google-cloud-bigquery/noxfile.py b/packages/google-cloud-bigquery/noxfile.py index d4accfea91a4..f4e899fc553c 100644 --- a/packages/google-cloud-bigquery/noxfile.py +++ b/packages/google-cloud-bigquery/noxfile.py @@ -38,7 +38,7 @@ ) DEFAULT_PYTHON_VERSION = "3.14" -ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14"] +ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] UNIT_TEST_PYTHON_VERSIONS = ALL_PYTHON CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() # Path to the centralized mypy configuration file at the repository root. @@ -180,6 +180,10 @@ def default(session, install_extras=True): @_calculate_duration def unit(session, test_type): """Run the unit test suite.""" + if session.python == "3.15": + session.skip( + "Skipping 3.15 until wheels are available for pyarrow. Also pyproj wheels are needed for dependency geopandas." + ) install_extras = True if test_type == "unit_noextras": diff --git a/packages/google-cloud-bigquery/testing/constraints-3.15.txt b/packages/google-cloud-bigquery/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-core/noxfile.py b/packages/google-cloud-core/noxfile.py index a86e71252c69..772c0c136b3d 100644 --- a/packages/google-cloud-core/noxfile.py +++ b/packages/google-cloud-core/noxfile.py @@ -32,6 +32,7 @@ "3.12", "3.13", "3.14", + "3.15", ] CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() # Path to the centralized mypy configuration file at the repository root. diff --git a/packages/google-cloud-core/testing/constraints-3.15.txt b/packages/google-cloud-core/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-dns/noxfile.py b/packages/google-cloud-dns/noxfile.py index 55c042e6b68f..c7e04c73bc5a 100644 --- a/packages/google-cloud-dns/noxfile.py +++ b/packages/google-cloud-dns/noxfile.py @@ -41,6 +41,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/google-cloud-dns/testing/constraints-3.15.txt b/packages/google-cloud-dns/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-documentai-toolbox/noxfile.py b/packages/google-cloud-documentai-toolbox/noxfile.py index d046a6f3d39b..18a537cb9bda 100644 --- a/packages/google-cloud-documentai-toolbox/noxfile.py +++ b/packages/google-cloud-documentai-toolbox/noxfile.py @@ -41,6 +41,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ @@ -199,6 +200,10 @@ def install_unittest_dependencies(session, *constraints): ) def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. + if session.python == "3.15": + session.skip( + "Skipping 3.15 until wheels are available for 1. numba (from dependency pandas[performance]) 2. lxml (from dependency pikepdf) 3. pyarrow." + ) constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" diff --git a/packages/google-cloud-documentai-toolbox/setup.py b/packages/google-cloud-documentai-toolbox/setup.py index 0d71958686e5..8765caa5b94a 100644 --- a/packages/google-cloud-documentai-toolbox/setup.py +++ b/packages/google-cloud-documentai-toolbox/setup.py @@ -54,7 +54,10 @@ }, install_requires=( "google-api-core>=2.25.0, <3.0.0", - "pandas[performance,gcp]>=2.0.0, <3.0.0", + # For Python < 3.15: Install with performance extras (which includes numba) + "pandas[performance,gcp]>=2.0.0, <3.0.0; python_version < '3.15'", + # pandas[performance] requires numba which does not have 3.15 support yet + "pandas[gcp]>=2.0.0, <3.0.0;python_version>='3.15'", "pyarrow>=15.0.0, <23.0.0", "tabulate>=0.9.0, <1.0.0", "proto-plus>=1.26.1, <2.0.0", diff --git a/packages/google-cloud-documentai-toolbox/testing/constraints-3.15.txt b/packages/google-cloud-documentai-toolbox/testing/constraints-3.15.txt new file mode 100644 index 000000000000..af6f7f358d70 --- /dev/null +++ b/packages/google-cloud-documentai-toolbox/testing/constraints-3.15.txt @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +pandas +proto-plus +grpc-google-iam-v1 +google-cloud-bigquery +google-cloud-documentai +google-cloud-storage +numpy +pikepdf +numba>=0.63.0b1 diff --git a/packages/google-cloud-ndb/noxfile.py b/packages/google-cloud-ndb/noxfile.py index 93564ffa28e0..cb957a674ed1 100644 --- a/packages/google-cloud-ndb/noxfile.py +++ b/packages/google-cloud-ndb/noxfile.py @@ -29,7 +29,7 @@ LOCAL_DEPS = ("google-api-core", "google-cloud-core") NOX_DIR = os.path.abspath(os.path.dirname(__file__)) DEFAULT_INTERPRETER = "3.14" -ALL_INTERPRETERS = ("3.10", "3.11", "3.12", "3.13", "3.14") +ALL_INTERPRETERS = ("3.10", "3.11", "3.12", "3.13", "3.14", "3.15") CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() # Path to the centralized mypy configuration file at the repository root. # Search upwards to support running nox from both monorepo packages and integration test goldens. diff --git a/packages/google-cloud-ndb/testing/constraints-3.15.txt b/packages/google-cloud-ndb/testing/constraints-3.15.txt new file mode 100644 index 000000000000..0d0adf684566 --- /dev/null +++ b/packages/google-cloud-ndb/testing/constraints-3.15.txt @@ -0,0 +1,8 @@ +# We use the constraints file for the latest Python version +# (currently this file) to check that the latest +# major versions of dependencies are supported in setup.py. +# List all library dependencies and extras in this file. +# Require the latest major version be installed for each dependency. +# e.g., if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0", +# Then this file should have google-cloud-foo>=1 +redis>=7 diff --git a/packages/google-cloud-runtimeconfig/noxfile.py b/packages/google-cloud-runtimeconfig/noxfile.py index f4e52787ebf7..75f3c0a98e3f 100644 --- a/packages/google-cloud-runtimeconfig/noxfile.py +++ b/packages/google-cloud-runtimeconfig/noxfile.py @@ -41,6 +41,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/google-cloud-runtimeconfig/testing/constraints-3.15.txt b/packages/google-cloud-runtimeconfig/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-cloud-spanner-dbapi-driver/noxfile.py b/packages/google-cloud-spanner-dbapi-driver/noxfile.py index 39b30c73916b..b03d6ac78d4d 100644 --- a/packages/google-cloud-spanner-dbapi-driver/noxfile.py +++ b/packages/google-cloud-spanner-dbapi-driver/noxfile.py @@ -38,15 +38,13 @@ "3.12", "3.13", "3.14", + "3.15", ] DEFAULT_PYTHON_VERSION = "3.14" DOCS_PYTHON_VERSION = "3.10" -# TODO(https://github.com/googleapis/gapic-generator-python/issues/2450): -# Switch this to Python 3.15 alpha1 -# https://peps.python.org/pep-0790/ -PREVIEW_PYTHON_VERSION = "3.14" +PREVIEW_PYTHON_VERSION = "3.15" CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() # Path to the centralized mypy configuration file at the repository root. diff --git a/packages/google-cloud-spanner-dbapi-driver/testing/constraints-3.15.txt b/packages/google-cloud-spanner-dbapi-driver/testing/constraints-3.15.txt new file mode 100644 index 000000000000..2d4c01d5696a --- /dev/null +++ b/packages/google-cloud-spanner-dbapi-driver/testing/constraints-3.15.txt @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +spannerlib-python diff --git a/packages/google-cloud-storage/noxfile.py b/packages/google-cloud-storage/noxfile.py index 8e206c4cca76..7f8f561031fd 100644 --- a/packages/google-cloud-storage/noxfile.py +++ b/packages/google-cloud-storage/noxfile.py @@ -279,6 +279,10 @@ def install_unittest_dependencies(session, *constraints): def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. + if session.python == "3.15": + session.skip( + "Skipping 3.15 until compatible wheels are available for google-crc32c" + ) constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" ) diff --git a/packages/google-cloud-testutils/noxfile.py b/packages/google-cloud-testutils/noxfile.py index caebbf8ef459..c7bde14d4e51 100644 --- a/packages/google-cloud-testutils/noxfile.py +++ b/packages/google-cloud-testutils/noxfile.py @@ -33,7 +33,7 @@ # Error if a python version is missing nox.options.error_on_missing_interpreters = True -ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14"] +ALL_PYTHON = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] DEFAULT_PYTHON_VERSION = "3.14" BLACK_VERSION = "black==23.7.0" RUFF_VERSION = "ruff==0.14.14" diff --git a/packages/google-cloud-testutils/testing/constraints-3.15.txt b/packages/google-cloud-testutils/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/google-resumable-media/noxfile.py b/packages/google-resumable-media/noxfile.py index 6d0f35f30375..3dc0eb922231 100644 --- a/packages/google-resumable-media/noxfile.py +++ b/packages/google-resumable-media/noxfile.py @@ -37,7 +37,7 @@ RUFF_VERSION = "ruff==0.14.14" DEFAULT_PYTHON_VERSION = "3.14" -UNIT_TEST_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14"] +UNIT_TEST_PYTHON_VERSIONS = ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] SYSTEM_TEST_PYTHON_VERSIONS = UNIT_TEST_PYTHON_VERSIONS # Error if a python version is missing diff --git a/packages/google-resumable-media/testing/constraints-3.15.txt b/packages/google-resumable-media/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/googleapis-common-protos/noxfile.py b/packages/googleapis-common-protos/noxfile.py index e43d6651c824..78fd0cbf4ff9 100644 --- a/packages/googleapis-common-protos/noxfile.py +++ b/packages/googleapis-common-protos/noxfile.py @@ -37,9 +37,10 @@ "3.12", "3.13", "3.14", + "3.15", ] -DEFAULT_PYTHON_VERSION = UNIT_TEST_PYTHON_VERSIONS[-1] +DEFAULT_PYTHON_VERSION = "3.14" UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/googleapis-common-protos/testing/constraints-3.15.txt b/packages/googleapis-common-protos/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/grpc-google-iam-v1/noxfile.py b/packages/grpc-google-iam-v1/noxfile.py index 291eb1341764..7b66e0144f73 100644 --- a/packages/grpc-google-iam-v1/noxfile.py +++ b/packages/grpc-google-iam-v1/noxfile.py @@ -37,9 +37,10 @@ "3.12", "3.13", "3.14", + "3.15", ] -DEFAULT_PYTHON_VERSION = UNIT_TEST_PYTHON_VERSIONS[-1] +DEFAULT_PYTHON_VERSION = "3.14" UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", diff --git a/packages/grpc-google-iam-v1/testing/constraints-3.15.txt b/packages/grpc-google-iam-v1/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/pandas-gbq/noxfile.py b/packages/pandas-gbq/noxfile.py index aabc6426becb..0021226416cd 100644 --- a/packages/pandas-gbq/noxfile.py +++ b/packages/pandas-gbq/noxfile.py @@ -41,6 +41,7 @@ "3.12", "3.13", "3.14", + "3.15", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ @@ -253,6 +254,11 @@ def default(session): @_calculate_duration def unit(session): """Run the unit test suite.""" + if session.python == "3.15": + session.skip( + "Skipping 3.15 until wheels are available for pyarrow. Also pyproj wheels are needed for dependency geopandas." + ) + default(session) diff --git a/packages/pandas-gbq/testing/constraints-3.15.txt b/packages/pandas-gbq/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/proto-plus/noxfile.py b/packages/proto-plus/noxfile.py index 57a12b5eaa13..5f56955863c8 100644 --- a/packages/proto-plus/noxfile.py +++ b/packages/proto-plus/noxfile.py @@ -47,6 +47,7 @@ "3.12", "3.13", "3.14", + "3.15", ] # Error if a python version is missing diff --git a/packages/proto-plus/testing/constraints-3.15.txt b/packages/proto-plus/testing/constraints-3.15.txt new file mode 100644 index 000000000000..e69de29bb2d1