Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cddabc0

Browse filesBrowse files
authored
feat(spanner): drop python runtime 3.9 (#17070)
## Description This Pull Request drops support for Python 3.9 in the `google-cloud-spanner` package. This is part of our ongoing effort to modernize the Cloud SDK libraries and remove support for End-of-Life (EOL) Python versions. ## Changes - Removed Python 3.9 from testing configurations and constraints files. - Resolved dependency conflicts arising from dropping support. - Cleaned up obsolete code related to Python 3.9 support.
1 parent 0d39c95 commit cddabc0
Copy full SHA for cddabc0

13 files changed

+66-284Lines changed: 66 additions & 284 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎packages/google-cloud-spanner/README.rst‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/README.rst
+2-2Lines changed: 2 additions & 2 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ Supported Python Versions
6262
Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of
6363
Python.
6464

65-
Python >= 3.9, including 3.14
65+
Python >= 3.10, including 3.14
6666

6767
.. _active: https://devguide.python.org/devcycle/#in-development-main-branch
6868
.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches
6969

7070
Unsupported Python Versions
7171
^^^^^^^^^^^^^^^^^^^^^^^^^^^
72-
Python <= 3.8
72+
Python <= 3.9
7373

7474
If you are using an `end-of-life`_
7575
version of Python, we recommend that you update as soon as possible to an actively supported version.
Collapse file

‎packages/google-cloud-spanner/docs/README.rst‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/docs/README.rst
+2-2Lines changed: 2 additions & 2 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ Supported Python Versions
6262
Our client libraries are compatible with all current `active`_ and `maintenance`_ versions of
6363
Python.
6464

65-
Python >= 3.9, including 3.14
65+
Python >= 3.10, including 3.14
6666

6767
.. _active: https://devguide.python.org/devcycle/#in-development-main-branch
6868
.. _maintenance: https://devguide.python.org/devcycle/#maintenance-branches
6969

7070
Unsupported Python Versions
7171
^^^^^^^^^^^^^^^^^^^^^^^^^^^
72-
Python <= 3.8
72+
Python <= 3.9
7373

7474
If you are using an `end-of-life`_
7575
version of Python, we recommend that you update as soon as possible to an actively supported version.
Collapse file

‎packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/__init__.py‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/google/cloud/spanner_admin_database_v1/__init__.py
+10-91Lines changed: 10 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,6 @@
2121

2222
__version__ = package_version.__version__
2323

24-
if sys.version_info >= (3, 8): # pragma: NO COVER
25-
from importlib import metadata
26-
else: # pragma: NO COVER
27-
# TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
28-
# this code path once we drop support for Python 3.7
29-
import importlib_metadata as metadata
30-
3124

3225
from .services.database_admin import DatabaseAdminAsyncClient, DatabaseAdminClient
3326
from .types.backup import (
@@ -106,92 +99,18 @@
10699
api_core.check_python_version("google.cloud.spanner_admin_database_v1") # type: ignore
107100
api_core.check_dependency_versions("google.cloud.spanner_admin_database_v1") # type: ignore
108101
else: # pragma: NO COVER
109-
# An older version of api_core is installed which does not define the
110-
# functions above. We do equivalent checks manually.
111-
try:
112-
import sys
113-
import warnings
114-
115-
_py_version_str = sys.version.split()[0]
116-
_package_label = "google.cloud.spanner_admin_database_v1"
117-
if sys.version_info < (3, 9):
118-
warnings.warn(
119-
"You are using a non-supported Python version "
120-
+ f"({_py_version_str}). Google will not post any further "
121-
+ f"updates to {_package_label} supporting this Python version. "
122-
+ "Please upgrade to the latest Python version, or at "
123-
+ f"least to Python 3.9, and then update {_package_label}.",
124-
FutureWarning,
125-
)
126-
if sys.version_info[:2] == (3, 9):
127-
warnings.warn(
128-
f"You are using a Python version ({_py_version_str}) "
129-
+ f"which Google will stop supporting in {_package_label} in "
130-
+ "January 2026. Please "
131-
+ "upgrade to the latest Python version, or at "
132-
+ "least to Python 3.10, before then, and "
133-
+ f"then update {_package_label}.",
134-
FutureWarning,
135-
)
136-
137-
def parse_version_to_tuple(version_string: str):
138-
"""Safely converts a semantic version string to a comparable tuple of integers.
139-
Example: "4.25.8" -> (4, 25, 8)
140-
Ignores non-numeric parts and handles common version formats.
141-
Args:
142-
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
143-
Returns:
144-
Tuple of integers for the parsed version string.
145-
"""
146-
parts = []
147-
for part in version_string.split("."):
148-
try:
149-
parts.append(int(part))
150-
except ValueError:
151-
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
152-
# This is a simplification compared to 'packaging.parse_version', but sufficient
153-
# for comparing strictly numeric semantic versions.
154-
break
155-
return tuple(parts)
156-
157-
def _get_version(dependency_name):
158-
try:
159-
version_string: str = metadata.version(dependency_name)
160-
parsed_version = parse_version_to_tuple(version_string)
161-
return (parsed_version, version_string)
162-
except Exception:
163-
# Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
164-
# or errors during parse_version_to_tuple
165-
return (None, "--")
102+
import warnings
166103

167-
_dependency_package = "google.protobuf"
168-
_next_supported_version = "4.25.8"
169-
_next_supported_version_tuple = (4, 25, 8)
170-
_recommendation = " (we recommend 6.x)"
171-
(_version_used, _version_used_string) = _get_version(_dependency_package)
172-
if _version_used and _version_used < _next_supported_version_tuple:
173-
warnings.warn(
174-
f"Package {_package_label} depends on "
175-
+ f"{_dependency_package}, currently installed at version "
176-
+ f"{_version_used_string}. Future updates to "
177-
+ f"{_package_label} will require {_dependency_package} at "
178-
+ f"version {_next_supported_version} or higher{_recommendation}."
179-
+ " Please ensure "
180-
+ "that either (a) your Python environment doesn't pin the "
181-
+ f"version of {_dependency_package}, so that updates to "
182-
+ f"{_package_label} can require the higher version, or "
183-
+ "(b) you manually update your Python environment to use at "
184-
+ f"least version {_next_supported_version} of "
185-
+ f"{_dependency_package}.",
186-
FutureWarning,
187-
)
188-
except Exception:
104+
_py_version_str = sys.version.split()[0]
105+
# version-scanner: ignore-next-line
106+
if sys.version_info < (3, 10):
189107
warnings.warn(
190-
"Could not determine the version of Python "
191-
+ "currently being used. To continue receiving "
192-
+ "updates for {_package_label}, ensure you are "
193-
+ "using a supported version of Python; see "
194-
+ "https://devguide.python.org/versions/"
108+
"You are using a non-supported Python version "
109+
+ f"({_py_version_str}). Google will not post any further "
110+
+ "updates to google.cloud.spanner_admin_database_v1 supporting this Python version. "
111+
+ "Please upgrade to the latest Python version, or at "
112+
+ "least to Python 3.10, and then update google.cloud.spanner_admin_database_v1.",
113+
FutureWarning,
195114
)
196115

197116
__all__ = (
Collapse file

‎packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/__init__.py‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/google/cloud/spanner_admin_instance_v1/__init__.py
+10-91Lines changed: 10 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,6 @@
2121

2222
__version__ = package_version.__version__
2323

24-
if sys.version_info >= (3, 8): # pragma: NO COVER
25-
from importlib import metadata
26-
else: # pragma: NO COVER
27-
# TODO(https://github.com/googleapis/python-api-core/issues/835): Remove
28-
# this code path once we drop support for Python 3.7
29-
import importlib_metadata as metadata
30-
3124

3225
from .services.instance_admin import InstanceAdminAsyncClient, InstanceAdminClient
3326
from .types.common import FulfillmentPeriod, OperationProgress, ReplicaSelection
@@ -78,92 +71,18 @@
7871
api_core.check_python_version("google.cloud.spanner_admin_instance_v1") # type: ignore
7972
api_core.check_dependency_versions("google.cloud.spanner_admin_instance_v1") # type: ignore
8073
else: # pragma: NO COVER
81-
# An older version of api_core is installed which does not define the
82-
# functions above. We do equivalent checks manually.
83-
try:
84-
import sys
85-
import warnings
86-
87-
_py_version_str = sys.version.split()[0]
88-
_package_label = "google.cloud.spanner_admin_instance_v1"
89-
if sys.version_info < (3, 9):
90-
warnings.warn(
91-
"You are using a non-supported Python version "
92-
+ f"({_py_version_str}). Google will not post any further "
93-
+ f"updates to {_package_label} supporting this Python version. "
94-
+ "Please upgrade to the latest Python version, or at "
95-
+ f"least to Python 3.9, and then update {_package_label}.",
96-
FutureWarning,
97-
)
98-
if sys.version_info[:2] == (3, 9):
99-
warnings.warn(
100-
f"You are using a Python version ({_py_version_str}) "
101-
+ f"which Google will stop supporting in {_package_label} in "
102-
+ "January 2026. Please "
103-
+ "upgrade to the latest Python version, or at "
104-
+ "least to Python 3.10, before then, and "
105-
+ f"then update {_package_label}.",
106-
FutureWarning,
107-
)
108-
109-
def parse_version_to_tuple(version_string: str):
110-
"""Safely converts a semantic version string to a comparable tuple of integers.
111-
Example: "4.25.8" -> (4, 25, 8)
112-
Ignores non-numeric parts and handles common version formats.
113-
Args:
114-
version_string: Version string in the format "x.y.z" or "x.y.z<suffix>"
115-
Returns:
116-
Tuple of integers for the parsed version string.
117-
"""
118-
parts = []
119-
for part in version_string.split("."):
120-
try:
121-
parts.append(int(part))
122-
except ValueError:
123-
# If it's a non-numeric part (e.g., '1.0.0b1' -> 'b1'), stop here.
124-
# This is a simplification compared to 'packaging.parse_version', but sufficient
125-
# for comparing strictly numeric semantic versions.
126-
break
127-
return tuple(parts)
128-
129-
def _get_version(dependency_name):
130-
try:
131-
version_string: str = metadata.version(dependency_name)
132-
parsed_version = parse_version_to_tuple(version_string)
133-
return (parsed_version, version_string)
134-
except Exception:
135-
# Catch exceptions from metadata.version() (e.g., PackageNotFoundError)
136-
# or errors during parse_version_to_tuple
137-
return (None, "--")
74+
import warnings
13875

139-
_dependency_package = "google.protobuf"
140-
_next_supported_version = "4.25.8"
141-
_next_supported_version_tuple = (4, 25, 8)
142-
_recommendation = " (we recommend 6.x)"
143-
(_version_used, _version_used_string) = _get_version(_dependency_package)
144-
if _version_used and _version_used < _next_supported_version_tuple:
145-
warnings.warn(
146-
f"Package {_package_label} depends on "
147-
+ f"{_dependency_package}, currently installed at version "
148-
+ f"{_version_used_string}. Future updates to "
149-
+ f"{_package_label} will require {_dependency_package} at "
150-
+ f"version {_next_supported_version} or higher{_recommendation}."
151-
+ " Please ensure "
152-
+ "that either (a) your Python environment doesn't pin the "
153-
+ f"version of {_dependency_package}, so that updates to "
154-
+ f"{_package_label} can require the higher version, or "
155-
+ "(b) you manually update your Python environment to use at "
156-
+ f"least version {_next_supported_version} of "
157-
+ f"{_dependency_package}.",
158-
FutureWarning,
159-
)
160-
except Exception:
76+
_py_version_str = sys.version.split()[0]
77+
# version-scanner: ignore-next-line
78+
if sys.version_info < (3, 10):
16179
warnings.warn(
162-
"Could not determine the version of Python "
163-
+ "currently being used. To continue receiving "
164-
+ "updates for {_package_label}, ensure you are "
165-
+ "using a supported version of Python; see "
166-
+ "https://devguide.python.org/versions/"
80+
"You are using a non-supported Python version "
81+
+ f"({_py_version_str}). Google will not post any further "
82+
+ "updates to google.cloud.spanner_admin_instance_v1 supporting this Python version. "
83+
+ "Please upgrade to the latest Python version, or at "
84+
+ "least to Python 3.10, and then update google.cloud.spanner_admin_instance_v1.",
85+
FutureWarning,
16786
)
16887

16988
__all__ = (
Collapse file

‎packages/google-cloud-spanner/google/cloud/spanner_v1/_opentelemetry_tracing.py‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/google/cloud/spanner_v1/_opentelemetry_tracing.py
+3-6Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@
1919
from datetime import datetime
2020

2121
from opentelemetry import trace
22-
from opentelemetry.semconv.attributes.otel_attributes import (
23-
OTEL_SCOPE_NAME,
24-
OTEL_SCOPE_VERSION,
25-
)
22+
2623
from opentelemetry.trace.status import Status, StatusCode
2724

2825
from google.cloud.spanner_v1._helpers import (
@@ -99,9 +96,9 @@ def trace_call(
9996
"db.url": SpannerClient.DEFAULT_ENDPOINT,
10097
"db.instance": db_name,
10198
"net.host.name": SpannerClient.DEFAULT_ENDPOINT,
102-
OTEL_SCOPE_NAME: TRACER_NAME,
99+
"otel.scope.name": TRACER_NAME,
103100
"cloud.region": cloud_region,
104-
OTEL_SCOPE_VERSION: TRACER_VERSION,
101+
"otel.scope.version": TRACER_VERSION,
105102
# Standard GCP attributes for OTel, attributes are used for internal purpose and are subjected to change
106103
"gcp.client.service": "spanner",
107104
"gcp.client.version": TRACER_VERSION,
Collapse file

‎packages/google-cloud-spanner/noxfile.py‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/noxfile.py
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.12"]
3232

3333
ALL_PYTHON: List[str] = [
34-
"3.9",
3534
"3.10",
3635
"3.11",
3736
"3.12",
Collapse file

‎packages/google-cloud-spanner/setup.py‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/setup.py
+4-6Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,11 @@
3939
release_status = "Development Status :: 5 - Production/Stable"
4040

4141
dependencies = [
42-
"google-api-core[grpc] >= 1.34.0, <3.0.0,!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,!=2.10.*",
43-
"google-cloud-core >= 1.4.4, < 3.0.0",
42+
"google-api-core[grpc] >= 2.19.0, <3.0.0",
43+
"google-cloud-core >= 2.0.0, < 3.0.0",
4444
"grpc-google-iam-v1 >= 0.12.4, <1.0.0",
45-
"proto-plus >= 1.22.0, <2.0.0",
45+
"proto-plus >= 1.22.3, <2.0.0",
4646
"sqlparse >= 0.4.4",
47-
"proto-plus >= 1.22.2, <2.0.0; python_version>='3.11'",
4847
"protobuf >= 4.25.8, < 8.0.0",
4948
"grpc-interceptor >= 0.15.4",
5049
# Make OpenTelemetry a core dependency
@@ -86,7 +85,6 @@
8685
"License :: OSI Approved :: Apache Software License",
8786
"Programming Language :: Python",
8887
"Programming Language :: Python :: 3",
89-
"Programming Language :: Python :: 3.9",
9088
"Programming Language :: Python :: 3.10",
9189
"Programming Language :: Python :: 3.11",
9290
"Programming Language :: Python :: 3.12",
@@ -97,7 +95,7 @@
9795
],
9896
platforms="Posix; MacOS X; Windows",
9997
packages=packages,
100-
python_requires=">=3.9",
98+
python_requires=">=3.10",
10199
install_requires=dependencies,
102100
extras_require=extras,
103101
include_package_data=True,
Collapse file
+20-10Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
1-
# -*- coding: utf-8 -*-
2-
# This constraints file is required for unit tests.
3-
# List all library dependencies and extras in this file.
4-
google-api-core
5-
google-auth
6-
grpcio
7-
proto-plus
8-
protobuf
9-
# cryptography is a direct dependency of google-auth
10-
cryptography
1+
# This constraints file is used to check that lower bounds
2+
# are correct in setup.py
3+
# List all library dependencies and extras in this file,
4+
# pinning their versions to their lower bounds.
5+
# For example, if setup.py has "google-cloud-foo >= 1.14.0, < 2.0.0",
6+
# then this file should have google-cloud-foo==1.14.0
7+
google-api-core==2.19.0
8+
google-cloud-core==2.0.0
9+
grpc-google-iam-v1==0.12.4
10+
proto-plus==1.22.3
11+
sqlparse==0.4.4
12+
protobuf==4.25.8
13+
grpc-interceptor==0.15.4
14+
opentelemetry-api==1.22.0
15+
opentelemetry-sdk==1.22.0
16+
opentelemetry-semantic-conventions==0.43b0
17+
opentelemetry-resourcedetector-gcp==1.8.0a0
18+
google-cloud-monitoring==2.16.0
19+
mmh3==4.1.0
20+
libcst==0.2.5
Collapse file

‎packages/google-cloud-spanner/testing/constraints-3.9.txt‎

Copy file name to clipboardExpand all lines: packages/google-cloud-spanner/testing/constraints-3.9.txt
-13Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.