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 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", 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" diff --git a/samples/cloud-client/snippets/requirements.txt b/samples/cloud-client/snippets/requirements.txt index 97f256bd8..b5c5cea30 100644 --- a/samples/cloud-client/snippets/requirements.txt +++ b/samples/cloud-client/snippets/requirements.txt @@ -1,7 +1,7 @@ google-cloud-compute==1.5.1 google-cloud-storage==3.1.0 google-auth==2.41.1 -pytest==7.1.2 +pytest==8.4.2 boto3>=1.26.0 requests==2.32.3 -python-dotenv==1.1.1 \ No newline at end of file +python-dotenv==1.1.1 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", diff --git a/testing/constraints-3.14.txt b/testing/constraints-3.14.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests_async/transport/test_aiohttp_requests.py b/tests_async/transport/test_aiohttp_requests.py index d00955a7d..e910779a6 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( @@ -144,11 +145,13 @@ class TestAuthorizedSession(object): TEST_URL = "http://example.com/" method = "GET" - def test_constructor(self): + @pytest.mark.asyncio + async def test_constructor(self): authed_session = 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 )