From 4029b8fc4eb6b98bceaca7c7166bb9bd90a76515 Mon Sep 17 00:00:00 2001 From: Linchin Date: Wed, 8 Oct 2025 22:40:35 +0000 Subject: [PATCH 01/13] feat: support Python 3.14 --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 20f79ce66..014b32a95 100644 --- a/setup.py +++ b/setup.py @@ -129,6 +129,7 @@ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", From b67156fe5fc8bac2f641bf93e953633651378b7e Mon Sep 17 00:00:00 2001 From: Linchin Date: Wed, 8 Oct 2025 22:44:30 +0000 Subject: [PATCH 02/13] add 3.14 unit test --- noxfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index 728e8c7cc..11f677a3b 100644 --- a/noxfile.py +++ b/noxfile.py @@ -36,7 +36,7 @@ DEFAULT_PYTHON_VERSION = "3.10" # TODO(https://github.com/googleapis/google-auth-library-python/issues/1787): # Remove or restore testing for Python 3.7/3.8 -UNIT_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13"] +UNIT_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] # Error if a python version is missing nox.options.error_on_missing_interpreters = True @@ -53,6 +53,7 @@ "unit-3.11", "unit-3.12", "unit-3.13", + "unit-3.14", # cover must be last to avoid error `No data to report` "cover", "docs", From 87de80ba21be1bcea845d793d8e2c1ff8e9ecd53 Mon Sep 17 00:00:00 2001 From: Linchin Date: Wed, 8 Oct 2025 22:46:15 +0000 Subject: [PATCH 03/13] add samples test for 3.14 --- samples/cloud-client/snippets/noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/cloud-client/snippets/noxfile.py b/samples/cloud-client/snippets/noxfile.py index c21466d4f..3cdf3cf3b 100644 --- a/samples/cloud-client/snippets/noxfile.py +++ b/samples/cloud-client/snippets/noxfile.py @@ -60,7 +60,7 @@ ] -@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]) +@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]) def unit(session): # constraints_path = str( # CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" From e290be3713ddf539d2ed9bd9e71577c7b3947021 Mon Sep 17 00:00:00 2001 From: Linchin Date: Wed, 8 Oct 2025 22:47:47 +0000 Subject: [PATCH 04/13] add samples test config --- .kokoro/samples/python3.14/common.cfg | 37 ++++++++++++++++++++ .kokoro/samples/python3.14/continuous.cfg | 6 ++++ .kokoro/samples/python3.14/periodic-head.cfg | 11 ++++++ .kokoro/samples/python3.14/periodic.cfg | 6 ++++ .kokoro/samples/python3.14/presubmit.cfg | 6 ++++ 5 files changed, 66 insertions(+) create mode 100644 .kokoro/samples/python3.14/common.cfg create mode 100644 .kokoro/samples/python3.14/continuous.cfg create mode 100644 .kokoro/samples/python3.14/periodic-head.cfg create mode 100644 .kokoro/samples/python3.14/periodic.cfg create mode 100644 .kokoro/samples/python3.14/presubmit.cfg diff --git a/.kokoro/samples/python3.14/common.cfg b/.kokoro/samples/python3.14/common.cfg new file mode 100644 index 000000000..c82a73a9e --- /dev/null +++ b/.kokoro/samples/python3.14/common.cfg @@ -0,0 +1,37 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Build logs will be here +action { + define_artifacts { + regex: "**/*sponge_log.xml" + } +} + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "unit-3.14" +} + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Download resources for system tests (service account key, etc.) +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-auth-library-python" + +# Use the trampoline script to run in docker. +build_file: "google-auth-library-python/.kokoro/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/google-auth-library-python/.kokoro/build.sh" +} +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/google-auth-library-python/.kokoro/samples-test-setup.sh" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.14/continuous.cfg b/.kokoro/samples/python3.14/continuous.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.14/continuous.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file diff --git a/.kokoro/samples/python3.14/periodic-head.cfg b/.kokoro/samples/python3.14/periodic-head.cfg new file mode 100644 index 000000000..83eace873 --- /dev/null +++ b/.kokoro/samples/python3.14/periodic-head.cfg @@ -0,0 +1,11 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/google-auth-library-python/.kokoro/test-samples-against-head.sh" +} diff --git a/.kokoro/samples/python3.14/periodic.cfg b/.kokoro/samples/python3.14/periodic.cfg new file mode 100644 index 000000000..71cd1e597 --- /dev/null +++ b/.kokoro/samples/python3.14/periodic.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "False" +} diff --git a/.kokoro/samples/python3.14/presubmit.cfg b/.kokoro/samples/python3.14/presubmit.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.14/presubmit.cfg @@ -0,0 +1,6 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +env_vars: { + key: "INSTALL_LIBRARY_FROM_SOURCE" + value: "True" +} \ No newline at end of file From ac347ac9836462270baf0c43ccf1a734419bdb95 Mon Sep 17 00:00:00 2001 From: Linchin Date: Fri, 10 Oct 2025 19:27:53 +0000 Subject: [PATCH 05/13] add constraints file for 3.14 --- testing/constraints-3.14.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 testing/constraints-3.14.txt diff --git a/testing/constraints-3.14.txt b/testing/constraints-3.14.txt new file mode 100644 index 000000000..e69de29bb From 1a24e691ce053c3b3189570a4287965f195414f2 Mon Sep 17 00:00:00 2001 From: Linchin Date: Fri, 17 Oct 2025 18:24:15 +0000 Subject: [PATCH 06/13] use higher pytest version for python 3.14 --- samples/cloud-client/snippets/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/cloud-client/snippets/requirements.txt b/samples/cloud-client/snippets/requirements.txt index 416c56b94..5cb356b67 100644 --- a/samples/cloud-client/snippets/requirements.txt +++ b/samples/cloud-client/snippets/requirements.txt @@ -1,4 +1,5 @@ google-cloud-compute==1.5.1 google-cloud-storage==3.1.0 google-auth==2.38.0 -pytest==7.1.2 +# pytest==7.1.2; python_version <= '3.13' +pytest==8.4.2; python_version == '3.14' From 6fa1fe386094b4760f5926f30caba176b45bd4a0 Mon Sep 17 00:00:00 2001 From: Linchin Date: Fri, 17 Oct 2025 18:32:50 +0000 Subject: [PATCH 07/13] update pytest dependency --- samples/cloud-client/snippets/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/cloud-client/snippets/requirements.txt b/samples/cloud-client/snippets/requirements.txt index 5cb356b67..0df083439 100644 --- a/samples/cloud-client/snippets/requirements.txt +++ b/samples/cloud-client/snippets/requirements.txt @@ -1,5 +1,5 @@ google-cloud-compute==1.5.1 google-cloud-storage==3.1.0 google-auth==2.38.0 -# pytest==7.1.2; python_version <= '3.13' +pytest==7.1.2; python_version <= '3.13' pytest==8.4.2; python_version == '3.14' From 06efb03f6cc23f6926d183d5638f6ba1e4399b22 Mon Sep 17 00:00:00 2001 From: Linchin Date: Fri, 17 Oct 2025 19:22:52 +0000 Subject: [PATCH 08/13] make unit test test_unsupported_session async --- tests_async/transport/test_aiohttp_requests.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests_async/transport/test_aiohttp_requests.py b/tests_async/transport/test_aiohttp_requests.py index d00955a7d..ec6ff19a1 100644 --- a/tests_async/transport/test_aiohttp_requests.py +++ b/tests_async/transport/test_aiohttp_requests.py @@ -115,10 +115,11 @@ def make_with_parameter_request(self): http = aiohttp.ClientSession(auto_decompress=False) return aiohttp_requests.Request(http) - def test_unsupported_session(self): + @pytest.mark.asyncio + async def test_unsupported_session(self): http = aiohttp.ClientSession(auto_decompress=True) with pytest.raises(ValueError): - aiohttp_requests.Request(http) + await aiohttp_requests.Request(http) def test_timeout(self): http = mock.create_autospec( From 5128e3ca9fb9f1d4d7398a5a1fa144cf31fe5236 Mon Sep 17 00:00:00 2001 From: Linchin Date: Fri, 17 Oct 2025 20:11:54 +0000 Subject: [PATCH 09/13] make 2 unit tests async --- tests_async/transport/test_aiohttp_requests.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests_async/transport/test_aiohttp_requests.py b/tests_async/transport/test_aiohttp_requests.py index ec6ff19a1..8a5f0f3be 100644 --- a/tests_async/transport/test_aiohttp_requests.py +++ b/tests_async/transport/test_aiohttp_requests.py @@ -145,17 +145,19 @@ class TestAuthorizedSession(object): TEST_URL = "http://example.com/" method = "GET" - def test_constructor(self): - authed_session = aiohttp_requests.AuthorizedSession(mock.sentinel.credentials) + @pytest.mark.asyncio + async def test_constructor(self): + authed_session = await aiohttp_requests.AuthorizedSession(mock.sentinel.credentials) assert authed_session.credentials == mock.sentinel.credentials - def test_constructor_with_auth_request(self): + @pytest.mark.asyncio + async def test_constructor_with_auth_request(self): http = mock.create_autospec( aiohttp.ClientSession, instance=True, _auto_decompress=False ) auth_request = aiohttp_requests.Request(http) - authed_session = aiohttp_requests.AuthorizedSession( + authed_session = await aiohttp_requests.AuthorizedSession( mock.sentinel.credentials, auth_request=auth_request ) From 9ef18cc9ae198dcd9ad5d20aa0d016bc21fa968d Mon Sep 17 00:00:00 2001 From: Linchin Date: Fri, 17 Oct 2025 20:49:19 +0000 Subject: [PATCH 10/13] remove await --- tests_async/transport/test_aiohttp_requests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests_async/transport/test_aiohttp_requests.py b/tests_async/transport/test_aiohttp_requests.py index 8a5f0f3be..e910779a6 100644 --- a/tests_async/transport/test_aiohttp_requests.py +++ b/tests_async/transport/test_aiohttp_requests.py @@ -147,7 +147,7 @@ class TestAuthorizedSession(object): @pytest.mark.asyncio async def test_constructor(self): - authed_session = await aiohttp_requests.AuthorizedSession(mock.sentinel.credentials) + authed_session = aiohttp_requests.AuthorizedSession(mock.sentinel.credentials) assert authed_session.credentials == mock.sentinel.credentials @pytest.mark.asyncio @@ -157,7 +157,7 @@ async def test_constructor_with_auth_request(self): ) auth_request = aiohttp_requests.Request(http) - authed_session = await aiohttp_requests.AuthorizedSession( + authed_session = aiohttp_requests.AuthorizedSession( mock.sentinel.credentials, auth_request=auth_request ) From 5cd841de03b5806c6433f02a06f7c24854e36caf Mon Sep 17 00:00:00 2001 From: Linchin Date: Tue, 21 Oct 2025 18:54:36 +0000 Subject: [PATCH 11/13] update requirements --- samples/cloud-client/snippets/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/cloud-client/snippets/requirements.txt b/samples/cloud-client/snippets/requirements.txt index 0df083439..3e0882c66 100644 --- a/samples/cloud-client/snippets/requirements.txt +++ b/samples/cloud-client/snippets/requirements.txt @@ -1,5 +1,5 @@ google-cloud-compute==1.5.1 google-cloud-storage==3.1.0 google-auth==2.38.0 -pytest==7.1.2; python_version <= '3.13' +pytest===7.1.2; python_version <= '3.13' pytest==8.4.2; python_version == '3.14' From f5add77be66c426b335c621d8bf12474e2fe6972 Mon Sep 17 00:00:00 2001 From: Linchin Date: Tue, 21 Oct 2025 20:36:58 +0000 Subject: [PATCH 12/13] add value for env var AUTHORIZED_USER_FILE --- system_tests/system_tests_sync/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/system_tests/system_tests_sync/conftest.py b/system_tests/system_tests_sync/conftest.py index 16caa659e..cd3afaaac 100644 --- a/system_tests/system_tests_sync/conftest.py +++ b/system_tests/system_tests_sync/conftest.py @@ -33,6 +33,7 @@ REQUESTS_SESSION = requests.Session() REQUESTS_SESSION.verify = False TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo" +AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json") @pytest.fixture From 1aeb62598162c99776102be665ce69a878f6ca30 Mon Sep 17 00:00:00 2001 From: Linchin Date: Fri, 24 Oct 2025 18:30:44 +0000 Subject: [PATCH 13/13] remove AUTHORIZED_USER_FILE --- system_tests/system_tests_sync/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/system_tests/system_tests_sync/conftest.py b/system_tests/system_tests_sync/conftest.py index cd3afaaac..16caa659e 100644 --- a/system_tests/system_tests_sync/conftest.py +++ b/system_tests/system_tests_sync/conftest.py @@ -33,7 +33,6 @@ REQUESTS_SESSION = requests.Session() REQUESTS_SESSION.verify = False TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo" -AUTHORIZED_USER_FILE = os.path.join(DATA_DIR, "authorized_user.json") @pytest.fixture