Skip to content

Commit 4d49aa0

Browse files
committed
feat: add deprecation check for the protobuf package
1 parent 133a1e0 commit 4d49aa0

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

google/api_core/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,14 @@
1717
This package contains common code and utilities used by Google client libraries.
1818
"""
1919

20+
from google.api_core import _python_package_support
2021
from google.api_core import _python_version_support
2122
from google.api_core import version as api_core_version
2223

2324
__version__ = api_core_version.__version__
25+
2426
check_python_version = _python_version_support.check_python_version
2527
check_python_version(package="package google-api-core (google.api_core)")
28+
29+
check_dependency_versions = _python_package_support.check_dependency_versions
30+
check_dependency_versions("google-api-core (google.api_core)")
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Code to check versions of dependencies used by Google Cloud Client Libraries."""
16+
17+
import logging
18+
import sys
19+
from typing import Optional
20+
from ._python_version_support import _flatten_message
21+
22+
# It is a good practice to alias the Version class for clarity in type hints.
23+
from packaging.version import parse as parse_version, Version as PackagingVersion
24+
25+
26+
def get_dependency_version(dependency_name: str) -> Optional[PackagingVersion]:
27+
"""Get the parsed version of an installed package dependency.
28+
29+
This function checks for an installed package and returns its version
30+
as a `packaging.version.Version` object for safe comparison. It handles
31+
both modern (Python 3.8+) and legacy (Python 3.7) environments.
32+
33+
Args:
34+
dependency_name: The distribution name of the package (e.g., 'requests').
35+
36+
Returns:
37+
A `packaging.version.Version` object, or `None` if the package
38+
is not found or another error occurs during version discovery.
39+
"""
40+
try:
41+
if sys.version_info >= (3, 8):
42+
from importlib import metadata
43+
version_string = metadata.version(dependency_name)
44+
return parse_version(version_string)
45+
46+
# TODO: Remove this code path once we drop support for Python 3.7
47+
else:
48+
# Use pkg_resources, which is part of setuptools.
49+
import pkg_resources
50+
version_string = pkg_resources.get_distribution(dependency_name).version
51+
return parse_version(version_string)
52+
53+
except:
54+
return None
55+
56+
57+
def warn_deprecation_for_versions_less_than(dependent_package:str,
58+
dependency_name:str,
59+
next_supported_version:str,
60+
message_template: Optional[str] = None):
61+
if not dependent_package or not dependency_name or not next_supported_version:
62+
return
63+
version_used = get_dependency_version(dependency_name)
64+
if not version_used:
65+
return
66+
if version_used < parse_version(next_supported_version):
67+
message_template = message_template or _flatten_message(
68+
"""DEPRECATION: Package {dependent_package} depends on
69+
{dependency_name}, currently installed at version
70+
{version_used.__str__}. Future updates to
71+
{dependent_package} will require {dependency_name} at
72+
version {next_supported_version} or higher. Please ensure
73+
that either (a) your Python environment doesn't pin the
74+
version of {dependency_name}, so that updates to
75+
{dependent_package} can require the higher version, or (b)
76+
you manually update your Python environment to use at
77+
least version {next_supported_version} of
78+
{dependency_name}."""
79+
)
80+
logging.warning(
81+
message_template.format(
82+
dependent_package=dependent_package,
83+
dependency_name=dependency_name,
84+
next_supported_version=next_supported_version,
85+
version_used=version_used,
86+
))
87+
88+
def check_dependency_versions(dependent_package: str):
89+
warn_deprecation_for_versions_less_than(dependent_package, "protobuf (google.protobuf)", "4.25.8")

0 commit comments

Comments
 (0)