diff --git a/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 b/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 index 8ee1670431..abe33f8575 100644 --- a/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 +++ b/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 @@ -7,6 +7,92 @@ from {{package_path}} import gapic_version as package_version __version__ = package_version.__version__ + +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + {# TODO(api_core): remove `type:ignore` below when minimum version of api_core makes the else clause unnecessary. #} + api_core.check_python_version("{{package_path}}") # type: ignore + api_core.check_dependency_versions("{{package_path}}") # type: ignore +else: # pragma: NO COVER +{# TODO(api_core): Remove this try-catch when we require api-core at a version that + supports the changes in https://github.com/googleapis/python-api-core/pull/832 + + In the meantime, please ensure the functionality here mirrors the + equivalent functionality in api_core, in those two functions above. +#} + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "{{package_path}}" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + {# Import subpackages. -#} {% for subpackage, _ in api.subpackages|dictsort %} from . import {{ subpackage }} diff --git a/gapic/templates/setup.py.j2 b/gapic/templates/setup.py.j2 index 6573b942db..5f2f803315 100644 --- a/gapic/templates/setup.py.j2 +++ b/gapic/templates/setup.py.j2 @@ -39,6 +39,7 @@ dependencies = [ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", {# Explicitly exclude protobuf versions mentioned in https://cloud.google.com/support/bulletins#GCP-2022-019 #} diff --git a/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 b/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 index 31ab20095b..6391c95768 100644 --- a/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 +++ b/gapic/templates/tests/unit/gapic/%name_%version/%sub/test_%service.py.j2 @@ -1472,6 +1472,7 @@ def test_{{ service.name|snake_case }}_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.{{ service.grpc_transport_name }}, transports.{{ service.grpc_asyncio_transport_name }}]) def test_{{ service.name|snake_case }}_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/noxfile.py b/noxfile.py index bfc4fff8b4..5571594f7f 100644 --- a/noxfile.py +++ b/noxfile.py @@ -61,6 +61,8 @@ def unit(session): "pyfakefs", "grpcio-status", "proto-plus", + "setuptools", # TODO: Remove when not needed in __init__.py.j2 + "packaging", # TODO: Remove when not needed in __init__.py.j2 ) session.install("-e", ".") session.run( @@ -482,6 +484,8 @@ def run_showcase_unit_tests(session, fail_under=100, rest_async_io_enabled=False "pytest-xdist", "asyncmock; python_version < '3.8'", "pytest-asyncio", + "setuptools", # TODO: Remove when not needed in __init__.py.j2 + "packaging", # TODO: Remove when not needed in __init__.py.j2 ) # Run the tests. # NOTE: async rest is not supported against the minimum supported version of google-api-core. @@ -596,6 +600,8 @@ def showcase_mypy( "types-protobuf", "types-requests", "types-dataclasses", + "setuptools", # TODO: Remove when not needed in __init__.py.j2 + "packaging", # TODO: Remove when not needed in __init__.py.j2 ) with showcase_library(session, templates=templates, other_opts=other_opts) as lib: @@ -726,6 +732,8 @@ def mypy(session): "types-PyYAML", "types-dataclasses", "click==8.1.3", + "setuptools", # TODO: Remove when not needed in __init__.py.j2 + "packaging", # TODO: Remove when not needed in __init__.py.j2 ) session.install(".") session.run("mypy", "-p", "gapic") diff --git a/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py b/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py index 03ee9ec521..4f4362db8d 100755 --- a/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py +++ b/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py @@ -18,6 +18,85 @@ __version__ = package_version.__version__ +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + api_core.check_python_version("google.cloud.asset_v1") # type: ignore + api_core.check_dependency_versions("google.cloud.asset_v1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.asset_v1" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + + from .services.asset_service import AssetServiceClient from .services.asset_service import AssetServiceAsyncClient diff --git a/tests/integration/goldens/asset/setup.py b/tests/integration/goldens/asset/setup.py index db0a03c590..f7d2a2bdf8 100755 --- a/tests/integration/goldens/asset/setup.py +++ b/tests/integration/goldens/asset/setup.py @@ -45,6 +45,7 @@ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", diff --git a/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py b/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py index 10cb01ca87..edd142a808 100755 --- a/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py +++ b/tests/integration/goldens/asset/tests/unit/gapic/asset_v1/test_asset_service.py @@ -17712,6 +17712,7 @@ def test_asset_service_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.AssetServiceGrpcTransport, transports.AssetServiceGrpcAsyncIOTransport]) def test_asset_service_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py b/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py index 2be4471eb8..3dd77183a7 100755 --- a/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py +++ b/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py @@ -18,6 +18,85 @@ __version__ = package_version.__version__ +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + api_core.check_python_version("google.iam.credentials_v1") # type: ignore + api_core.check_dependency_versions("google.iam.credentials_v1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.iam.credentials_v1" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + + from .services.iam_credentials import IAMCredentialsClient from .services.iam_credentials import IAMCredentialsAsyncClient diff --git a/tests/integration/goldens/credentials/setup.py b/tests/integration/goldens/credentials/setup.py index eaba6dcd0c..f4ebe518e8 100755 --- a/tests/integration/goldens/credentials/setup.py +++ b/tests/integration/goldens/credentials/setup.py @@ -45,6 +45,7 @@ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", diff --git a/tests/integration/goldens/credentials/tests/unit/gapic/credentials_v1/test_iam_credentials.py b/tests/integration/goldens/credentials/tests/unit/gapic/credentials_v1/test_iam_credentials.py index 62b329f3e5..90ddb8c449 100755 --- a/tests/integration/goldens/credentials/tests/unit/gapic/credentials_v1/test_iam_credentials.py +++ b/tests/integration/goldens/credentials/tests/unit/gapic/credentials_v1/test_iam_credentials.py @@ -3972,6 +3972,7 @@ def test_iam_credentials_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.IAMCredentialsGrpcTransport, transports.IAMCredentialsGrpcAsyncIOTransport]) def test_iam_credentials_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py b/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py index a343867284..714542db61 100755 --- a/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py +++ b/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py @@ -18,6 +18,85 @@ __version__ = package_version.__version__ +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + api_core.check_python_version("google.cloud.eventarc_v1") # type: ignore + api_core.check_dependency_versions("google.cloud.eventarc_v1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.eventarc_v1" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + + from .services.eventarc import EventarcClient from .services.eventarc import EventarcAsyncClient diff --git a/tests/integration/goldens/eventarc/setup.py b/tests/integration/goldens/eventarc/setup.py index 8f8887b4d5..aeb6fdeb1c 100755 --- a/tests/integration/goldens/eventarc/setup.py +++ b/tests/integration/goldens/eventarc/setup.py @@ -45,6 +45,7 @@ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", diff --git a/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py b/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py index 66ac1829f1..c815caafc5 100755 --- a/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py +++ b/tests/integration/goldens/eventarc/tests/unit/gapic/eventarc_v1/test_eventarc.py @@ -15378,6 +15378,7 @@ def test_eventarc_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.EventarcGrpcTransport, transports.EventarcGrpcAsyncIOTransport]) def test_eventarc_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py b/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py index e8b59e0bb5..65abc3b298 100755 --- a/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py +++ b/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py @@ -18,6 +18,85 @@ __version__ = package_version.__version__ +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + api_core.check_python_version("google.cloud.logging_v2") # type: ignore + api_core.check_dependency_versions("google.cloud.logging_v2") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.logging_v2" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + + from .services.config_service_v2 import ConfigServiceV2Client from .services.config_service_v2 import ConfigServiceV2AsyncClient from .services.logging_service_v2 import LoggingServiceV2Client diff --git a/tests/integration/goldens/logging/setup.py b/tests/integration/goldens/logging/setup.py index cb6015c69b..0c103cd02f 100755 --- a/tests/integration/goldens/logging/setup.py +++ b/tests/integration/goldens/logging/setup.py @@ -45,6 +45,7 @@ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", diff --git a/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py b/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py index 5de14eaafe..c284e58f8b 100755 --- a/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py +++ b/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_config_service_v2.py @@ -12897,6 +12897,7 @@ def test_config_service_v2_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.ConfigServiceV2GrpcTransport, transports.ConfigServiceV2GrpcAsyncIOTransport]) def test_config_service_v2_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py b/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py index 195d456017..3a3740300b 100755 --- a/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py +++ b/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_logging_service_v2.py @@ -3445,6 +3445,7 @@ def test_logging_service_v2_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.LoggingServiceV2GrpcTransport, transports.LoggingServiceV2GrpcAsyncIOTransport]) def test_logging_service_v2_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py b/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py index a7b6c70e07..4633e315a1 100755 --- a/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py +++ b/tests/integration/goldens/logging/tests/unit/gapic/logging_v2/test_metrics_service_v2.py @@ -3249,6 +3249,7 @@ def test_metrics_service_v2_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.MetricsServiceV2GrpcTransport, transports.MetricsServiceV2GrpcAsyncIOTransport]) def test_metrics_service_v2_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py b/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py index 3e0f9c2155..ab630bbc65 100755 --- a/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py +++ b/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py @@ -18,6 +18,85 @@ __version__ = package_version.__version__ +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + api_core.check_python_version("google.cloud.logging_v2") # type: ignore + api_core.check_dependency_versions("google.cloud.logging_v2") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.logging_v2" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + + from .services.config_service_v2 import BaseConfigServiceV2Client from .services.config_service_v2 import BaseConfigServiceV2AsyncClient from .services.logging_service_v2 import LoggingServiceV2Client diff --git a/tests/integration/goldens/logging_internal/setup.py b/tests/integration/goldens/logging_internal/setup.py index cb6015c69b..0c103cd02f 100755 --- a/tests/integration/goldens/logging_internal/setup.py +++ b/tests/integration/goldens/logging_internal/setup.py @@ -45,6 +45,7 @@ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", diff --git a/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py b/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py index e206a2486b..97d56ab135 100755 --- a/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py +++ b/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_config_service_v2.py @@ -12897,6 +12897,7 @@ def test_config_service_v2_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.ConfigServiceV2GrpcTransport, transports.ConfigServiceV2GrpcAsyncIOTransport]) def test_config_service_v2_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py b/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py index 195d456017..3a3740300b 100755 --- a/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py +++ b/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_logging_service_v2.py @@ -3445,6 +3445,7 @@ def test_logging_service_v2_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.LoggingServiceV2GrpcTransport, transports.LoggingServiceV2GrpcAsyncIOTransport]) def test_logging_service_v2_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py b/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py index 35cb37f70d..bcb2c8346f 100755 --- a/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py +++ b/tests/integration/goldens/logging_internal/tests/unit/gapic/logging_v2/test_metrics_service_v2.py @@ -3249,6 +3249,7 @@ def test_metrics_service_v2_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.MetricsServiceV2GrpcTransport, transports.MetricsServiceV2GrpcAsyncIOTransport]) def test_metrics_service_v2_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py b/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py index af3d250ccd..8db2b26e65 100755 --- a/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py +++ b/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py @@ -18,6 +18,85 @@ __version__ = package_version.__version__ +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + api_core.check_python_version("google.cloud.redis_v1") # type: ignore + api_core.check_dependency_versions("google.cloud.redis_v1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.redis_v1" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + + from .services.cloud_redis import CloudRedisClient from .services.cloud_redis import CloudRedisAsyncClient diff --git a/tests/integration/goldens/redis/setup.py b/tests/integration/goldens/redis/setup.py index 026674b2d3..cf35d014a4 100755 --- a/tests/integration/goldens/redis/setup.py +++ b/tests/integration/goldens/redis/setup.py @@ -45,6 +45,7 @@ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", diff --git a/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py b/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py index 4ff5644cdc..02549e2f2f 100755 --- a/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py +++ b/tests/integration/goldens/redis/tests/unit/gapic/redis_v1/test_cloud_redis.py @@ -11657,6 +11657,7 @@ def test_cloud_redis_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.CloudRedisGrpcTransport, transports.CloudRedisGrpcAsyncIOTransport]) def test_cloud_redis_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py b/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py index 760fe80f6c..b781ff92cd 100755 --- a/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py +++ b/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py @@ -18,6 +18,85 @@ __version__ = package_version.__version__ +import google.api_core as api_core + +if hasattr(api_core, "check_python_version") and hasattr(api_core, "check_dependency_versions"): # pragma: NO COVER + api_core.check_python_version("google.cloud.redis_v1") # type: ignore + api_core.check_dependency_versions("google.cloud.redis_v1") # type: ignore +else: # pragma: NO COVER + # An older version of api_core is installed which does not define the + # functions above. We do equivalent checks manually. + try: + import warnings + import sys + + _py_version_str = sys.version.split()[0] + _package_label = "google.cloud.redis_v1" + if sys.version_info < (3, 9): + warnings.warn("You are using a non-supported Python version " + + f"({_py_version_str}). Google will not post any further " + + f"updates to {_package_label} supporting this Python version. " + + "Please upgrade to the latest Python version, or at " + + f"least to Python 3.9, and then update {_package_label}.", + FutureWarning) + if sys.version_info[:2] == (3, 9): + warnings.warn(f"You are using a Python version ({_py_version_str}) " + + f"which Google will stop supporting in {_package_label} in " + + "January 2026. Please " + + "upgrade to the latest Python version, or at " + + "least to Python 3.10, before then, and " + + f"then update {_package_label}.", + FutureWarning) + + from packaging.version import parse as parse_version + + if sys.version_info < (3, 8): + import pkg_resources + + def _get_version(dependency_name): + try: + version_string = pkg_resources.get_distribution(dependency_name).version + return (parse_version(version_string), version_string) + except pkg_resources.DistributionNotFound: + return (None, "--") + else: + from importlib import metadata + + def _get_version(dependency_name): + try: + version_string = metadata.version("requests") + parsed_version = parse_version(version_string) + return (parsed_version.release, version_string) + except metadata.PackageNotFoundError: + return (None, "--") + + _dependency_package = "google.protobuf" + _next_supported_version = "4.25.8" + _next_supported_version_tuple = (4, 25, 8) + _recommendation = " (we recommend 6.x)" + (_version_used, _version_used_string) = _get_version(_dependency_package) + if _version_used and _version_used < _next_supported_version_tuple: + warnings.warn(f"Package {_package_label} depends on " + + f"{_dependency_package}, currently installed at version " + + f"{_version_used_string}. Future updates to " + + f"{_package_label} will require {_dependency_package} at " + + f"version {_next_supported_version} or higher{_recommendation}." + + " Please ensure " + + "that either (a) your Python environment doesn't pin the " + + f"version of {_dependency_package}, so that updates to " + + f"{_package_label} can require the higher version, or " + + "(b) you manually update your Python environment to use at " + + f"least version {_next_supported_version} of " + + f"{_dependency_package}.", + FutureWarning) + except Exception: + warnings.warn("Could not determine the version of Python " + + "currently being used. To continue receiving " + + "updates for {_package_label}, ensure you are " + + "using a supported version of Python; see " + + "https://devguide.python.org/versions/") + + from .services.cloud_redis import CloudRedisClient from .services.cloud_redis import CloudRedisAsyncClient diff --git a/tests/integration/goldens/redis_selective/setup.py b/tests/integration/goldens/redis_selective/setup.py index 026674b2d3..cf35d014a4 100755 --- a/tests/integration/goldens/redis_selective/setup.py +++ b/tests/integration/goldens/redis_selective/setup.py @@ -45,6 +45,7 @@ "google-auth >= 2.14.1, <3.0.0,!=2.24.0,!=2.25.0", "grpcio >= 1.33.2, < 2.0.0", "grpcio >= 1.75.1, < 2.0.0; python_version >= '3.14'", + "packaging", # TODO: Remove once we require versions of api core that include this "proto-plus >= 1.22.3, <2.0.0", "proto-plus >= 1.25.0, <2.0.0; python_version >= '3.13'", "protobuf>=3.20.2,<7.0.0,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5", diff --git a/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py b/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py index fd46390682..2aed5640c0 100755 --- a/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py +++ b/tests/integration/goldens/redis_selective/tests/unit/gapic/redis_v1/test_cloud_redis.py @@ -6823,6 +6823,7 @@ def test_cloud_redis_grpc_asyncio_transport_channel(): # Remove this test when deprecated arguments (api_mtls_endpoint, client_cert_source) are # removed from grpc/grpc_asyncio transport constructor. +@pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize("transport_class", [transports.CloudRedisGrpcTransport, transports.CloudRedisGrpcAsyncIOTransport]) def test_cloud_redis_transport_channel_mtls_with_client_cert_source( transport_class diff --git a/tests/system/test_response_metadata.py b/tests/system/test_response_metadata.py index f99abf3e11..2cc8681455 100644 --- a/tests/system/test_response_metadata.py +++ b/tests/system/test_response_metadata.py @@ -84,6 +84,7 @@ async def test_metadata_response_rest_streams_async(intercepted_echo_rest_async) ("rest_asyncio", ("X-Showcase-Request-Something3", "something_value3")), ], ) + @pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.asyncio async def test_metadata_response_unary_async( intercepted_echo_grpc_async,