From 064df21f1bf0b37b689c4b60908bbf3818e87034 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 14 Apr 2026 08:42:00 -0400 Subject: [PATCH 1/7] chore: updates noxfiles with RUFF version and format session --- packages/bigframes/noxfile.py | 9 +++++ packages/google-cloud-bigquery/noxfile.py | 33 +++++++++++++------ packages/google-cloud-ndb/noxfile.py | 29 +++++++++++++++++ packages/google-cloud-storage/noxfile.py | 1 + packages/google-crc32c/noxfile.py | 24 +++++++++----- packages/google-resumable-media/noxfile.py | 38 ++++++++++++++++++++++ packages/pandas-gbq/noxfile.py | 25 +++++++++----- packages/sqlalchemy-bigquery/noxfile.py | 25 ++++++++------ packages/sqlalchemy-spanner/noxfile.py | 33 +++++++++++++++---- 9 files changed, 174 insertions(+), 43 deletions(-) diff --git a/packages/bigframes/noxfile.py b/packages/bigframes/noxfile.py index 537d417e9145..cfd0315727f6 100644 --- a/packages/bigframes/noxfile.py +++ b/packages/bigframes/noxfile.py @@ -191,6 +191,15 @@ def format(session): *LINT_PATHS, ) + # 3. Run Ruff to format code + session.run( + "ruff", + "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", # Standard Black line length + *LINT_PATHS, + ) + @nox.session(python=DEFAULT_PYTHON_VERSION) def lint_setup_py(session): diff --git a/packages/google-cloud-bigquery/noxfile.py b/packages/google-cloud-bigquery/noxfile.py index 2ad39b26263a..b759b4416f06 100644 --- a/packages/google-cloud-bigquery/noxfile.py +++ b/packages/google-cloud-bigquery/noxfile.py @@ -25,6 +25,7 @@ MYPY_VERSION = "mypy==1.6.1" BLACK_VERSION = "black==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.10.1" BLACK_PATHS = ( "benchmark", @@ -550,16 +551,28 @@ def core_deps_from_source(session): session.skip("Core deps from source tests are not yet supported") -@nox.session -def format(session: nox.sessions.Session) -> None: +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - python_files = [path for path in os.listdir(".") if path.endswith(".py")] + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections - session.run("isort", "--fss", *python_files) - session.run("black", *python_files) + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) diff --git a/packages/google-cloud-ndb/noxfile.py b/packages/google-cloud-ndb/noxfile.py index b457368bb75f..11262f503edf 100644 --- a/packages/google-cloud-ndb/noxfile.py +++ b/packages/google-cloud-ndb/noxfile.py @@ -33,6 +33,7 @@ CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", "asyncmock", @@ -58,6 +59,7 @@ "emulator-system", "lint", "blacken", + "format", "docs", "doctest", "system", @@ -278,6 +280,33 @@ def blacken(session): run_black(session) +@nox.session(py=DEFAULT_INTERPRETER) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", + "--line-length=88", + "docs", "noxfile.py", "google", "tests", + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", + "--line-length=88", + "docs", "noxfile.py", "google", "tests", + ) + + @nox.session(py="3.10") def docs(session): """Build the docs for this library.""" diff --git a/packages/google-cloud-storage/noxfile.py b/packages/google-cloud-storage/noxfile.py index 909f0f3b8656..7fcaa389abdd 100644 --- a/packages/google-cloud-storage/noxfile.py +++ b/packages/google-cloud-storage/noxfile.py @@ -89,6 +89,7 @@ "lint", "lint_setup_py", "blacken", + "format", "docs", ] diff --git a/packages/google-crc32c/noxfile.py b/packages/google-crc32c/noxfile.py index b58397c9e0b4..110d2316debf 100644 --- a/packages/google-crc32c/noxfile.py +++ b/packages/google-crc32c/noxfile.py @@ -31,6 +31,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["src", "tests", "noxfile.py", "setup.py"] @@ -116,19 +117,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/google-resumable-media/noxfile.py b/packages/google-resumable-media/noxfile.py index 84fb6a492e72..3fc656368485 100644 --- a/packages/google-resumable-media/noxfile.py +++ b/packages/google-resumable-media/noxfile.py @@ -36,6 +36,7 @@ "blacken", "mypy", "doctest", + "format", ] @@ -240,6 +241,43 @@ def blacken(session): ) +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + os.path.join("google", "resumable_media"), + "tests", + os.path.join("google", "_async_resumable_media"), + "tests_async", + "noxfile.py", + "setup.py", + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + os.path.join("google", "resumable_media"), + "tests", + os.path.join("google", "_async_resumable_media"), + "tests_async", + "noxfile.py", + "setup.py", + ) + + @nox.session(python=DEFAULT_PYTHON_VERSION) def mypy(session): """Verify type hints are mypy compatible.""" diff --git a/packages/pandas-gbq/noxfile.py b/packages/pandas-gbq/noxfile.py index b85e92602aeb..748e5a4d69f3 100644 --- a/packages/pandas-gbq/noxfile.py +++ b/packages/pandas-gbq/noxfile.py @@ -29,6 +29,7 @@ import nox BLACK_VERSION = "black==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.10.1" LINT_PATHS = ["docs", "pandas_gbq", "tests", "noxfile.py", "setup.py"] @@ -112,6 +113,7 @@ def wrapper(*args, **kwargs): "lint", "lint_setup_py", "blacken", + "format", "docs", ] @@ -151,19 +153,26 @@ def blacken(session): @_calculate_duration def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/sqlalchemy-bigquery/noxfile.py b/packages/sqlalchemy-bigquery/noxfile.py index 615ac0c30f5c..778ebf985f3e 100644 --- a/packages/sqlalchemy-bigquery/noxfile.py +++ b/packages/sqlalchemy-bigquery/noxfile.py @@ -31,6 +31,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = [ "third_party", @@ -200,22 +201,26 @@ def blacken(session): @_calculate_duration def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) - session.run("python", "-m", "pip", "freeze") - - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/sqlalchemy-spanner/noxfile.py b/packages/sqlalchemy-spanner/noxfile.py index f0e115ef3ed5..90e29b6b0804 100644 --- a/packages/sqlalchemy-spanner/noxfile.py +++ b/packages/sqlalchemy-spanner/noxfile.py @@ -78,6 +78,7 @@ class = StreamHandler BLACK_VERSION = "black==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" BLACK_PATHS = ["google", "tests", "noxfile.py", "setup.py", "samples"] UNIT_TEST_PYTHON_VERSIONS = ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] @@ -96,6 +97,7 @@ class = StreamHandler "migration_test", "_migration_test", "mockserver", + "format", ] @@ -434,11 +436,28 @@ def docfx(session): session.skip("docfx builds are not yet supported") -@nox.session -def format(session: nox.sessions.Session) -> None: - session.install(BLACK_VERSION, ISORT_VERSION) - import os +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) - python_files = [path for path in os.listdir(".") if path.endswith(".py")] - session.run("isort", "--fss", *python_files) - session.run("black", *python_files) + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) From d3c2753c345d716e4472f7e24bc69d808340426f Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 14 Apr 2026 08:49:14 -0400 Subject: [PATCH 2/7] chore(nox): standardize format session to use Ruff across multiple packages --- packages/bigquery-magics/noxfile.py | 24 ++++++++++----- packages/db-dtypes/noxfile.py | 25 ++++++++++------ packages/google-api-core/noxfile.py | 28 ++++++++++++++++++ packages/google-auth-httplib2/noxfile.py | 24 ++++++++++----- packages/google-auth-oauthlib/noxfile.py | 24 ++++++++++----- packages/google-auth/noxfile.py | 29 +++++++++++++++++++ packages/google-cloud-core/noxfile.py | 28 ++++++++++++++++++ packages/google-cloud-dns/noxfile.py | 24 ++++++++++----- .../noxfile.py | 24 ++++++++++----- .../google-cloud-runtimeconfig/noxfile.py | 24 ++++++++++----- packages/google-cloud-testutils/noxfile.py | 29 +++++++++++++++++++ packages/proto-plus/noxfile.py | 28 ++++++++++++++++++ 12 files changed, 254 insertions(+), 57 deletions(-) diff --git a/packages/bigquery-magics/noxfile.py b/packages/bigquery-magics/noxfile.py index 5dbe8aaf3e9a..1337a97f84c3 100644 --- a/packages/bigquery-magics/noxfile.py +++ b/packages/bigquery-magics/noxfile.py @@ -29,6 +29,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "bigquery_magics", "tests", "noxfile.py", "setup.py"] @@ -170,19 +171,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/db-dtypes/noxfile.py b/packages/db-dtypes/noxfile.py index c7200dce77f1..b9f66866b792 100644 --- a/packages/db-dtypes/noxfile.py +++ b/packages/db-dtypes/noxfile.py @@ -29,6 +29,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "db_dtypes", "tests", "noxfile.py", "setup.py"] @@ -122,20 +123,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections - session.run("python", "-m", "pip", "freeze") + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/google-api-core/noxfile.py b/packages/google-api-core/noxfile.py index ca3238763c1d..dcb6136a6260 100644 --- a/packages/google-api-core/noxfile.py +++ b/packages/google-api-core/noxfile.py @@ -29,6 +29,7 @@ BLACK_VERSION = "black==23.7.0" +RUFF_VERSION = "ruff==0.14.14" BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] # Black and flake8 clash on the syntax for ignoring flake8's F401 in this file. BLACK_EXCLUDES = ["--exclude", "^/google/api_core/operations_v1/__init__.py"] @@ -72,6 +73,33 @@ def blacken(session): session.run("black", *BLACK_EXCLUDES, *BLACK_PATHS) +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + def install_prerelease_dependencies(session, constraints_path): with open(constraints_path, encoding="utf-8") as constraints_file: constraints_text = constraints_file.read() diff --git a/packages/google-auth-httplib2/noxfile.py b/packages/google-auth-httplib2/noxfile.py index f5807d1fce5b..bf90168aeea7 100644 --- a/packages/google-auth-httplib2/noxfile.py +++ b/packages/google-auth-httplib2/noxfile.py @@ -27,6 +27,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google_auth_httplib2.py", "tests", "noxfile.py", "setup.py"] @@ -118,19 +119,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/google-auth-oauthlib/noxfile.py b/packages/google-auth-oauthlib/noxfile.py index 7b6637889775..9f238315570f 100644 --- a/packages/google-auth-oauthlib/noxfile.py +++ b/packages/google-auth-oauthlib/noxfile.py @@ -29,6 +29,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google_auth_oauthlib", "tests", "noxfile.py", "setup.py"] @@ -103,19 +104,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/google-auth/noxfile.py b/packages/google-auth/noxfile.py index ca829fa96030..2dfadbbcf6a2 100644 --- a/packages/google-auth/noxfile.py +++ b/packages/google-auth/noxfile.py @@ -22,6 +22,7 @@ CLICK_VERSION = "click" BLACK_VERSION = "black==23.7.0" +RUFF_VERSION = "ruff==0.14.14" BLACK_PATHS = [ "google", "tests", @@ -51,6 +52,7 @@ nox.options.sessions = [ "lint", "blacken", + "format", "mypy", # cover must be last to avoid error `No data to report` "docs", @@ -97,6 +99,33 @@ def blacken(session): session.run("black", *BLACK_PATHS) +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + @nox.session(python=DEFAULT_PYTHON_VERSION) def mypy(session): """Verify type hints are mypy compatible.""" diff --git a/packages/google-cloud-core/noxfile.py b/packages/google-cloud-core/noxfile.py index 400a0235d6a4..c9d7084e57a9 100644 --- a/packages/google-cloud-core/noxfile.py +++ b/packages/google-cloud-core/noxfile.py @@ -21,6 +21,7 @@ BLACK_VERSION = "black==23.7.0" +RUFF_VERSION = "ruff==0.14.14" BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] DEFAULT_PYTHON_VERSION = "3.14" @@ -75,6 +76,33 @@ def blacken(session): session.run("black", *BLACK_PATHS) +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + def default(session): """Default unit test session. This is intended to be run **without** an interpreter set, so diff --git a/packages/google-cloud-dns/noxfile.py b/packages/google-cloud-dns/noxfile.py index 5df61c9c4a2f..a5f58aa1e2b2 100644 --- a/packages/google-cloud-dns/noxfile.py +++ b/packages/google-cloud-dns/noxfile.py @@ -29,6 +29,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -118,19 +119,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/google-cloud-documentai-toolbox/noxfile.py b/packages/google-cloud-documentai-toolbox/noxfile.py index 4d9415cb22e7..c3d2c7698eea 100644 --- a/packages/google-cloud-documentai-toolbox/noxfile.py +++ b/packages/google-cloud-documentai-toolbox/noxfile.py @@ -29,6 +29,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -120,19 +121,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/google-cloud-runtimeconfig/noxfile.py b/packages/google-cloud-runtimeconfig/noxfile.py index 9ae3a68fedc3..d433e9e5af39 100644 --- a/packages/google-cloud-runtimeconfig/noxfile.py +++ b/packages/google-cloud-runtimeconfig/noxfile.py @@ -29,6 +29,7 @@ FLAKE8_VERSION = "flake8==6.1.0" BLACK_VERSION = "black[jupyter]==23.7.0" +RUFF_VERSION = "ruff==0.14.14" ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -118,19 +119,26 @@ def blacken(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def format(session): """ - Run isort to sort imports. Then run black - to format code to uniform standard. + Run ruff to sort imports and format code. """ - session.install(BLACK_VERSION, ISORT_VERSION) - # Use the --fss option to sort imports using strict alphabetical order. - # See https://pycqa.github.io/isort/docs/configuration/options.html#force-sort-within-sections + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports session.run( - "isort", - "--fss", + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) + + # 3. Run Ruff to format code session.run( - "black", + "ruff", "format", + f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", *LINT_PATHS, ) diff --git a/packages/google-cloud-testutils/noxfile.py b/packages/google-cloud-testutils/noxfile.py index 65f9c1ee1967..3cbc6d7cc607 100644 --- a/packages/google-cloud-testutils/noxfile.py +++ b/packages/google-cloud-testutils/noxfile.py @@ -26,6 +26,7 @@ # 'update_lower_bounds' is excluded nox.options.sessions = [ "check_lower_bounds", + "format", ] @@ -35,6 +36,7 @@ ALL_PYTHON = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] DEFAULT_PYTHON_VERSION = "3.14" BLACK_VERSION = "black==23.7.0" +RUFF_VERSION = "ruff==0.14.14" BLACK_PATHS = ["test_utils", "setup.py"] CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() @@ -68,6 +70,33 @@ def blacken(session): ) +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", + "--line-length=88", + *BLACK_PATHS, + ) + + @nox.session(python=DEFAULT_PYTHON_VERSION) def lint_setup_py(session): """Verify that setup.py is valid (including RST check).""" diff --git a/packages/proto-plus/noxfile.py b/packages/proto-plus/noxfile.py index 1cf600b1b1b1..c7e372c118cc 100644 --- a/packages/proto-plus/noxfile.py +++ b/packages/proto-plus/noxfile.py @@ -22,6 +22,7 @@ BLACK_VERSION = "black[jupyter]==23.7.0" ISORT_VERSION = "isort==5.11.0" +RUFF_VERSION = "ruff==0.14.14" LINT_PATHS = ["docs", "proto", "tests", "noxfile.py", "setup.py"] @@ -322,3 +323,30 @@ def lint(session): ) session.run("flake8", "proto", "tests") + + +@nox.session(python=DEFAULT_PYTHON_VERSION) +def format(session): + """ + Run ruff to sort imports and format code. + """ + # 1. Install ruff (skipped automatically if you run with --no-venv) + session.install(RUFF_VERSION) + + # 2. Run Ruff to fix imports + session.run( + "ruff", "check", + "--select", "I", + "--fix", + f"--target-version=py{PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) + + # 3. Run Ruff to format code + session.run( + "ruff", "format", + f"--target-version=py{PYTHON_VERSIONS[0].replace('.', '')}", + "--line-length=88", + *LINT_PATHS, + ) From 53d4872180415ea7f6e85ddd929856ee6f6865ed Mon Sep 17 00:00:00 2001 From: Chalmer Lowe Date: Tue, 14 Apr 2026 09:08:29 -0400 Subject: [PATCH 3/7] Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/google-cloud-bigquery/noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google-cloud-bigquery/noxfile.py b/packages/google-cloud-bigquery/noxfile.py index b759b4416f06..25e37a869779 100644 --- a/packages/google-cloud-bigquery/noxfile.py +++ b/packages/google-cloud-bigquery/noxfile.py @@ -552,7 +552,7 @@ def core_deps_from_source(session): @nox.session(python=DEFAULT_PYTHON_VERSION) -def format(session): +def format(session: nox.sessions.Session) -> None: """ Run ruff to sort imports and format code. """ From bd7bfbfa28a1eb3f826bf9a17c657c06caf6c835 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 14 Apr 2026 09:29:05 -0400 Subject: [PATCH 4/7] chore: updates linting for the noxfiles --- packages/bigquery-magics/noxfile.py | 11 ++++++---- packages/db-dtypes/noxfile.py | 11 ++++++---- packages/google-api-core/noxfile.py | 11 ++++++---- packages/google-auth-httplib2/noxfile.py | 11 ++++++---- packages/google-auth-oauthlib/noxfile.py | 11 ++++++---- packages/google-auth/noxfile.py | 9 +++++--- packages/google-cloud-bigquery/noxfile.py | 11 ++++++---- packages/google-cloud-core/noxfile.py | 13 +++++++----- packages/google-cloud-dns/noxfile.py | 11 ++++++---- .../noxfile.py | 11 ++++++---- packages/google-cloud-ndb/noxfile.py | 19 ++++++++++++----- .../google-cloud-runtimeconfig/noxfile.py | 11 ++++++---- packages/google-crc32c/noxfile.py | 9 +++++--- packages/google-resumable-media/noxfile.py | 21 +++++++++++++------ packages/pandas-gbq/noxfile.py | 11 ++++++---- packages/proto-plus/noxfile.py | 13 +++++++----- packages/sqlalchemy-bigquery/noxfile.py | 13 +++++++----- packages/sqlalchemy-spanner/noxfile.py | 9 +++++--- 18 files changed, 141 insertions(+), 75 deletions(-) diff --git a/packages/bigquery-magics/noxfile.py b/packages/bigquery-magics/noxfile.py index 1337a97f84c3..988d9b4f7b71 100644 --- a/packages/bigquery-magics/noxfile.py +++ b/packages/bigquery-magics/noxfile.py @@ -22,8 +22,8 @@ import pathlib import re import shutil -from typing import Dict, List import warnings +from typing import Dict, List import nox @@ -178,8 +178,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -188,7 +190,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/db-dtypes/noxfile.py b/packages/db-dtypes/noxfile.py index b9f66866b792..2a07b72321d8 100644 --- a/packages/db-dtypes/noxfile.py +++ b/packages/db-dtypes/noxfile.py @@ -22,8 +22,8 @@ import pathlib import re import shutil -from typing import Dict, List import warnings +from typing import Dict, List import nox @@ -130,8 +130,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -140,7 +142,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/google-api-core/noxfile.py b/packages/google-api-core/noxfile.py index dcb6136a6260..3ae96e416736 100644 --- a/packages/google-api-core/noxfile.py +++ b/packages/google-api-core/noxfile.py @@ -18,6 +18,7 @@ # PIP_INDEX_URL=https://pypi.org/simple nox from __future__ import absolute_import + import os import pathlib import re @@ -27,7 +28,6 @@ # https://github.com/google/importlab/issues/25 import nox - BLACK_VERSION = "black==23.7.0" RUFF_VERSION = "ruff==0.14.14" BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -83,8 +83,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", @@ -93,7 +95,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", *BLACK_PATHS, diff --git a/packages/google-auth-httplib2/noxfile.py b/packages/google-auth-httplib2/noxfile.py index bf90168aeea7..df9b4c2656e9 100644 --- a/packages/google-auth-httplib2/noxfile.py +++ b/packages/google-auth-httplib2/noxfile.py @@ -20,8 +20,8 @@ import pathlib import re import shutil -from typing import Dict, List import warnings +from typing import Dict, List import nox @@ -126,8 +126,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -136,7 +138,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/google-auth-oauthlib/noxfile.py b/packages/google-auth-oauthlib/noxfile.py index 9f238315570f..8af6dc8319d5 100644 --- a/packages/google-auth-oauthlib/noxfile.py +++ b/packages/google-auth-oauthlib/noxfile.py @@ -22,8 +22,8 @@ import pathlib import re import shutil -from typing import Dict, List import warnings +from typing import Dict, List import nox @@ -111,8 +111,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -121,7 +123,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/google-auth/noxfile.py b/packages/google-auth/noxfile.py index 2dfadbbcf6a2..78dd7805424a 100644 --- a/packages/google-auth/noxfile.py +++ b/packages/google-auth/noxfile.py @@ -109,8 +109,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", @@ -119,7 +121,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", *BLACK_PATHS, diff --git a/packages/google-cloud-bigquery/noxfile.py b/packages/google-cloud-bigquery/noxfile.py index 25e37a869779..68c57bc41752 100644 --- a/packages/google-cloud-bigquery/noxfile.py +++ b/packages/google-cloud-bigquery/noxfile.py @@ -14,12 +14,12 @@ from __future__ import absolute_import -from functools import wraps import os import pathlib import re import shutil import time +from functools import wraps import nox @@ -561,8 +561,10 @@ def format(session: nox.sessions.Session) -> None: # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -571,7 +573,8 @@ def format(session: nox.sessions.Session) -> None: # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *BLACK_PATHS, diff --git a/packages/google-cloud-core/noxfile.py b/packages/google-cloud-core/noxfile.py index c9d7084e57a9..e6f33b60ad65 100644 --- a/packages/google-cloud-core/noxfile.py +++ b/packages/google-cloud-core/noxfile.py @@ -13,13 +13,13 @@ # limitations under the License. from __future__ import absolute_import + import os import re import shutil import nox - BLACK_VERSION = "black==23.7.0" RUFF_VERSION = "ruff==0.14.14" BLACK_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] @@ -86,8 +86,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -96,7 +98,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *BLACK_PATHS, @@ -370,7 +373,7 @@ def core_deps_from_source(session, protobuf_implementation): f"{CURRENT_DIRECTORY}/../google-api-core", f"{CURRENT_DIRECTORY}/../google-auth", f"{CURRENT_DIRECTORY}/../grpc-google-iam-v1", - f"{CURRENT_DIRECTORY}/../proto-plus" + f"{CURRENT_DIRECTORY}/../proto-plus", ] for dep in core_dependencies_from_source: diff --git a/packages/google-cloud-dns/noxfile.py b/packages/google-cloud-dns/noxfile.py index a5f58aa1e2b2..548f9189a2c0 100644 --- a/packages/google-cloud-dns/noxfile.py +++ b/packages/google-cloud-dns/noxfile.py @@ -22,8 +22,8 @@ import pathlib import re import shutil -from typing import Dict, List import warnings +from typing import Dict, List import nox @@ -126,8 +126,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", @@ -136,7 +138,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/google-cloud-documentai-toolbox/noxfile.py b/packages/google-cloud-documentai-toolbox/noxfile.py index c3d2c7698eea..418cbb368f75 100644 --- a/packages/google-cloud-documentai-toolbox/noxfile.py +++ b/packages/google-cloud-documentai-toolbox/noxfile.py @@ -22,8 +22,8 @@ import pathlib import re import shutil -from typing import Dict, List import warnings +from typing import Dict, List import nox @@ -128,8 +128,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -138,7 +140,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/google-cloud-ndb/noxfile.py b/packages/google-cloud-ndb/noxfile.py index 11262f503edf..dc3f500930d6 100644 --- a/packages/google-cloud-ndb/noxfile.py +++ b/packages/google-cloud-ndb/noxfile.py @@ -290,20 +290,29 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", "--line-length=88", - "docs", "noxfile.py", "google", "tests", + "docs", + "noxfile.py", + "google", + "tests", ) # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{ALL_INTERPRETERS[0].replace('.', '')}", "--line-length=88", - "docs", "noxfile.py", "google", "tests", + "docs", + "noxfile.py", + "google", + "tests", ) diff --git a/packages/google-cloud-runtimeconfig/noxfile.py b/packages/google-cloud-runtimeconfig/noxfile.py index d433e9e5af39..81d69b01d38c 100644 --- a/packages/google-cloud-runtimeconfig/noxfile.py +++ b/packages/google-cloud-runtimeconfig/noxfile.py @@ -22,8 +22,8 @@ import pathlib import re import shutil -from typing import Dict, List import warnings +from typing import Dict, List import nox @@ -126,8 +126,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -136,7 +138,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/google-crc32c/noxfile.py b/packages/google-crc32c/noxfile.py index 110d2316debf..c1b449abbbf4 100644 --- a/packages/google-crc32c/noxfile.py +++ b/packages/google-crc32c/noxfile.py @@ -124,8 +124,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", @@ -134,7 +136,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{ALL_PYTHON[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/google-resumable-media/noxfile.py b/packages/google-resumable-media/noxfile.py index 3fc656368485..34455c0883ca 100644 --- a/packages/google-resumable-media/noxfile.py +++ b/packages/google-resumable-media/noxfile.py @@ -13,6 +13,7 @@ # limitations under the License. from __future__ import absolute_import + import os import pathlib import shutil @@ -68,7 +69,7 @@ def unit(session): line_coverage, os.path.join("tests", "unit"), os.path.join("tests_async", "unit"), - *session.posargs + *session.posargs, ) @@ -106,6 +107,7 @@ def docs(session): os.path.join("docs", "_build", "html", ""), ) + @nox.session(python="3.10") def docfx(session): """Build the docfx yaml files for this library.""" @@ -251,8 +253,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -266,7 +270,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", os.path.join("google", "resumable_media"), @@ -345,7 +350,9 @@ def prerelease_deps(session): # Resolve the linked bug once prerelease_deps and core_deps_from_source # are implemented for this package. if session.python == DEFAULT_PYTHON_VERSION: - session.skip(f"Skipping prerelease_deps for {DEFAULT_PYTHON_VERSION} until a future release.") + session.skip( + f"Skipping prerelease_deps for {DEFAULT_PYTHON_VERSION} until a future release." + ) @nox.session(python=DEFAULT_PYTHON_VERSION) @@ -354,4 +361,6 @@ def core_deps_from_source(session): # Resolve the linked bug once prerelease_deps and core_deps_from_source # are implemented for this package. if session.python == DEFAULT_PYTHON_VERSION: - session.skip(f"Skipping core_deps_from_source for {DEFAULT_PYTHON_VERSION} until a future release.") + session.skip( + f"Skipping core_deps_from_source for {DEFAULT_PYTHON_VERSION} until a future release." + ) diff --git a/packages/pandas-gbq/noxfile.py b/packages/pandas-gbq/noxfile.py index 748e5a4d69f3..123a9713b7ed 100644 --- a/packages/pandas-gbq/noxfile.py +++ b/packages/pandas-gbq/noxfile.py @@ -18,13 +18,13 @@ from __future__ import absolute_import -from functools import wraps import os import pathlib import re import shutil import time import warnings +from functools import wraps import nox @@ -160,8 +160,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -170,7 +172,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/proto-plus/noxfile.py b/packages/proto-plus/noxfile.py index c7e372c118cc..ab2c85110cbc 100644 --- a/packages/proto-plus/noxfile.py +++ b/packages/proto-plus/noxfile.py @@ -14,11 +14,11 @@ from __future__ import absolute_import -import shutil -import nox import os import pathlib +import shutil +import nox BLACK_VERSION = "black[jupyter]==23.7.0" ISORT_VERSION = "isort==5.11.0" @@ -335,8 +335,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -345,7 +347,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/sqlalchemy-bigquery/noxfile.py b/packages/sqlalchemy-bigquery/noxfile.py index 778ebf985f3e..7a8ba6cdfc2a 100644 --- a/packages/sqlalchemy-bigquery/noxfile.py +++ b/packages/sqlalchemy-bigquery/noxfile.py @@ -18,14 +18,14 @@ from __future__ import absolute_import -from functools import wraps import os import pathlib import re import shutil import time -from typing import Dict, List import warnings +from functools import wraps +from typing import Dict, List import nox @@ -208,8 +208,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -218,7 +220,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *LINT_PATHS, diff --git a/packages/sqlalchemy-spanner/noxfile.py b/packages/sqlalchemy-spanner/noxfile.py index 90e29b6b0804..179ce306c9dc 100644 --- a/packages/sqlalchemy-spanner/noxfile.py +++ b/packages/sqlalchemy-spanner/noxfile.py @@ -446,8 +446,10 @@ def format(session): # 2. Run Ruff to fix imports session.run( - "ruff", "check", - "--select", "I", + "ruff", + "check", + "--select", + "I", "--fix", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", @@ -456,7 +458,8 @@ def format(session): # 3. Run Ruff to format code session.run( - "ruff", "format", + "ruff", + "format", f"--target-version=py{UNIT_TEST_PYTHON_VERSIONS[0].replace('.', '')}", "--line-length=88", *BLACK_PATHS, From 7109c9c8b47f1c5ba43f90d8d4b0d04d92d3774a Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 15 Apr 2026 05:43:08 -0400 Subject: [PATCH 5/7] test: limits total number of test DBs allowed --- .../create_test_database.py | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/packages/sqlalchemy-spanner/create_test_database.py b/packages/sqlalchemy-spanner/create_test_database.py index a72e44aa4ed3..d311ecb3e70c 100644 --- a/packages/sqlalchemy-spanner/create_test_database.py +++ b/packages/sqlalchemy-spanner/create_test_database.py @@ -68,28 +68,74 @@ def delete_stale_test_instances(): def delete_stale_test_databases(): - """Delete test databases that are older than four hours.""" + """Delete stale or excessive test databases. + + Deletes stale test databases that are older than 4 hours and + ensures we don't hit the 100 database limit per spanner instance by + deleting the oldest databases if we are near the limit. + """ cutoff = (int(time.time()) - 4 * 60 * 60) * 1000 instance = CLIENT.instance("sqlalchemy-dialect-test") if not instance.exists(): return - database_pbs = instance.list_databases() + + # Convert iterator to list to allow multiple passes and length check + database_pbs = list(instance.list_databases()) + + # First pass: Delete stale databases + remaining_dbs = [] for database_pb in database_pbs: database = Database.from_pb(database_pb, instance) # The emulator does not return a create_time for databases. if database.create_time is None: + remaining_dbs.append(database_pb) continue + create_time = datetime_helpers.to_milliseconds(database_pb.create_time) if create_time > cutoff: + remaining_dbs.append(database_pb) continue + try: database.drop() + print(f"Dropped stale database '{database.database_id}'") except ResourceExhausted: print( "Unable to drop stale database '{}'. May need manual delete.".format( database.database_id ) ) + remaining_dbs.append(database_pb) # Still there + + # Second pass: If we are still near the limit (e.g., 90+ databases), + # delete the oldest ones regardless of age to free up slots. + # Spanner instances have a hard limit of 100 databases. + LIMIT = 90 + if len(remaining_dbs) >= LIMIT: + print(f"Database count ({len(remaining_dbs)}) is near limit. Cleaning up oldest databases.") + + # Sort by creation time + dbs_with_time = [] + for db_pb in remaining_dbs: + if db_pb.create_time: + dbs_with_time.append((db_pb.create_time, db_pb.name)) + + dbs_with_time.sort() # Sorts by time ascending (oldest first) + + # Delete enough to get below the limit + to_delete = len(remaining_dbs) - (LIMIT - 10) # Aim for 80 + deleted_count = 0 + + for create_time, full_name in dbs_with_time: + if deleted_count >= to_delete: + break + db_id = full_name.split('/')[-1] + try: + instance.database(db_id).drop() + print(f"Dropped oldest database '{db_id}' to prevent resource exhaustion.") + deleted_count += 1 + except Exception as e: + print(f"Failed to drop database '{db_id}': {e}") def create_test_instance(): From 5aa2cfe0f45d1a1c1bdf75a7e974764cd9950cf8 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 15 Apr 2026 07:40:45 -0400 Subject: [PATCH 6/7] test: adjusts deadline to account for flakiness --- .../tests/unit/job/test_async_job_retry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google-cloud-bigquery/tests/unit/job/test_async_job_retry.py b/packages/google-cloud-bigquery/tests/unit/job/test_async_job_retry.py index 4d9cccf932c3..968a080eefbb 100644 --- a/packages/google-cloud-bigquery/tests/unit/job/test_async_job_retry.py +++ b/packages/google-cloud-bigquery/tests/unit/job/test_async_job_retry.py @@ -110,7 +110,7 @@ def test_result_w_retry_wo_state(global_time_lock): predicate=custom_predicate, initial=0.001, maximum=0.001, - deadline=0.1, + deadline=1.0, # Increased from 0.1 to avoid flakiness in slow environments ) assert job.result(retry=custom_retry) is job From a26986118e69479b7e34351b510f0ef71f4c7b77 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Wed, 15 Apr 2026 08:41:53 -0400 Subject: [PATCH 7/7] test: adjusts assert to account for potential race condition --- .../google-cloud-storage/tests/system/test_zonal.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/google-cloud-storage/tests/system/test_zonal.py b/packages/google-cloud-storage/tests/system/test_zonal.py index 3c275794e331..ad0a871f44b4 100644 --- a/packages/google-cloud-storage/tests/system/test_zonal.py +++ b/packages/google-cloud-storage/tests/system/test_zonal.py @@ -722,7 +722,15 @@ async def _run(): for i in range(num_chunks): if i % 2 == 0: - assert isinstance(results[i], asyncio.CancelledError) + # In fast environments, the task might complete before cancellation takes effect. + # We accept either Cancellation or successful completion to avoid flakiness. + if isinstance(results[i], asyncio.CancelledError): + pass + else: + assert results[i] is None + start = i * chunk_size + expected_data = object_data[start : start + chunk_size] + assert buffers[i].getvalue() == expected_data else: start = i * chunk_size expected_data = object_data[start : start + chunk_size]