diff --git a/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 b/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 index abe33f8575..9eb968dd01 100644 --- a/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 +++ b/gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2 @@ -5,10 +5,46 @@ {% set package_path = api.naming.module_namespace|join('.') + "." + api.naming.versioned_module_name %} from {{package_path}} import gapic_version as package_version +import google.api_core as api_core +import sys + __version__ = package_version.__version__ +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata -import google.api_core as api_core +{# Import subpackages. -#} +{% for subpackage, _ in api.subpackages|dictsort %} +from . import {{ subpackage }} +{% endfor %} + +{# Import services for this package. -#} +{% for service in api.services.values()|sort(attribute='name') + if service.meta.address.subpackage == api.subpackage_view %} +from .services.{{ service.name|snake_case }} import {{ service.client_name }} +{% if 'grpc' in opts.transport %} +from .services.{{ service.name|snake_case }} import {{ service.async_client_name }} +{% endif %} +{% endfor %} + +{# Import messages and enums from each proto. + It is safe to import all of the messages into the same namespace here, + because protocol buffers itself enforces selector uniqueness within + a proto package. +-#} +{% for proto in api.protos.values()|sort(attribute='name') + if proto.meta.address.subpackage == api.subpackage_view %} +{% for message in proto.messages.values()|sort(attribute='name') %} +from .types.{{ proto.module_name }} import {{ message.name }} +{% endfor %} +{% for enum in proto.enums.values()|sort(attribute='name') %} +from .types.{{ proto.module_name }} import {{ enum.name }} +{% endfor %} +{% endfor %} 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. #} @@ -45,27 +81,35 @@ else: # pragma: NO COVER 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): + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): try: - version_string = metadata.version("requests") - parsed_version = parse_version(version_string) - return (parsed_version.release, version_string) - except metadata.PackageNotFoundError: - return (None, "--") + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + return (None, "--") _dependency_package = "google.protobuf" _next_supported_version = "4.25.8" @@ -93,35 +137,6 @@ else: # pragma: NO COVER "using a supported version of Python; see " + "https://devguide.python.org/versions/") -{# Import subpackages. -#} -{% for subpackage, _ in api.subpackages|dictsort %} -from . import {{ subpackage }} -{% endfor %} - -{# Import services for this package. -#} -{% for service in api.services.values()|sort(attribute='name') - if service.meta.address.subpackage == api.subpackage_view %} -from .services.{{ service.name|snake_case }} import {{ service.client_name }} -{% if 'grpc' in opts.transport %} -from .services.{{ service.name|snake_case }} import {{ service.async_client_name }} -{% endif %} -{% endfor %} - -{# Import messages and enums from each proto. - It is safe to import all of the messages into the same namespace here, - because protocol buffers itself enforces selector uniqueness within - a proto package. --#} -{% for proto in api.protos.values()|sort(attribute='name') - if proto.meta.address.subpackage == api.subpackage_view %} -{% for message in proto.messages.values()|sort(attribute='name') %} -from .types.{{ proto.module_name }} import {{ message.name }} -{% endfor %} -{% for enum in proto.enums.values()|sort(attribute='name') %} -from .types.{{ proto.module_name }} import {{ enum.name }} -{% endfor %} -{% endfor %} - {# Define __all__. This requires the full set of imported names, so we iterate over them again. diff --git a/gapic/templates/setup.py.j2 b/gapic/templates/setup.py.j2 index 5f2f803315..6573b942db 100644 --- a/gapic/templates/setup.py.j2 +++ b/gapic/templates/setup.py.j2 @@ -39,7 +39,6 @@ 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/noxfile.py b/noxfile.py index 0201b17dfe..e99bfad597 100644 --- a/noxfile.py +++ b/noxfile.py @@ -64,8 +64,6 @@ 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( @@ -501,8 +499,6 @@ 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. @@ -617,8 +613,6 @@ 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: @@ -749,8 +743,6 @@ 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 4f4362db8d..31068ac472 100755 --- a/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py +++ b/tests/integration/goldens/asset/google/cloud/asset_v1/__init__.py @@ -15,86 +15,17 @@ # from google.cloud.asset_v1 import gapic_version as package_version -__version__ = package_version.__version__ - - import google.api_core as api_core +import sys -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, "--") +__version__ = package_version.__version__ - _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/") +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata from .services.asset_service import AssetServiceClient @@ -178,6 +109,90 @@ def _get_version(dependency_name): from .types.assets import TimeWindow from .types.assets import VersionedResource +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) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + 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/") + __all__ = ( 'AssetServiceAsyncClient', 'AnalyzeIamPolicyLongrunningMetadata', diff --git a/tests/integration/goldens/asset/setup.py b/tests/integration/goldens/asset/setup.py index f7d2a2bdf8..db0a03c590 100755 --- a/tests/integration/goldens/asset/setup.py +++ b/tests/integration/goldens/asset/setup.py @@ -45,7 +45,6 @@ "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/google/iam/credentials_v1/__init__.py b/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py index 3dd77183a7..2890169a65 100755 --- a/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py +++ b/tests/integration/goldens/credentials/google/iam/credentials_v1/__init__.py @@ -15,10 +15,30 @@ # from google.iam.credentials_v1 import gapic_version as package_version +import google.api_core as api_core +import sys + __version__ = package_version.__version__ +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata -import google.api_core as api_core + +from .services.iam_credentials import IAMCredentialsClient +from .services.iam_credentials import IAMCredentialsAsyncClient + +from .types.common import GenerateAccessTokenRequest +from .types.common import GenerateAccessTokenResponse +from .types.common import GenerateIdTokenRequest +from .types.common import GenerateIdTokenResponse +from .types.common import SignBlobRequest +from .types.common import SignBlobResponse +from .types.common import SignJwtRequest +from .types.common import SignJwtResponse 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 @@ -48,27 +68,35 @@ f"then update {_package_label}.", FutureWarning) - from packaging.version import parse as parse_version - - if sys.version_info < (3, 8): - import pkg_resources + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) - 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: + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple 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" @@ -96,19 +124,6 @@ def _get_version(dependency_name): "using a supported version of Python; see " + "https://devguide.python.org/versions/") - -from .services.iam_credentials import IAMCredentialsClient -from .services.iam_credentials import IAMCredentialsAsyncClient - -from .types.common import GenerateAccessTokenRequest -from .types.common import GenerateAccessTokenResponse -from .types.common import GenerateIdTokenRequest -from .types.common import GenerateIdTokenResponse -from .types.common import SignBlobRequest -from .types.common import SignBlobResponse -from .types.common import SignJwtRequest -from .types.common import SignJwtResponse - __all__ = ( 'IAMCredentialsAsyncClient', 'GenerateAccessTokenRequest', diff --git a/tests/integration/goldens/credentials/setup.py b/tests/integration/goldens/credentials/setup.py index f4ebe518e8..eaba6dcd0c 100755 --- a/tests/integration/goldens/credentials/setup.py +++ b/tests/integration/goldens/credentials/setup.py @@ -45,7 +45,6 @@ "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/google/cloud/eventarc_v1/__init__.py b/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py index 714542db61..20d981ec3e 100755 --- a/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py +++ b/tests/integration/goldens/eventarc/google/cloud/eventarc_v1/__init__.py @@ -15,10 +15,59 @@ # from google.cloud.eventarc_v1 import gapic_version as package_version +import google.api_core as api_core +import sys + __version__ = package_version.__version__ +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata -import google.api_core as api_core + +from .services.eventarc import EventarcClient +from .services.eventarc import EventarcAsyncClient + +from .types.channel import Channel +from .types.channel_connection import ChannelConnection +from .types.discovery import EventType +from .types.discovery import FilteringAttribute +from .types.discovery import Provider +from .types.eventarc import CreateChannelConnectionRequest +from .types.eventarc import CreateChannelRequest +from .types.eventarc import CreateTriggerRequest +from .types.eventarc import DeleteChannelConnectionRequest +from .types.eventarc import DeleteChannelRequest +from .types.eventarc import DeleteTriggerRequest +from .types.eventarc import GetChannelConnectionRequest +from .types.eventarc import GetChannelRequest +from .types.eventarc import GetGoogleChannelConfigRequest +from .types.eventarc import GetProviderRequest +from .types.eventarc import GetTriggerRequest +from .types.eventarc import ListChannelConnectionsRequest +from .types.eventarc import ListChannelConnectionsResponse +from .types.eventarc import ListChannelsRequest +from .types.eventarc import ListChannelsResponse +from .types.eventarc import ListProvidersRequest +from .types.eventarc import ListProvidersResponse +from .types.eventarc import ListTriggersRequest +from .types.eventarc import ListTriggersResponse +from .types.eventarc import OperationMetadata +from .types.eventarc import UpdateChannelRequest +from .types.eventarc import UpdateGoogleChannelConfigRequest +from .types.eventarc import UpdateTriggerRequest +from .types.google_channel_config import GoogleChannelConfig +from .types.trigger import CloudRun +from .types.trigger import Destination +from .types.trigger import EventFilter +from .types.trigger import GKE +from .types.trigger import Pubsub +from .types.trigger import StateCondition +from .types.trigger import Transport +from .types.trigger import Trigger 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 @@ -48,27 +97,35 @@ f"then update {_package_label}.", FutureWarning) - from packaging.version import parse as parse_version - - if sys.version_info < (3, 8): - import pkg_resources + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) - 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: + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple 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" @@ -96,48 +153,6 @@ def _get_version(dependency_name): "using a supported version of Python; see " + "https://devguide.python.org/versions/") - -from .services.eventarc import EventarcClient -from .services.eventarc import EventarcAsyncClient - -from .types.channel import Channel -from .types.channel_connection import ChannelConnection -from .types.discovery import EventType -from .types.discovery import FilteringAttribute -from .types.discovery import Provider -from .types.eventarc import CreateChannelConnectionRequest -from .types.eventarc import CreateChannelRequest -from .types.eventarc import CreateTriggerRequest -from .types.eventarc import DeleteChannelConnectionRequest -from .types.eventarc import DeleteChannelRequest -from .types.eventarc import DeleteTriggerRequest -from .types.eventarc import GetChannelConnectionRequest -from .types.eventarc import GetChannelRequest -from .types.eventarc import GetGoogleChannelConfigRequest -from .types.eventarc import GetProviderRequest -from .types.eventarc import GetTriggerRequest -from .types.eventarc import ListChannelConnectionsRequest -from .types.eventarc import ListChannelConnectionsResponse -from .types.eventarc import ListChannelsRequest -from .types.eventarc import ListChannelsResponse -from .types.eventarc import ListProvidersRequest -from .types.eventarc import ListProvidersResponse -from .types.eventarc import ListTriggersRequest -from .types.eventarc import ListTriggersResponse -from .types.eventarc import OperationMetadata -from .types.eventarc import UpdateChannelRequest -from .types.eventarc import UpdateGoogleChannelConfigRequest -from .types.eventarc import UpdateTriggerRequest -from .types.google_channel_config import GoogleChannelConfig -from .types.trigger import CloudRun -from .types.trigger import Destination -from .types.trigger import EventFilter -from .types.trigger import GKE -from .types.trigger import Pubsub -from .types.trigger import StateCondition -from .types.trigger import Transport -from .types.trigger import Trigger - __all__ = ( 'EventarcAsyncClient', 'Channel', diff --git a/tests/integration/goldens/eventarc/setup.py b/tests/integration/goldens/eventarc/setup.py index aeb6fdeb1c..8f8887b4d5 100755 --- a/tests/integration/goldens/eventarc/setup.py +++ b/tests/integration/goldens/eventarc/setup.py @@ -45,7 +45,6 @@ "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/google/cloud/logging_v2/__init__.py b/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py index 65abc3b298..242a438825 100755 --- a/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py +++ b/tests/integration/goldens/logging/google/cloud/logging_v2/__init__.py @@ -15,86 +15,17 @@ # from google.cloud.logging_v2 import gapic_version as package_version -__version__ = package_version.__version__ - - import google.api_core as api_core +import sys -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, "--") +__version__ = package_version.__version__ - _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/") +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata from .services.config_service_v2 import ConfigServiceV2Client @@ -181,6 +112,90 @@ def _get_version(dependency_name): from .types.logging_metrics import LogMetric from .types.logging_metrics import UpdateLogMetricRequest +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) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + 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/") + __all__ = ( 'ConfigServiceV2AsyncClient', 'LoggingServiceV2AsyncClient', diff --git a/tests/integration/goldens/logging/setup.py b/tests/integration/goldens/logging/setup.py index 0c103cd02f..cb6015c69b 100755 --- a/tests/integration/goldens/logging/setup.py +++ b/tests/integration/goldens/logging/setup.py @@ -45,7 +45,6 @@ "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/google/cloud/logging_v2/__init__.py b/tests/integration/goldens/logging_internal/google/cloud/logging_v2/__init__.py index ab630bbc65..38f3dc49f5 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 @@ -15,86 +15,17 @@ # from google.cloud.logging_v2 import gapic_version as package_version -__version__ = package_version.__version__ - - import google.api_core as api_core +import sys -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, "--") +__version__ = package_version.__version__ - _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/") +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata from .services.config_service_v2 import BaseConfigServiceV2Client @@ -181,6 +112,90 @@ def _get_version(dependency_name): from .types.logging_metrics import LogMetric from .types.logging_metrics import UpdateLogMetricRequest +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) + + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) + + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple + 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/") + __all__ = ( 'BaseConfigServiceV2AsyncClient', 'BaseMetricsServiceV2AsyncClient', diff --git a/tests/integration/goldens/logging_internal/setup.py b/tests/integration/goldens/logging_internal/setup.py index 0c103cd02f..cb6015c69b 100755 --- a/tests/integration/goldens/logging_internal/setup.py +++ b/tests/integration/goldens/logging_internal/setup.py @@ -45,7 +45,6 @@ "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/google/cloud/redis_v1/__init__.py b/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py index 8db2b26e65..c5182e2f84 100755 --- a/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py +++ b/tests/integration/goldens/redis/google/cloud/redis_v1/__init__.py @@ -15,10 +15,49 @@ # from google.cloud.redis_v1 import gapic_version as package_version +import google.api_core as api_core +import sys + __version__ = package_version.__version__ +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata -import google.api_core as api_core + +from .services.cloud_redis import CloudRedisClient +from .services.cloud_redis import CloudRedisAsyncClient + +from .types.cloud_redis import CreateInstanceRequest +from .types.cloud_redis import DeleteInstanceRequest +from .types.cloud_redis import ExportInstanceRequest +from .types.cloud_redis import FailoverInstanceRequest +from .types.cloud_redis import GcsDestination +from .types.cloud_redis import GcsSource +from .types.cloud_redis import GetInstanceAuthStringRequest +from .types.cloud_redis import GetInstanceRequest +from .types.cloud_redis import ImportInstanceRequest +from .types.cloud_redis import InputConfig +from .types.cloud_redis import Instance +from .types.cloud_redis import InstanceAuthString +from .types.cloud_redis import ListInstancesRequest +from .types.cloud_redis import ListInstancesResponse +from .types.cloud_redis import LocationMetadata +from .types.cloud_redis import MaintenancePolicy +from .types.cloud_redis import MaintenanceSchedule +from .types.cloud_redis import NodeInfo +from .types.cloud_redis import OperationMetadata +from .types.cloud_redis import OutputConfig +from .types.cloud_redis import PersistenceConfig +from .types.cloud_redis import RescheduleMaintenanceRequest +from .types.cloud_redis import TlsCertificate +from .types.cloud_redis import UpdateInstanceRequest +from .types.cloud_redis import UpgradeInstanceRequest +from .types.cloud_redis import WeeklyMaintenanceWindow +from .types.cloud_redis import ZoneMetadata 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 @@ -48,27 +87,35 @@ f"then update {_package_label}.", FutureWarning) - from packaging.version import parse as parse_version - - if sys.version_info < (3, 8): - import pkg_resources + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) - 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: + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple 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" @@ -96,38 +143,6 @@ def _get_version(dependency_name): "using a supported version of Python; see " + "https://devguide.python.org/versions/") - -from .services.cloud_redis import CloudRedisClient -from .services.cloud_redis import CloudRedisAsyncClient - -from .types.cloud_redis import CreateInstanceRequest -from .types.cloud_redis import DeleteInstanceRequest -from .types.cloud_redis import ExportInstanceRequest -from .types.cloud_redis import FailoverInstanceRequest -from .types.cloud_redis import GcsDestination -from .types.cloud_redis import GcsSource -from .types.cloud_redis import GetInstanceAuthStringRequest -from .types.cloud_redis import GetInstanceRequest -from .types.cloud_redis import ImportInstanceRequest -from .types.cloud_redis import InputConfig -from .types.cloud_redis import Instance -from .types.cloud_redis import InstanceAuthString -from .types.cloud_redis import ListInstancesRequest -from .types.cloud_redis import ListInstancesResponse -from .types.cloud_redis import LocationMetadata -from .types.cloud_redis import MaintenancePolicy -from .types.cloud_redis import MaintenanceSchedule -from .types.cloud_redis import NodeInfo -from .types.cloud_redis import OperationMetadata -from .types.cloud_redis import OutputConfig -from .types.cloud_redis import PersistenceConfig -from .types.cloud_redis import RescheduleMaintenanceRequest -from .types.cloud_redis import TlsCertificate -from .types.cloud_redis import UpdateInstanceRequest -from .types.cloud_redis import UpgradeInstanceRequest -from .types.cloud_redis import WeeklyMaintenanceWindow -from .types.cloud_redis import ZoneMetadata - __all__ = ( 'CloudRedisAsyncClient', 'CloudRedisClient', diff --git a/tests/integration/goldens/redis/setup.py b/tests/integration/goldens/redis/setup.py index cf35d014a4..026674b2d3 100755 --- a/tests/integration/goldens/redis/setup.py +++ b/tests/integration/goldens/redis/setup.py @@ -45,7 +45,6 @@ "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/google/cloud/redis_v1/__init__.py b/tests/integration/goldens/redis_selective/google/cloud/redis_v1/__init__.py index b781ff92cd..1f7bad3796 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 @@ -15,10 +15,36 @@ # from google.cloud.redis_v1 import gapic_version as package_version +import google.api_core as api_core +import sys + __version__ = package_version.__version__ +if sys.version_info >= (3, 8): # pragma: NO COVER + from importlib import metadata +else: # pragma: NO COVER + # TODO(https://github.com/googleapis/python-api-core/issues/835): Remove + # this code path once we drop support for Python 3.7 + import importlib_metadata as metadata -import google.api_core as api_core + +from .services.cloud_redis import CloudRedisClient +from .services.cloud_redis import CloudRedisAsyncClient + +from .types.cloud_redis import CreateInstanceRequest +from .types.cloud_redis import DeleteInstanceRequest +from .types.cloud_redis import GetInstanceRequest +from .types.cloud_redis import Instance +from .types.cloud_redis import ListInstancesRequest +from .types.cloud_redis import ListInstancesResponse +from .types.cloud_redis import MaintenancePolicy +from .types.cloud_redis import MaintenanceSchedule +from .types.cloud_redis import NodeInfo +from .types.cloud_redis import OperationMetadata +from .types.cloud_redis import PersistenceConfig +from .types.cloud_redis import TlsCertificate +from .types.cloud_redis import UpdateInstanceRequest +from .types.cloud_redis import WeeklyMaintenanceWindow 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 @@ -48,27 +74,35 @@ f"then update {_package_label}.", FutureWarning) - from packaging.version import parse as parse_version - - if sys.version_info < (3, 8): - import pkg_resources + def parse_version_to_tuple(version_string: str): + """Safely converts a semantic version string to a comparable tuple of integers. + Example: "4.25.8" -> (4, 25, 8) + Ignores non-numeric parts and handles common version formats. + Args: + version_string: Version string in the format "x.y.z" or "x.y.z" + Returns: + Tuple of integers for the parsed version string. + """ + parts = [] + for part in version_string.split("."): + try: + parts.append(int(part)) + except ValueError: + # If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here. + # This is a simplification compared to 'packaging.parse_version', but sufficient + # for comparing strictly numeric semantic versions. + break + return tuple(parts) - 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: + def _get_version(dependency_name): + try: + version_string: str = metadata.version(dependency_name) + parsed_version = parse_version_to_tuple(version_string) + return (parsed_version, version_string) + except Exception: + # Catch exceptions from metadata.version() (e.g., PackageNotFoundError) + # or errors during parse_version_to_tuple 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" @@ -96,25 +130,6 @@ def _get_version(dependency_name): "using a supported version of Python; see " + "https://devguide.python.org/versions/") - -from .services.cloud_redis import CloudRedisClient -from .services.cloud_redis import CloudRedisAsyncClient - -from .types.cloud_redis import CreateInstanceRequest -from .types.cloud_redis import DeleteInstanceRequest -from .types.cloud_redis import GetInstanceRequest -from .types.cloud_redis import Instance -from .types.cloud_redis import ListInstancesRequest -from .types.cloud_redis import ListInstancesResponse -from .types.cloud_redis import MaintenancePolicy -from .types.cloud_redis import MaintenanceSchedule -from .types.cloud_redis import NodeInfo -from .types.cloud_redis import OperationMetadata -from .types.cloud_redis import PersistenceConfig -from .types.cloud_redis import TlsCertificate -from .types.cloud_redis import UpdateInstanceRequest -from .types.cloud_redis import WeeklyMaintenanceWindow - __all__ = ( 'CloudRedisAsyncClient', 'CloudRedisClient', diff --git a/tests/integration/goldens/redis_selective/setup.py b/tests/integration/goldens/redis_selective/setup.py index cf35d014a4..026674b2d3 100755 --- a/tests/integration/goldens/redis_selective/setup.py +++ b/tests/integration/goldens/redis_selective/setup.py @@ -45,7 +45,6 @@ "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",