From 8505d5ea0593ad2a34808ad9a302e2c3c8981034 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Mon, 10 Nov 2025 12:03:58 +0000 Subject: [PATCH 1/9] chore(librarian): clean up owlbot files and pin image sha --- .github/auto-approve.yml | 3 --- .librarian/config.yaml | 6 ------ .librarian/state.yaml | 2 +- owlbot.py | 40 ---------------------------------------- 4 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 .github/auto-approve.yml delete mode 100644 .librarian/config.yaml delete mode 100644 owlbot.py diff --git a/.github/auto-approve.yml b/.github/auto-approve.yml deleted file mode 100644 index 311ebbb85..000000000 --- a/.github/auto-approve.yml +++ /dev/null @@ -1,3 +0,0 @@ -# https://github.com/googleapis/repo-automation-bots/tree/main/packages/auto-approve -processes: - - "OwlBotTemplateChanges" diff --git a/.librarian/config.yaml b/.librarian/config.yaml deleted file mode 100644 index 111f94dd5..000000000 --- a/.librarian/config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -global_files_allowlist: - # Allow the container to read and write the root `CHANGELOG.md` - # file during the `release` step to update the latest client library - # versions which are hardcoded in the file. - - path: "CHANGELOG.md" - permissions: "read-write" diff --git a/.librarian/state.yaml b/.librarian/state.yaml index 6ac8b0a64..cd7704318 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator:latest +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:39628f6e89c9cad27973b9a39a50f7052bec0435ee58c7027b4fa6b655943e31 libraries: - id: google-api-core version: 2.28.1 diff --git a/owlbot.py b/owlbot.py deleted file mode 100644 index 58bc75170..000000000 --- a/owlbot.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2020 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. - -"""This script is used to synthesize generated parts of this library.""" - -import synthtool as s -from synthtool import gcp -from synthtool.languages import python - -common = gcp.CommonTemplates() - -# ---------------------------------------------------------------------------- -# Add templated files -# ---------------------------------------------------------------------------- -excludes = [ - "noxfile.py", # pytype - "setup.cfg", # pytype - ".coveragerc", # layout - "CONTRIBUTING.rst", # no systests - ".github/workflows/unittest.yml", # exclude unittest gh action - ".github/workflows/lint.yml", # exclude lint gh action - "README.rst", -] -templated_files = common.py_library(microgenerator=True, cov_level=100) -s.move(templated_files, excludes=excludes) - -python.configure_previous_major_version_branches() - -s.shell.run(["nox", "-s", "blacken"], hide_output=False) From fc9d25f5dddbc36749ab24607a877480c8d6b743 Mon Sep 17 00:00:00 2001 From: ohmayr Date: Tue, 11 Nov 2025 12:19:55 +0000 Subject: [PATCH 2/9] update librarian container sha --- .librarian/state.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.librarian/state.yaml b/.librarian/state.yaml index cd7704318..1a97264b7 100644 --- a/.librarian/state.yaml +++ b/.librarian/state.yaml @@ -1,4 +1,4 @@ -image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:39628f6e89c9cad27973b9a39a50f7052bec0435ee58c7027b4fa6b655943e31 +image: us-central1-docker.pkg.dev/cloud-sdk-librarian-prod/images-prod/python-librarian-generator@sha256:c8612d3fffb3f6a32353b2d1abd16b61e87811866f7ec9d65b59b02eb452a620 libraries: - id: google-api-core version: 2.28.1 From 6287fdd511f1a1885b3cc5b0d80e6984263d1554 Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Tue, 11 Nov 2025 16:53:42 -0800 Subject: [PATCH 3/9] fix: fix test failures due to warnings --- tests/unit/test_client_options.py | 40 ++++++++++++++--------- tests/unit/test_python_version_support.py | 20 +++++++----- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/tests/unit/test_client_options.py b/tests/unit/test_client_options.py index 396d66271..61630aaae 100644 --- a/tests/unit/test_client_options.py +++ b/tests/unit/test_client_options.py @@ -28,18 +28,22 @@ def get_client_encrypted_cert(): def test_constructor(): - options = client_options.ClientOptions( - api_endpoint="foo.googleapis.com", - client_cert_source=get_client_cert, - quota_project_id="quote-proj", - credentials_file="path/to/credentials.json", - scopes=[ - "https://www.googleapis.com/auth/cloud-platform", - "https://www.googleapis.com/auth/cloud-platform.read-only", - ], - api_audience="foo2.googleapis.com", - universe_domain="googleapis.com", - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + options = client_options.ClientOptions( + api_endpoint="foo.googleapis.com", + client_cert_source=get_client_cert, + quota_project_id="quote-proj", + credentials_file="path/to/credentials.json", + scopes=[ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ], + api_audience="foo2.googleapis.com", + universe_domain="googleapis.com", + ) assert options.api_endpoint == "foo.googleapis.com" assert options.client_cert_source() == (b"cert", b"key") @@ -102,10 +106,14 @@ def test_constructor_with_api_key(): def test_constructor_with_both_api_key_and_credentials_file(): with pytest.raises(ValueError): - client_options.ClientOptions( - api_key="api-key", - credentials_file="path/to/credentials.json", - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + client_options.ClientOptions( + api_key="api-key", + credentials_file="path/to/credentials.json", + ) def test_from_dict(): diff --git a/tests/unit/test_python_version_support.py b/tests/unit/test_python_version_support.py index c38160b78..76eb821e0 100644 --- a/tests/unit/test_python_version_support.py +++ b/tests/unit/test_python_version_support.py @@ -178,17 +178,20 @@ def test_override_gapic_end_only(): "google.api_core._python_version_support.PYTHON_VERSION_INFO", {version_tuple: overridden_info}, ): - result_before_boundary = check_python_version( - today=custom_gapic_end + datetime.timedelta(days=-1) - ) + with pytest.warns(FutureWarning, match="past its end of life"): + result_before_boundary = check_python_version( + today=custom_gapic_end + datetime.timedelta(days=-1) + ) assert result_before_boundary == PythonVersionStatus.PYTHON_VERSION_EOL - result_at_boundary = check_python_version(today=custom_gapic_end) + with pytest.warns(FutureWarning, match="past its end of life"): + result_at_boundary = check_python_version(today=custom_gapic_end) assert result_at_boundary == PythonVersionStatus.PYTHON_VERSION_EOL - result_after_boundary = check_python_version( - today=custom_gapic_end + datetime.timedelta(days=1) - ) + with pytest.warns(FutureWarning, match="non-supported Python version"): + result_after_boundary = check_python_version( + today=custom_gapic_end + datetime.timedelta(days=1) + ) assert ( result_after_boundary == PythonVersionStatus.PYTHON_VERSION_UNSUPPORTED ) @@ -217,7 +220,8 @@ def test_override_gapic_deprecation_only(): result_before_boundary == PythonVersionStatus.PYTHON_VERSION_SUPPORTED ) - result_at_boundary = check_python_version(today=custom_gapic_dep) + with pytest.warns(FutureWarning, match="Google will stop supporting"): + result_at_boundary = check_python_version(today=custom_gapic_dep) assert result_at_boundary == PythonVersionStatus.PYTHON_VERSION_DEPRECATED From b159a828be4d41ce9c73e5b7b1e4599dfeb77990 Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Wed, 12 Nov 2025 12:54:08 -0800 Subject: [PATCH 4/9] chore: fix additional tests --- tests/asyncio/test_grpc_helpers_async.py | 44 ++++++++++----- .../test_operations_rest_client.py | 55 ++++++++++++++----- tests/unit/test_grpc_helpers.py | 40 ++++++++++---- 3 files changed, 99 insertions(+), 40 deletions(-) diff --git a/tests/asyncio/test_grpc_helpers_async.py b/tests/asyncio/test_grpc_helpers_async.py index aa8d5d10b..ba4c52ffe 100644 --- a/tests/asyncio/test_grpc_helpers_async.py +++ b/tests/asyncio/test_grpc_helpers_async.py @@ -522,11 +522,15 @@ def test_create_channel_explicit_with_duplicate_credentials(): target = "example:443" with pytest.raises(exceptions.DuplicateCredentialArgs) as excinfo: - grpc_helpers_async.create_channel( - target, - credentials_file="credentials.json", - credentials=mock.sentinel.credentials, - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + grpc_helpers_async.create_channel( + target, + credentials_file="credentials.json", + credentials=mock.sentinel.credentials, + ) assert "mutually exclusive" in str(excinfo.value) @@ -641,9 +645,13 @@ def test_create_channel_with_credentials_file( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - channel = grpc_helpers_async.create_channel( - target, credentials_file=credentials_file - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + channel = grpc_helpers_async.create_channel( + target, credentials_file=credentials_file + ) google.auth.load_credentials_from_file.assert_called_once_with( credentials_file, scopes=None, default_scopes=None @@ -670,9 +678,13 @@ def test_create_channel_with_credentials_file_and_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - channel = grpc_helpers_async.create_channel( - target, credentials_file=credentials_file, scopes=scopes - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + channel = grpc_helpers_async.create_channel( + target, credentials_file=credentials_file, scopes=scopes + ) google.auth.load_credentials_from_file.assert_called_once_with( credentials_file, scopes=scopes, default_scopes=None @@ -699,9 +711,13 @@ def test_create_channel_with_credentials_file_and_default_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - channel = grpc_helpers_async.create_channel( - target, credentials_file=credentials_file, default_scopes=default_scopes - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + channel = grpc_helpers_async.create_channel( + target, credentials_file=credentials_file, default_scopes=default_scopes + ) google.auth.load_credentials_from_file.assert_called_once_with( credentials_file, scopes=None, default_scopes=default_scopes diff --git a/tests/unit/operations_v1/test_operations_rest_client.py b/tests/unit/operations_v1/test_operations_rest_client.py index 4e8ef4073..4bbcee4ad 100644 --- a/tests/unit/operations_v1/test_operations_rest_client.py +++ b/tests/unit/operations_v1/test_operations_rest_client.py @@ -369,7 +369,11 @@ def test_operations_client_client_options( ) # Check the case credentials_file is provided - options = client_options.ClientOptions(credentials_file="credentials.json") + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + options = client_options.ClientOptions(credentials_file="credentials.json") with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None client = client_class(client_options=options, transport=transport_name) @@ -539,7 +543,11 @@ def test_operations_client_client_options_credentials_file( client_class, transport_class, transport_name ): # Check the case credentials file is provided. - options = client_options.ClientOptions(credentials_file="credentials.json") + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + options = client_options.ClientOptions(credentials_file="credentials.json") if "async" in str(client_class): # TODO(): Add support for credentials file to async REST transport. with pytest.raises(core_exceptions.AsyncRestUnsupportedParameterError): @@ -570,10 +578,21 @@ def test_operations_client_client_options_credentials_file( return_value=(mock.sentinel.credentials, mock.sentinel.project), ) def test_list_operations_rest(google_auth_default, credentials_file): - sync_transport = transports.rest.OperationsRestTransport( - credentials_file=credentials_file, - http_options=HTTP_OPTIONS, - ) + if credentials_file: + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + sync_transport = transports.rest.OperationsRestTransport( + credentials_file=credentials_file, + http_options=HTTP_OPTIONS, + ) + else: + # no warning expected + sync_transport = transports.rest.OperationsRestTransport( + credentials_file=credentials_file, + http_options=HTTP_OPTIONS, + ) client = AbstractOperationsClient(transport=sync_transport) @@ -1130,10 +1149,14 @@ def test_transport_adc(client_class, transport_class, credentials): def test_operations_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error with pytest.raises(core_exceptions.DuplicateCredentialArgs): - transports.OperationsTransport( - credentials=ga_credentials.AnonymousCredentials(), - credentials_file="credentials.json", - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + transports.OperationsTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json", + ) def test_operations_base_transport(): @@ -1171,10 +1194,14 @@ def test_operations_base_transport_with_credentials_file(): ) as Transport: Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - transports.OperationsTransport( - credentials_file="credentials.json", - quota_project_id="octopus", - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + transports.OperationsTransport( + credentials_file="credentials.json", + quota_project_id="octopus", + ) load_creds.assert_called_once_with( "credentials.json", scopes=None, diff --git a/tests/unit/test_grpc_helpers.py b/tests/unit/test_grpc_helpers.py index 8de9d8c0b..6aa025b25 100644 --- a/tests/unit/test_grpc_helpers.py +++ b/tests/unit/test_grpc_helpers.py @@ -581,11 +581,15 @@ def test_create_channel_explicit_with_duplicate_credentials(): target = "example.com:443" with pytest.raises(exceptions.DuplicateCredentialArgs): - grpc_helpers.create_channel( - target, - credentials_file="credentials.json", - credentials=mock.sentinel.credentials, - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + grpc_helpers.create_channel( + target, + credentials_file="credentials.json", + credentials=mock.sentinel.credentials, + ) @mock.patch("grpc.compute_engine_channel_credentials") @@ -710,7 +714,11 @@ def test_create_channel_with_credentials_file( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - channel = grpc_helpers.create_channel(target, credentials_file=credentials_file) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + channel = grpc_helpers.create_channel(target, credentials_file=credentials_file) google.auth.load_credentials_from_file.assert_called_once_with( credentials_file, scopes=None, default_scopes=None @@ -742,9 +750,13 @@ def test_create_channel_with_credentials_file_and_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - channel = grpc_helpers.create_channel( - target, credentials_file=credentials_file, scopes=scopes - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + channel = grpc_helpers.create_channel( + target, credentials_file=credentials_file, scopes=scopes + ) google.auth.load_credentials_from_file.assert_called_once_with( credentials_file, scopes=scopes, default_scopes=None @@ -776,9 +788,13 @@ def test_create_channel_with_credentials_file_and_default_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - channel = grpc_helpers.create_channel( - target, credentials_file=credentials_file, default_scopes=default_scopes - ) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + channel = grpc_helpers.create_channel( + target, credentials_file=credentials_file, default_scopes=default_scopes + ) load_credentials_from_file.assert_called_once_with( credentials_file, scopes=None, default_scopes=default_scopes From e1eba13a0aeeac90f989a5928ec31b795548e89f Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Wed, 12 Nov 2025 13:29:01 -0800 Subject: [PATCH 5/9] chore: prevent FutureWarning about Pyton versions from failing tests --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 0132afe05..31f82052a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,6 +91,8 @@ ignore_missing_imports = true filterwarnings = [ # treat all warnings as errors "error", + # Prevent Python version warnings from interfering with tests + "ignore:.* Python version .*:FutureWarning", # Remove once https://github.com/pytest-dev/pytest-cov/issues/621 is fixed "ignore:.*The --rsyncdir command line argument and rsyncdirs config variable are deprecated:DeprecationWarning", # Remove once https://github.com/protocolbuffers/protobuf/issues/12186 is fixed From 8398248c037d1a88f2504af9499aa7ef9de07835 Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Wed, 12 Nov 2025 13:35:36 -0800 Subject: [PATCH 6/9] chore: fix additional test for deprecation warning --- tests/unit/operations_v1/test_operations_rest_client.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/unit/operations_v1/test_operations_rest_client.py b/tests/unit/operations_v1/test_operations_rest_client.py index 4bbcee4ad..f5ff24078 100644 --- a/tests/unit/operations_v1/test_operations_rest_client.py +++ b/tests/unit/operations_v1/test_operations_rest_client.py @@ -551,7 +551,12 @@ def test_operations_client_client_options_credentials_file( if "async" in str(client_class): # TODO(): Add support for credentials file to async REST transport. with pytest.raises(core_exceptions.AsyncRestUnsupportedParameterError): - client_class(client_options=options, transport=transport_name) + with pytest.warns( + DeprecationWarning, + match="argument is deprecated because of a potential security risk", + ): + + client_class(client_options=options, transport=transport_name) else: with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None From 44bf38528b5f1bc4e0625b82b007fb5bb07e0313 Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Wed, 12 Nov 2025 17:20:34 -0800 Subject: [PATCH 7/9] chore: simplify warnings check --- tests/asyncio/test_grpc_helpers_async.py | 21 +++---------- tests/helpers.py | 11 +++++++ .../test_operations_rest_client.py | 31 +++++-------------- tests/unit/test_client_options.py | 12 ++----- tests/unit/test_grpc_helpers.py | 21 +++---------- 5 files changed, 31 insertions(+), 65 deletions(-) diff --git a/tests/asyncio/test_grpc_helpers_async.py b/tests/asyncio/test_grpc_helpers_async.py index ba4c52ffe..43700f22b 100644 --- a/tests/asyncio/test_grpc_helpers_async.py +++ b/tests/asyncio/test_grpc_helpers_async.py @@ -17,6 +17,7 @@ from unittest.mock import AsyncMock # pragma: NO COVER # noqa: F401 except ImportError: # pragma: NO COVER import mock # type: ignore +from ..helpers import warn_deprecated_credentials_file import pytest # noqa: I202 try: @@ -522,10 +523,7 @@ def test_create_channel_explicit_with_duplicate_credentials(): target = "example:443" with pytest.raises(exceptions.DuplicateCredentialArgs) as excinfo: - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): grpc_helpers_async.create_channel( target, credentials_file="credentials.json", @@ -645,10 +643,7 @@ def test_create_channel_with_credentials_file( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): channel = grpc_helpers_async.create_channel( target, credentials_file=credentials_file ) @@ -678,10 +673,7 @@ def test_create_channel_with_credentials_file_and_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): channel = grpc_helpers_async.create_channel( target, credentials_file=credentials_file, scopes=scopes ) @@ -711,10 +703,7 @@ def test_create_channel_with_credentials_file_and_default_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): channel = grpc_helpers_async.create_channel( target, credentials_file=credentials_file, default_scopes=default_scopes ) diff --git a/tests/helpers.py b/tests/helpers.py index 3429d511e..4c7d5db3e 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -14,7 +14,9 @@ """Helpers for tests""" +import functools import logging +import pytest # noqa: I202 from typing import List import proto @@ -69,3 +71,12 @@ def parse_responses(response_message_cls, all_responses: List[proto.Message]) -> logging.info(f"Sending JSON stream: {json_responses}") ret_val = "[{}]".format(",".join(json_responses)) return bytes(ret_val, "utf-8") + + +warn_deprecated_credentials_file = functools.partial( + # This is used to test that the auth credentials file deprecation + # warning is emitted as expected. + pytest.warns, + DeprecationWarning, + match="argument is deprecated because of a potential security risk", +) diff --git a/tests/unit/operations_v1/test_operations_rest_client.py b/tests/unit/operations_v1/test_operations_rest_client.py index f5ff24078..87523c5dd 100644 --- a/tests/unit/operations_v1/test_operations_rest_client.py +++ b/tests/unit/operations_v1/test_operations_rest_client.py @@ -23,6 +23,7 @@ import pytest from typing import Any, List +from ...helpers import warn_deprecated_credentials_file try: import grpc # noqa: F401 @@ -369,10 +370,7 @@ def test_operations_client_client_options( ) # Check the case credentials_file is provided - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): options = client_options.ClientOptions(credentials_file="credentials.json") with mock.patch.object(transport_class, "__init__") as patched: patched.return_value = None @@ -543,18 +541,12 @@ def test_operations_client_client_options_credentials_file( client_class, transport_class, transport_name ): # Check the case credentials file is provided. - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): options = client_options.ClientOptions(credentials_file="credentials.json") if "async" in str(client_class): # TODO(): Add support for credentials file to async REST transport. with pytest.raises(core_exceptions.AsyncRestUnsupportedParameterError): - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): client_class(client_options=options, transport=transport_name) else: @@ -584,10 +576,7 @@ def test_operations_client_client_options_credentials_file( ) def test_list_operations_rest(google_auth_default, credentials_file): if credentials_file: - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): sync_transport = transports.rest.OperationsRestTransport( credentials_file=credentials_file, http_options=HTTP_OPTIONS, @@ -1154,10 +1143,7 @@ def test_transport_adc(client_class, transport_class, credentials): def test_operations_base_transport_error(): # Passing both a credentials object and credentials_file should raise an error with pytest.raises(core_exceptions.DuplicateCredentialArgs): - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): transports.OperationsTransport( credentials=ga_credentials.AnonymousCredentials(), credentials_file="credentials.json", @@ -1199,10 +1185,7 @@ def test_operations_base_transport_with_credentials_file(): ) as Transport: Transport.return_value = None load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): transports.OperationsTransport( credentials_file="credentials.json", quota_project_id="octopus", diff --git a/tests/unit/test_client_options.py b/tests/unit/test_client_options.py index 61630aaae..58b0286cb 100644 --- a/tests/unit/test_client_options.py +++ b/tests/unit/test_client_options.py @@ -14,6 +14,7 @@ from re import match import pytest +from ..helpers import warn_deprecated_credentials_file from google.api_core import client_options @@ -27,11 +28,7 @@ def get_client_encrypted_cert(): def test_constructor(): - - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): options = client_options.ClientOptions( api_endpoint="foo.googleapis.com", client_cert_source=get_client_cert, @@ -106,10 +103,7 @@ def test_constructor_with_api_key(): def test_constructor_with_both_api_key_and_credentials_file(): with pytest.raises(ValueError): - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): client_options.ClientOptions( api_key="api-key", credentials_file="path/to/credentials.json", diff --git a/tests/unit/test_grpc_helpers.py b/tests/unit/test_grpc_helpers.py index 6aa025b25..ed4a92249 100644 --- a/tests/unit/test_grpc_helpers.py +++ b/tests/unit/test_grpc_helpers.py @@ -15,6 +15,7 @@ from unittest import mock import pytest +from ..helpers import warn_deprecated_credentials_file try: import grpc @@ -581,10 +582,7 @@ def test_create_channel_explicit_with_duplicate_credentials(): target = "example.com:443" with pytest.raises(exceptions.DuplicateCredentialArgs): - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): grpc_helpers.create_channel( target, credentials_file="credentials.json", @@ -714,10 +712,7 @@ def test_create_channel_with_credentials_file( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): channel = grpc_helpers.create_channel(target, credentials_file=credentials_file) google.auth.load_credentials_from_file.assert_called_once_with( @@ -750,10 +745,7 @@ def test_create_channel_with_credentials_file_and_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): channel = grpc_helpers.create_channel( target, credentials_file=credentials_file, scopes=scopes ) @@ -788,10 +780,7 @@ def test_create_channel_with_credentials_file_and_default_scopes( credentials_file = "/path/to/credentials/file.json" composite_creds = composite_creds_call.return_value - with pytest.warns( - DeprecationWarning, - match="argument is deprecated because of a potential security risk", - ): + with warn_deprecated_credentials_file(): channel = grpc_helpers.create_channel( target, credentials_file=credentials_file, default_scopes=default_scopes ) From 61315f4d1006eb4fbb2e0cf8c3bc1a0af41111ea Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Wed, 12 Nov 2025 17:25:48 -0800 Subject: [PATCH 8/9] chore(test): increase timeout tolerance --- tests/asyncio/gapic/test_method_async.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/asyncio/gapic/test_method_async.py b/tests/asyncio/gapic/test_method_async.py index 3edf8b6d4..08a3a6b88 100644 --- a/tests/asyncio/gapic/test_method_async.py +++ b/tests/asyncio/gapic/test_method_async.py @@ -260,7 +260,7 @@ async def test_wrap_method_with_overriding_timeout_as_a_number(): actual_timeout = method.call_args[1]["timeout"] metadata = method.call_args[1]["metadata"] assert metadata == mock.ANY - assert actual_timeout == pytest.approx(22, abs=0.01) + assert actual_timeout == pytest.approx(22, abs=0.02) @pytest.mark.asyncio From b8dcb1f746eac371924c570cd5c9647f74c8506b Mon Sep 17 00:00:00 2001 From: Victor Chudnovsky Date: Wed, 12 Nov 2025 17:28:55 -0800 Subject: [PATCH 9/9] more tolerance --- tests/asyncio/gapic/test_method_async.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/asyncio/gapic/test_method_async.py b/tests/asyncio/gapic/test_method_async.py index 08a3a6b88..40dd168a0 100644 --- a/tests/asyncio/gapic/test_method_async.py +++ b/tests/asyncio/gapic/test_method_async.py @@ -260,7 +260,7 @@ async def test_wrap_method_with_overriding_timeout_as_a_number(): actual_timeout = method.call_args[1]["timeout"] metadata = method.call_args[1]["metadata"] assert metadata == mock.ANY - assert actual_timeout == pytest.approx(22, abs=0.02) + assert actual_timeout == pytest.approx(22, abs=0.05) @pytest.mark.asyncio