From 307916cdd99fc99bb4de567848f0809746db0562 Mon Sep 17 00:00:00 2001 From: Anthonios Partheniou Date: Tue, 28 Nov 2023 19:23:29 -0500 Subject: [PATCH] feat: Add support for Python 3.12 (#1421) * feat: Add support for Python 3.12 * Add samples lint session * Add constraints file for python 3.12 * chore: Refresh system test creds. * only run specified nox session for samples --------- Co-authored-by: Carl Lundin --- .github/sync-repo-settings.yaml | 2 + .kokoro/samples-test-setup.sh | 4 +- .kokoro/samples/lint/common.cfg | 7 +++ .kokoro/samples/python3.10/common.cfg | 6 +++ .kokoro/samples/python3.11/common.cfg | 37 ++++++++++++++ .kokoro/samples/python3.11/continuous.cfg | 6 +++ .kokoro/samples/python3.11/periodic-head.cfg | 11 +++++ .kokoro/samples/python3.11/periodic.cfg | 6 +++ .kokoro/samples/python3.11/presubmit.cfg | 6 +++ .kokoro/samples/python3.12/common.cfg | 37 ++++++++++++++ .kokoro/samples/python3.12/continuous.cfg | 6 +++ .kokoro/samples/python3.12/periodic-head.cfg | 11 +++++ .kokoro/samples/python3.12/periodic.cfg | 6 +++ .kokoro/samples/python3.12/presubmit.cfg | 6 +++ .kokoro/samples/python3.7/common.cfg | 7 +++ .kokoro/samples/python3.8/common.cfg | 6 +++ .kokoro/samples/python3.9/common.cfg | 6 +++ CONTRIBUTING.rst | 2 +- noxfile.py | 2 +- .../authenticate_implicit_with_adc.py | 2 +- samples/cloud-client/snippets/noxfile.py | 45 ++++++++++++++++-- setup.py | 1 + system_tests/secrets.tar.enc | Bin 10324 -> 10324 bytes testing/constraints-2.7.txt | 1 - testing/constraints-3.12.txt | 1 + 25 files changed, 214 insertions(+), 10 deletions(-) create mode 100644 .kokoro/samples/python3.11/common.cfg create mode 100644 .kokoro/samples/python3.11/continuous.cfg create mode 100644 .kokoro/samples/python3.11/periodic-head.cfg create mode 100644 .kokoro/samples/python3.11/periodic.cfg create mode 100644 .kokoro/samples/python3.11/presubmit.cfg create mode 100644 .kokoro/samples/python3.12/common.cfg create mode 100644 .kokoro/samples/python3.12/continuous.cfg create mode 100644 .kokoro/samples/python3.12/periodic-head.cfg create mode 100644 .kokoro/samples/python3.12/periodic.cfg create mode 100644 .kokoro/samples/python3.12/presubmit.cfg delete mode 100644 testing/constraints-2.7.txt create mode 100644 testing/constraints-3.12.txt diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index ab8bb03fa..5ebb96e6a 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -15,6 +15,8 @@ branchProtectionRules: - 'Samples - Python 3.8' - 'Samples - Python 3.9' - 'Samples - Python 3.10' + - 'Samples - Python 3.11' + - 'Samples - Python 3.12' permissionRules: - team: actools-python permission: admin diff --git a/.kokoro/samples-test-setup.sh b/.kokoro/samples-test-setup.sh index 938402a92..5be9713ef 100755 --- a/.kokoro/samples-test-setup.sh +++ b/.kokoro/samples-test-setup.sh @@ -44,5 +44,5 @@ gcloud config set project ${PROJECT_ID} # Decrypt system test secrets ./scripts/decrypt-secrets.sh -# Run system tests which use a different noxfile -python3 -m nox -f samples/cloud-client/snippets/noxfile.py +# Run samples tests which use a different noxfile +python3 -m nox -f samples/cloud-client/snippets/noxfile.py -s "$RUN_TESTS_SESSION" diff --git a/.kokoro/samples/lint/common.cfg b/.kokoro/samples/lint/common.cfg index da47830eb..e38920a08 100644 --- a/.kokoro/samples/lint/common.cfg +++ b/.kokoro/samples/lint/common.cfg @@ -7,6 +7,13 @@ action { } } +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "lint" +} + + # Download trampoline resources. gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" diff --git a/.kokoro/samples/python3.10/common.cfg b/.kokoro/samples/python3.10/common.cfg index da47830eb..022eaafda 100644 --- a/.kokoro/samples/python3.10/common.cfg +++ b/.kokoro/samples/python3.10/common.cfg @@ -7,6 +7,12 @@ action { } } +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "unit-3.10" +} + # Download trampoline resources. gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" diff --git a/.kokoro/samples/python3.11/common.cfg b/.kokoro/samples/python3.11/common.cfg new file mode 100644 index 000000000..25be29326 --- /dev/null +++ b/.kokoro/samples/python3.11/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.11" +} + +# 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.11/continuous.cfg b/.kokoro/samples/python3.11/continuous.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.11/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.11/periodic-head.cfg b/.kokoro/samples/python3.11/periodic-head.cfg new file mode 100644 index 000000000..83eace873 --- /dev/null +++ b/.kokoro/samples/python3.11/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.11/periodic.cfg b/.kokoro/samples/python3.11/periodic.cfg new file mode 100644 index 000000000..71cd1e597 --- /dev/null +++ b/.kokoro/samples/python3.11/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.11/presubmit.cfg b/.kokoro/samples/python3.11/presubmit.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.11/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/.kokoro/samples/python3.12/common.cfg b/.kokoro/samples/python3.12/common.cfg new file mode 100644 index 000000000..25d2ea1de --- /dev/null +++ b/.kokoro/samples/python3.12/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.12" +} + +# 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.12/continuous.cfg b/.kokoro/samples/python3.12/continuous.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.12/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.12/periodic-head.cfg b/.kokoro/samples/python3.12/periodic-head.cfg new file mode 100644 index 000000000..83eace873 --- /dev/null +++ b/.kokoro/samples/python3.12/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.12/periodic.cfg b/.kokoro/samples/python3.12/periodic.cfg new file mode 100644 index 000000000..71cd1e597 --- /dev/null +++ b/.kokoro/samples/python3.12/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.12/presubmit.cfg b/.kokoro/samples/python3.12/presubmit.cfg new file mode 100644 index 000000000..a1c8d9759 --- /dev/null +++ b/.kokoro/samples/python3.12/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/.kokoro/samples/python3.7/common.cfg b/.kokoro/samples/python3.7/common.cfg index da47830eb..123c3e122 100644 --- a/.kokoro/samples/python3.7/common.cfg +++ b/.kokoro/samples/python3.7/common.cfg @@ -7,6 +7,13 @@ action { } } + +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "unit-3.7" +} + # Download trampoline resources. gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" diff --git a/.kokoro/samples/python3.8/common.cfg b/.kokoro/samples/python3.8/common.cfg index da47830eb..62108f6be 100644 --- a/.kokoro/samples/python3.8/common.cfg +++ b/.kokoro/samples/python3.8/common.cfg @@ -7,6 +7,12 @@ action { } } +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "unit-3.8" +} + # Download trampoline resources. gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" diff --git a/.kokoro/samples/python3.9/common.cfg b/.kokoro/samples/python3.9/common.cfg index da47830eb..2649c6c6e 100644 --- a/.kokoro/samples/python3.9/common.cfg +++ b/.kokoro/samples/python3.9/common.cfg @@ -7,6 +7,12 @@ action { } } +# Specify which tests to run +env_vars: { + key: "RUN_TESTS_SESSION" + value: "unit-3.9" +} + # Download trampoline resources. gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3d07261ec..34a91ec7a 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -19,7 +19,7 @@ A few notes on making changes to ``google-auth-library-python``. using ``nox -s docgen``. - The change must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10 across macOS, Linux, and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11 and 3.12 across macOS, Linux, and Windows. - The codebase *must* have 100% test statement coverage after each commit. You can test coverage via ``nox -e cover``. diff --git a/noxfile.py b/noxfile.py index 4ec313407..07cef9bcc 100644 --- a/noxfile.py +++ b/noxfile.py @@ -84,7 +84,7 @@ def mypy(session): session.run("mypy", "-p", "google", "-p", "tests", "-p", "tests_async") -@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11"]) +@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]) def unit(session): constraints_path = str( CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" diff --git a/samples/cloud-client/snippets/authenticate_implicit_with_adc.py b/samples/cloud-client/snippets/authenticate_implicit_with_adc.py index 006e75bf6..2c1a0414d 100644 --- a/samples/cloud-client/snippets/authenticate_implicit_with_adc.py +++ b/samples/cloud-client/snippets/authenticate_implicit_with_adc.py @@ -43,4 +43,4 @@ def authenticate_implicit_with_adc(project_id="your-google-cloud-project-id"): print(bucket.name) print("Listed all storage buckets.") -# [END auth_cloud_implicit_adc] \ No newline at end of file +# [END auth_cloud_implicit_adc] diff --git a/samples/cloud-client/snippets/noxfile.py b/samples/cloud-client/snippets/noxfile.py index e129dca59..f5d827941 100644 --- a/samples/cloud-client/snippets/noxfile.py +++ b/samples/cloud-client/snippets/noxfile.py @@ -12,9 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import pathlib -import shutil import nox @@ -33,7 +31,36 @@ "docs/conf.py", ] -@nox.session(python=["3.7", "3.8", "3.9", "3.10"]) + +# Error if a python version is missing +nox.options.error_on_missing_interpreters = True + +# +# Style Checks +# + + +# Linting with flake8. +# +# We ignore the following rules: +# E203: whitespace before ‘:’ +# E266: too many leading ‘#’ for block comment +# E501: line too long +# I202: Additional newline in a section of imports +# +# We also need to specify the rules which are ignored by default: +# ['E226', 'W504', 'E126', 'E123', 'W503', 'E24', 'E704', 'E121'] +FLAKE8_COMMON_ARGS = [ + "--show-source", + "--builtin=gettext", + "--max-complexity=20", + "--exclude=.nox,.cache,env,lib,generated_pb2,*_pb2.py,*_pb2_grpc.py", + "--ignore=E121,E123,E126,E203,E226,E24,E266,E501,E704,W503,W504,I202", + "--max-line-length=88", +] + + +@nox.session(python=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]) def unit(session): # constraints_path = str( # CURRENT_DIRECTORY / "testing" / f"constraints-{session.python}.txt" @@ -45,4 +72,14 @@ def unit(session): f"--junitxml=unit_{session.python}_sponge_log.xml", "snippets_test.py", # "tests_async", - ) \ No newline at end of file + ) + + +@nox.session +def lint(session: nox.sessions.Session) -> None: + session.install("flake8") + + args = FLAKE8_COMMON_ARGS + [ + ".", + ] + session.run("flake8", *args) diff --git a/setup.py b/setup.py index 047818ca0..71a3655fa 100644 --- a/setup.py +++ b/setup.py @@ -70,6 +70,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", diff --git a/system_tests/secrets.tar.enc b/system_tests/secrets.tar.enc index 06696ab2ab4464b5cd1c5246fa09304e189166b2..937b6f065e8e90a37d6aaba424e4b73010ef785b 100644 GIT binary patch literal 10324 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 literal 10324 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 maDa>Rh^@{#K}!?W}skBc_JS4|12.0.0 \ No newline at end of file