diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index 6f1eaeb9..0de95e19 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -13,5 +13,5 @@ # limitations under the License. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:ecf409a43d8b157fb83c403de4d83e3da7d88e423044410c0e2434bf776221d1 + digest: sha256:543e209e7c1c1ffe720eb4db1a3f045a75099304fb19aa11a47dc717b8aae2a9 # created: 2025-04-10T16:21:41.67162455Z diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 439a0bcb..f38e0685 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -16,3 +16,5 @@ branchProtectionRules: - 'Samples - Python 3.10' - 'Samples - Python 3.11' - 'Samples - Python 3.12' + - 'Samples - Python 3.13' + - 'Samples - Python 3.14' diff --git a/.kokoro/samples/python3.14/common.cfg b/.kokoro/samples/python3.14/common.cfg new file mode 100644 index 00000000..0fa3f1ba --- /dev/null +++ b/.kokoro/samples/python3.14/common.cfg @@ -0,0 +1,60 @@ +# 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: "py-3.14" +} + +# Declare build specific Cloud project. +env_vars: { + key: "BUILD_SPECIFIC_GCLOUD_PROJECT" + value: "python-docs-samples-tests-314" +} + +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/python-logging/.kokoro/test-samples.sh" +} + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-samples-testing-docker" +} + +# Download secrets for samples +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/python-docs-samples" + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "python-logging/.kokoro/trampoline_v2.sh" + + +############################################# +# this section merged from .kokoro/common_env_vars.cfg using owlbot.py + +env_vars: { + key: "PRODUCT_AREA_LABEL" + value: "observability" +} +env_vars: { + key: "PRODUCT_LABEL" + value: "logging" +} +env_vars: { + key: "LANGUAGE_LABEL" + value: "python" +} + +################################################### + diff --git a/.kokoro/samples/python3.14/continuous.cfg b/.kokoro/samples/python3.14/continuous.cfg new file mode 100644 index 00000000..a1c8d975 --- /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 00000000..7e2973e3 --- /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/python-logging/.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 00000000..71cd1e59 --- /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 00000000..a1c8d975 --- /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/CONTRIBUTING.rst b/CONTRIBUTING.rst index 7bbacd5c..e029e882 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -22,7 +22,7 @@ In order to add a feature: documentation. - The feature must work fully on the following CPython versions: - 3.7, 3.8, 3.9, 3.10, 3.11, 3.12 and 3.13 on both UNIX and Windows. + 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows. - The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should @@ -72,7 +72,7 @@ We use `nox `__ to instrument our tests. - To run a single unit test:: - $ nox -s unit-3.13 -- -k + $ nox -s unit-3.14 -- -k .. note:: @@ -143,12 +143,12 @@ Running System Tests $ nox -s system # Run a single system test - $ nox -s system-3.12 -- -k + $ nox -s system-3.19 -- -k .. note:: - System tests are only configured to run under Python 3.12. + System tests are only configured to run under Python 3.19. For expediency, we do not run them in older versions of Python 3. This alone will not run the tests. You'll need to change some local @@ -228,6 +228,7 @@ We support: - `Python 3.11`_ - `Python 3.12`_ - `Python 3.13`_ +- `Python 3.14`_ .. _Python 3.7: https://docs.python.org/3.7/ .. _Python 3.8: https://docs.python.org/3.8/ @@ -236,6 +237,7 @@ We support: .. _Python 3.11: https://docs.python.org/3.11/ .. _Python 3.12: https://docs.python.org/3.12/ .. _Python 3.13: https://docs.python.org/3.13/ +.. _Python 3.14: https://docs.python.org/3.14/ Supported versions can be found in our ``noxfile.py`` `config`_. diff --git a/noxfile.py b/noxfile.py index b75e78ac..ed5e4778 100644 --- a/noxfile.py +++ b/noxfile.py @@ -32,7 +32,7 @@ ISORT_VERSION = "isort==5.11.0" LINT_PATHS = ["docs", "google", "tests", "noxfile.py", "setup.py"] -DEFAULT_PYTHON_VERSION = "3.8" +DEFAULT_PYTHON_VERSION = "3.13" UNIT_TEST_PYTHON_VERSIONS: List[str] = [ "3.7", @@ -42,6 +42,7 @@ "3.11", "3.12", "3.13", + "3.14", ] UNIT_TEST_STANDARD_DEPENDENCIES = [ "mock", @@ -60,7 +61,7 @@ UNIT_TEST_EXTRAS: List[str] = [] UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {} -SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.12"] +SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.9"] SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [ "mock", "pytest", @@ -81,7 +82,12 @@ CURRENT_DIRECTORY = pathlib.Path(__file__).parent.absolute() nox.options.sessions = [ - "unit", + "unit-3.9", + "unit-3.10", + "unit-3.11", + "unit-3.12", + "unit-3.13", + "unit-3.14", "system", "cover", "lint", @@ -145,7 +151,7 @@ def format(session): @nox.session(python=DEFAULT_PYTHON_VERSION) def lint_setup_py(session): """Verify that setup.py is valid (including RST check).""" - session.install("docutils", "pygments") + session.install("setuptools", "docutils", "pygments") session.run("python", "setup.py", "check", "--restructuredtext", "--strict") @@ -184,8 +190,8 @@ def install_unittest_dependencies(session, *constraints): ) def unit(session, protobuf_implementation): # Install all test dependencies, then install this package in-place. - - if protobuf_implementation == "cpp" and session.python in ("3.11", "3.12", "3.13"): + py_version = tuple([int(v) for v in session.python.split(".")]) + if protobuf_implementation == "cpp" and py_version >= (3, 11): session.skip("cpp implementation is not supported in python 3.11+") constraints_path = str( @@ -385,7 +391,7 @@ def docfx(session): ) -@nox.session(python="3.13") +@nox.session(python="3.14") @nox.parametrize( "protobuf_implementation", ["python", "upb", "cpp"], diff --git a/owlbot.py b/owlbot.py index 2be8464c..4f8752e3 100644 --- a/owlbot.py +++ b/owlbot.py @@ -95,7 +95,8 @@ def place_before(path, text, *before_text, escape=None): "google-cloud-testutils", "opentelemetry-sdk" ], - system_test_python_versions=["3.12"], + system_test_python_versions=["3.9"], + unit_test_python_versions=["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"], unit_test_external_dependencies=["flask", "webob", "django"], samples=True, ) diff --git a/pytest.ini b/pytest.ini index 2d8ce14b..960d6cba 100644 --- a/pytest.ini +++ b/pytest.ini @@ -27,3 +27,5 @@ filterwarnings = ignore:.*Please use message_factory.GetMessageClass\(\) instead. SymbolDatabase.GetPrototype\(\) will be removed soon.:UserWarning # Remove warning once https://github.com/googleapis/gapic-generator-python/issues/2046 is fixed ignore:coroutine 'AsyncMockMixin._execute_mock_call' was never awaited:RuntimeWarning + # Remove once credential file support is removed + ignore:.*The \`credentials_file\` argument is deprecated.*:DeprecationWarning diff --git a/samples/snippets/export_test.py b/samples/snippets/export_test.py index 845359e0..ef9dc460 100644 --- a/samples/snippets/export_test.py +++ b/samples/snippets/export_test.py @@ -79,6 +79,9 @@ def cleanup_old_sinks(): # Bucket timestamp is int(time.time() * 1000) bucket_timestamp = int(match.group(1)) if TIMESTAMP - bucket_timestamp // 1000 > CLEANUP_THRESHOLD: + # Delete all blobs in the bucket before deleting the bucket. + for blob in bucket.list_blobs(): + _delete_object(blob) _delete_object(bucket) diff --git a/samples/snippets/noxfile.py b/samples/snippets/noxfile.py index c9a3d1ec..c326375b 100644 --- a/samples/snippets/noxfile.py +++ b/samples/snippets/noxfile.py @@ -89,7 +89,7 @@ def get_pytest_env_vars() -> Dict[str, str]: # DO NOT EDIT - automatically generated. # All versions used to test samples. -ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] +ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] # Any default versions that should be ignored. IGNORED_VERSIONS = TEST_CONFIG["ignored_versions"] diff --git a/setup.py b/setup.py index c80db046..0bd8d6a8 100644 --- a/setup.py +++ b/setup.py @@ -85,6 +85,8 @@ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Operating System :: OS Independent", "Topic :: Internet", ], diff --git a/testing/constraints-3.14.txt b/testing/constraints-3.14.txt new file mode 100644 index 00000000..981d37ac --- /dev/null +++ b/testing/constraints-3.14.txt @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# This constraints file is required for unit tests. +# List all library dependencies and extras in this file. +google-api-core +google-auth +proto-plus +protobuf +google-cloud-core +google-cloud-appengine-logging +google-cloud-audit-log +grpc-google-iam-v1 +opentelemetry-api + +# optional dependencies +django +flask diff --git a/tests/system/test_system.py b/tests/system/test_system.py index 487ecde6..fb80e382 100644 --- a/tests/system/test_system.py +++ b/tests/system/test_system.py @@ -1058,7 +1058,7 @@ def retryable(): # http and gapic results should be consistent self.assertEqual(gapic_list[0].insert_id, http_list[0].insert_id) # returned logs should be in descending order - self.assertEqual(gapic_list[0].payload, f"test {log_count-1}") + self.assertEqual(gapic_list[0].payload, f"test {log_count - 1}") RetryErrors( (ServiceUnavailable, InternalServerError, AssertionError),