Skip to content

Commit 6698861

Browse files
authored
fix(db-dtypes): Drop support for Python <= 3.9 (#16966)
This PR updates \`db-dtypes\` to establish Python 3.10 as the minimum supported version, dropping support for Python 3.7, 3.8, and 3.9. ### Changes * Configuration: Updated setup.py metadata and python_requires to >=3.10. * Nox: Updated noxfile.py sessions and deleted constraints-3.9.txt. * Documentation: Updated README.rst and CONTRIBUTING.rst (and synced to docs/README.rst!). * Removed extract_runtime_version and its helper file from db_dtypes * Updated the tests to mock sys.version_info correctly. Fixes internal issue: http://b/482126936 🦕
1 parent 8fa321e commit 6698861

10 files changed

Lines changed: 40 additions & 81 deletions

File tree

packages/db-dtypes/CONTRIBUTING.rst

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ In order to add a feature:
2222
documentation.
2323

2424
- The feature must work fully on the following CPython versions:
25-
3.9, 3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows.
25+
3.10, 3.11, 3.12, 3.13 and 3.14 on both UNIX and Windows.
2626

2727
- The feature must not add unnecessary dependencies (where
2828
"unnecessary" is of course subjective, but new dependencies should
@@ -143,13 +143,12 @@ Running System Tests
143143
$ nox -s system
144144

145145
# Run a single system test
146-
$ nox -s system-3.9 -- -k <name of test>
146+
$ nox -s system-3.12 -- -k <name of test>
147147

148148

149149
.. note::
150150

151-
System tests are only configured to run under Python 3.9.
152-
For expediency, we do not run them in older versions of Python 3.
151+
System tests are only configured to run under Python 3.12.
153152

154153
This alone will not run the tests. You'll need to change some local
155154
auth settings and change some configuration in your project to
@@ -198,14 +197,12 @@ Supported Python Versions
198197

199198
We support:
200199

201-
- `Python 3.9`_
202200
- `Python 3.10`_
203201
- `Python 3.11`_
204202
- `Python 3.12`_
205203
- `Python 3.13`_
206204
- `Python 3.14`_
207205

208-
.. _Python 3.9: https://docs.python.org/3.9/
209206
.. _Python 3.10: https://docs.python.org/3.10/
210207
.. _Python 3.11: https://docs.python.org/3.11/
211208
.. _Python 3.12: https://docs.python.org/3.12/
@@ -218,17 +215,7 @@ Supported versions can be found in our ``noxfile.py`` `config`_.
218215
.. _config: https://github.com/googleapis/google-cloud-python/blob/main/packages/db-dtypes/noxfile.py
219216

220217

221-
We also explicitly decided to support Python 3 beginning with version 3.9.
222-
Reasons for this include:
223218

224-
- Encouraging use of newest versions of Python 3
225-
- Taking the lead of `prominent`_ open-source `projects`_
226-
- `Unicode literal support`_ which allows for a cleaner codebase that
227-
works in both Python 2 and Python 3
228-
229-
.. _prominent: https://docs.djangoproject.com/en/1.9/faq/install/#what-python-version-can-i-use-with-django
230-
.. _projects: http://flask.pocoo.org/docs/0.10/python3/
231-
.. _Unicode literal support: https://www.python.org/dev/peps/pep-0414/
232219

233220
**********
234221
Versioning

packages/db-dtypes/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ dependencies.
3434

3535
Supported Python Versions
3636
^^^^^^^^^^^^^^^^^^^^^^^^^
37-
Python >= 3.9
37+
Python >= 3.10
3838

3939
Unsupported Python Versions
4040
^^^^^^^^^^^^^^^^^^^^^^^^^^^
41-
Python <= 3.8.
41+
Python <= 3.9
4242

4343

4444
Mac/Linux

packages/db-dtypes/db_dtypes/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
from db_dtypes import core
3131
from db_dtypes.json import JSONArray, JSONArrowType, JSONDtype # noqa: F401
3232

33-
from . import _versions_helpers
3433

3534
date_dtype_name = "dbdate"
3635
time_dtype_name = "dbtime"
@@ -341,12 +340,13 @@ def __sub__(self, other):
341340

342341
def _check_python_version():
343342
"""Checks the runtime Python version and issues a warning if needed."""
344-
sys_major, sys_minor, sys_micro = _versions_helpers.extract_runtime_version()
345-
if sys_major == 3 and sys_minor in (7, 8):
343+
import sys
344+
345+
if sys.version_info < (3, 10):
346346
warnings.warn(
347347
"The python-bigquery library as well as the python-db-dtypes-pandas library no "
348-
"longer supports Python 3.7 and Python 3.8. "
349-
f"Your Python version is {sys_major}.{sys_minor}.{sys_micro}. We "
348+
"longer supports Python 3.7, 3.8, and 3.9. "
349+
f"Your Python version is {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}. We "
350350
"recommend that you update soon to ensure ongoing support. For "
351351
"more details, see: [Google Cloud Client Libraries Supported Python Versions policy](https://cloud.google.com/python/docs/supported-python-versions)",
352352
FutureWarning,

packages/db-dtypes/db_dtypes/_versions_helpers.py

Lines changed: 0 additions & 32 deletions
This file was deleted.

packages/db-dtypes/docs/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ dependencies.
3434

3535
Supported Python Versions
3636
^^^^^^^^^^^^^^^^^^^^^^^^^
37-
Python >= 3.9
37+
Python >= 3.10
3838

3939
Unsupported Python Versions
4040
^^^^^^^^^^^^^^^^^^^^^^^^^^^
41-
Python <= 3.8.
41+
Python <= 3.9
4242

4343

4444
Mac/Linux

packages/db-dtypes/noxfile.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
LINT_PYTHON_VERSION = "3.10"
3838

3939
UNIT_TEST_PYTHON_VERSIONS: List[str] = [
40-
"3.9",
4140
"3.10",
4241
"3.11",
4342
"3.12",
@@ -58,7 +57,7 @@
5857
UNIT_TEST_EXTRAS: List[str] = []
5958
UNIT_TEST_EXTRAS_BY_PYTHON: Dict[str, List[str]] = {}
6059

61-
SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.9"]
60+
SYSTEM_TEST_PYTHON_VERSIONS: List[str] = ["3.12"]
6261
SYSTEM_TEST_STANDARD_DEPENDENCIES: List[str] = [
6362
"mock",
6463
"pytest",

packages/db-dtypes/setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ def readme():
6464
"License :: OSI Approved :: Apache Software License",
6565
"Programming Language :: Python",
6666
"Programming Language :: Python :: 3",
67-
"Programming Language :: Python :: 3.9",
6867
"Programming Language :: Python :: 3.10",
6968
"Programming Language :: Python :: 3.11",
7069
"Programming Language :: Python :: 3.12",
@@ -75,6 +74,6 @@ def readme():
7574
],
7675
platforms="Posix; MacOS X; Windows",
7776
install_requires=dependencies,
78-
python_requires=">=3.9",
77+
python_requires=">=3.10",
7978
tests_require=["pytest"],
8079
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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+
numpy==1.24.0
8+
packaging==24.2.0
9+
pandas==1.5.3
10+
pyarrow==13.0.0

packages/db-dtypes/testing/constraints-3.9.txt

Lines changed: 0 additions & 11 deletions
This file was deleted.

packages/db-dtypes/tests/unit/test__init__.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from collections import namedtuple
1516
from unittest import mock
1617

1718
import pytest
1819

1920
# Module paths used for mocking
2021
MODULE_PATH = "db_dtypes"
21-
HELPER_MODULE_PATH = f"{MODULE_PATH}._versions_helpers"
22-
MOCK_EXTRACT_VERSION = f"{HELPER_MODULE_PATH}.extract_runtime_version"
2322
MOCK_WARN = "warnings.warn" # Target the standard warnings module
2423

24+
VersionInfo = namedtuple("VersionInfo", ["major", "minor", "micro"])
25+
2526

2627
@pytest.mark.parametrize(
2728
"mock_version_tuple, version_str",
@@ -30,17 +31,20 @@
3031
((3, 7, 0), "3.7.0"),
3132
((3, 8, 5), "3.8.5"),
3233
((3, 8, 12), "3.8.12"),
34+
((3, 9, 5), "3.9.5"),
3335
],
3436
)
3537
def test_check_python_version_warns_on_unsupported(mock_version_tuple, version_str):
3638
"""
37-
Test that _check_python_version issues a FutureWarning for Python 3.7/3.8.
39+
Test that _check_python_version issues a FutureWarning for Python 3.7/3.8/3.9.
3840
"""
3941

4042
from db_dtypes import _check_python_version
4143

42-
# Mock the helper function it calls and the warnings.warn function
43-
with mock.patch(MOCK_EXTRACT_VERSION, return_value=mock_version_tuple), mock.patch(
44+
mock_version = VersionInfo(*mock_version_tuple)
45+
46+
# Mock sys.version_info and warnings.warn
47+
with mock.patch("sys.version_info", new=mock_version), mock.patch(
4448
MOCK_WARN
4549
) as mock_warn_call:
4650
_check_python_version() # Call the function
@@ -55,17 +59,18 @@ def test_check_python_version_warns_on_unsupported(mock_version_tuple, version_s
5559
warning_category = args[1] if len(args) > 1 else kwargs.get("category")
5660

5761
# Verify message content and category
58-
assert "longer supports Python 3.7 and Python 3.8" in warning_message
62+
assert "longer supports Python 3.7, 3.8, and 3.9" in warning_message
5963
assert warning_category == FutureWarning
6064

6165

6266
@pytest.mark.parametrize(
6367
"mock_version_tuple",
6468
[
65-
(3, 9, 1),
6669
(3, 10, 0),
6770
(3, 11, 2),
6871
(3, 12, 0),
72+
(3, 13, 0),
73+
(3, 14, 0),
6974
],
7075
)
7176
def test_check_python_version_does_not_warn_on_supported(mock_version_tuple):
@@ -75,8 +80,10 @@ def test_check_python_version_does_not_warn_on_supported(mock_version_tuple):
7580

7681
from db_dtypes import _check_python_version
7782

78-
# Mock the helper function it calls and the warnings.warn function
79-
with mock.patch(MOCK_EXTRACT_VERSION, return_value=mock_version_tuple), mock.patch(
83+
mock_version = VersionInfo(*mock_version_tuple)
84+
85+
# Mock sys.version_info and warnings.warn
86+
with mock.patch("sys.version_info", new=mock_version), mock.patch(
8087
MOCK_WARN
8188
) as mock_warn_call:
8289
_check_python_version()

0 commit comments

Comments
 (0)