Skip to content

Commit afc3b2c

Browse files
authored
chore(python): Add support for Python 3.14 (#804)
This PR adds support for Python 3.14 to the library. Key changes include: - Updating `setup.py` to include the Python 3.14 classifier. - Updating `noxfile.py`: - Add 3.14 to test sessions. - Refactor to use version constants (`UNIT_TEST_PYTHON_VERSIONS`, `SYSTEM_TEST_PYTHON_VERSIONS`). - Update `DEFAULT_PYTHON_VERSION` and `DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20` to "3.14". - Update `BLACK_VERSION` to `23.7.0` for Python 3.14 compatibility. - Updating `.github/workflows/test_suite.yml` to use appropriate Python versions for each job including matrix strategies for `unit` and `system` jobs. NOTE: The following CI/CD check is failing: * `SQLAlchemy Spanner dialect / compliance_tests_20` Per Gemini: The `compliance_test_20` session in Nox is currently failing on Python 3.13 and 3.14 due to issues with schema reflection for elements with quoted names or mixed case. These appear to pre-existing issues with the dialect's handling of such identifiers, rather than a regressio introduced by Python 3.14. The failing compliance test has been marked as not required so as to not be a blocker for this PR. As noted in the issue that status should be reverted when the issue is resolved. Further details and investigation are tracked in Issue #805.
1 parent 601d3f6 commit afc3b2c

File tree

10 files changed

+42
-23
lines changed

10 files changed

+42
-23
lines changed

.github/workflows/test_suite.yml

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,28 @@ jobs:
1414
- name: Setup Python
1515
uses: actions/setup-python@v6
1616
with:
17-
python-version: 3.12
17+
python-version: 3.14
1818
- name: Install nox
1919
run: python -m pip install nox
2020
- name: Run Lint
2121
run: nox -s lint_setup_py lint blacken
2222

2323
unit:
2424
runs-on: ubuntu-latest
25-
25+
strategy:
26+
matrix:
27+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
2628
steps:
2729
- name: Checkout code
2830
uses: actions/checkout@v5
29-
- name: Setup Python
31+
- name: Setup Python ${{ matrix.python-version }}
3032
uses: actions/setup-python@v6
3133
with:
32-
python-version: 3.12
34+
python-version: ${{ matrix.python-version }}
3335
- name: Install nox
3436
run: python -m pip install nox
3537
- name: Run Unit Tests
36-
run: nox -s unit
38+
run: nox -s unit-${{ matrix.python-version }}
3739
env:
3840
SPANNER_EMULATOR_HOST: localhost:9010
3941
GOOGLE_CLOUD_PROJECT: appdev-soda-spanner-staging
@@ -47,7 +49,7 @@ jobs:
4749
- name: Setup Python
4850
uses: actions/setup-python@v6
4951
with:
50-
python-version: 3.12
52+
python-version: 3.14
5153
- name: Install nox
5254
run: python -m pip install nox
5355
- name: Run mockserver tests
@@ -62,7 +64,7 @@ jobs:
6264
- name: Setup Python
6365
uses: actions/setup-python@v6
6466
with:
65-
python-version: 3.12
67+
python-version: 3.14
6668
- name: Install nox
6769
run: python -m pip install nox
6870
- name: Run samples
@@ -84,7 +86,7 @@ jobs:
8486
- name: Setup Python
8587
uses: actions/setup-python@v6
8688
with:
87-
python-version: 3.12
89+
python-version: 3.9
8890
- name: Install nox
8991
run: python -m pip install nox
9092
- name: Run Compliance Tests
@@ -109,7 +111,7 @@ jobs:
109111
- name: Setup Python
110112
uses: actions/setup-python@v6
111113
with:
112-
python-version: 3.12
114+
python-version: 3.14
113115
- name: Install nox
114116
run: python -m pip install nox
115117
- name: Run Compliance Tests
@@ -120,7 +122,9 @@ jobs:
120122

121123
system:
122124
runs-on: ubuntu-latest
123-
125+
strategy:
126+
matrix:
127+
python-version: ["3.9", "3.14"]
124128
services:
125129
emulator-0:
126130
image: gcr.io/cloud-spanner-emulator/emulator:latest
@@ -130,14 +134,14 @@ jobs:
130134
steps:
131135
- name: Checkout code
132136
uses: actions/checkout@v5
133-
- name: Setup Python
137+
- name: Setup Python ${{ matrix.python-version }}
134138
uses: actions/setup-python@v6
135139
with:
136-
python-version: 3.12
140+
python-version: ${{ matrix.python-version }}
137141
- name: Install nox
138142
run: python -m pip install nox
139143
- name: Run System Tests
140-
run: nox -s system
144+
run: nox -s system-${{ matrix.python-version }}
141145
env:
142146
SPANNER_EMULATOR_HOST: localhost:9010
143147
GOOGLE_CLOUD_PROJECT: appdev-soda-spanner-staging
@@ -157,11 +161,11 @@ jobs:
157161
- name: Setup Python
158162
uses: actions/setup-python@v6
159163
with:
160-
python-version: 3.12
164+
python-version: 3.9
161165
- name: Install nox
162166
run: python -m pip install nox
163167
- name: Run Migration Tests
164168
run: nox -s migration_test
165169
env:
166170
SPANNER_EMULATOR_HOST: localhost:9010
167-
GOOGLE_CLOUD_PROJECT: appdev-soda-spanner-staging
171+
GOOGLE_CLOUD_PROJECT: appdev-soda-spanner-staging

noxfile.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,12 @@ class = StreamHandler
7575
"""
7676

7777

78-
BLACK_VERSION = "black==22.3.0"
78+
BLACK_VERSION = "black==23.7.0"
7979
BLACK_PATHS = ["google", "test", "noxfile.py", "setup.py", "samples"]
80-
DEFAULT_PYTHON_VERSION = "3.12"
81-
DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20 = "3.12"
80+
UNIT_TEST_PYTHON_VERSIONS = ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
81+
SYSTEM_TEST_PYTHON_VERSIONS = ["3.9", "3.14"]
82+
DEFAULT_PYTHON_VERSION = "3.14"
83+
DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20 = "3.14"
8284

8385

8486
@nox.session(python=DEFAULT_PYTHON_VERSION_FOR_SQLALCHEMY_20)
@@ -126,7 +128,7 @@ def lint_setup_py(session):
126128
session.run("python", "setup.py", "check", "--restructuredtext", "--strict")
127129

128130

129-
@nox.session(python=DEFAULT_PYTHON_VERSION)
131+
@nox.session(python=UNIT_TEST_PYTHON_VERSIONS[0])
130132
def compliance_test_14(session):
131133
"""Run SQLAlchemy dialect compliance test suite."""
132134

@@ -208,7 +210,7 @@ def compliance_test_20(session):
208210
)
209211

210212

211-
@nox.session()
213+
@nox.session(python=SYSTEM_TEST_PYTHON_VERSIONS)
212214
def system(session):
213215
"""Run SQLAlchemy dialect system test suite."""
214216

@@ -245,7 +247,7 @@ def system(session):
245247
session.run("python", "drop_test_database.py")
246248

247249

248-
@nox.session(python=DEFAULT_PYTHON_VERSION)
250+
@nox.session(python=UNIT_TEST_PYTHON_VERSIONS)
249251
def unit(session):
250252
"""Run unit tests."""
251253
# Run SQLAlchemy dialect compliance test suite with OpenTelemetry.
@@ -287,14 +289,14 @@ def mockserver(session):
287289
)
288290

289291

290-
@nox.session(python=DEFAULT_PYTHON_VERSION)
292+
@nox.session(python=UNIT_TEST_PYTHON_VERSIONS[0])
291293
def migration_test(session):
292294
"""Test migrations with SQLAlchemy v1.4 and Alembic"""
293295
session.run("pip", "install", "sqlalchemy>=1.4,<2.0", "--force-reinstall")
294296
_migration_test(session)
295297

296298

297-
@nox.session(python=DEFAULT_PYTHON_VERSION)
299+
@nox.session(python=UNIT_TEST_PYTHON_VERSIONS[-1])
298300
def _migration_test(session):
299301
"""Migrate with SQLAlchemy and Alembic and check the result."""
300302
import glob

samples/insert_data_sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from sample_helper import run_sample
2121
from model import Singer, Album, Track
2222

23+
2324
# Shows how to insert data using SQLAlchemy, including relationships that are
2425
# defined both as foreign keys and as interleaved tables.
2526
def insert_data():

samples/insert_or_ignore_sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from sample_helper import run_sample
2222
from model import Singer
2323

24+
2425
# Shows how to use insert-or-ignore using SQLAlchemy and Spanner.
2526
def insert_or_ignore_sample():
2627
engine = create_engine(

samples/insert_or_update_sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from sample_helper import run_sample
2222
from model import Singer
2323

24+
2425
# Shows how to use insert-or-update using SQLAlchemy and Spanner.
2526
def insert_or_update_sample():
2627
engine = create_engine(

samples/interleaved_table_sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from sample_helper import run_sample
2121
from model import Singer, Album, Track
2222

23+
2324
# Shows how INTERLEAVE IN PARENT can be used in SQLAlchemy.
2425
# INTERLEAVE IN PARENT can be modelled as if it were a normal relationship
2526
# in SQLAlchemy. SQLAlchemy can also generate the correct DDL for this.

samples/parse_json_sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from sample_helper import run_sample
1919
from model import Venue
2020

21+
2122
# Shows how to use the PARSE_JSON function in Spanner using SQLAlchemy.
2223
def parse_json_sample():
2324
engine = create_engine(

samples/partitioned_dml_sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from sample_helper import run_sample
1919

20+
2021
# Shows how to use Partitioned DML using SQLAlchemy and Spanner.
2122
def partitioned_dml_sample():
2223
engine = create_engine(

samples/pickle_type_sample.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from sample_helper import run_sample
2121
from model import Singer
2222

23+
2324
# Shows how to use PickleType with Spanner.
2425
def pickle_type():
2526
engine = create_engine(

setup.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@
6262
classifiers=[
6363
"Intended Audience :: Developers",
6464
"License :: OSI Approved :: Apache Software License",
65+
"Programming Language :: Python :: 3.9",
66+
"Programming Language :: Python :: 3.10",
67+
"Programming Language :: Python :: 3.11",
68+
"Programming Language :: Python :: 3.12",
69+
"Programming Language :: Python :: 3.13",
70+
"Programming Language :: Python :: 3.14",
6571
],
6672
description=description,
6773
long_description=readme,

0 commit comments

Comments
 (0)