Skip to content

Commit dea8078

Browse files
kevinjqliusa1
andauthored
infra: Add Python 3.13 support (apache#2863)
<!-- Thanks for opening a pull request! --> <!-- In the case this PR will resolve an issue, please replace ${GITHUB_ISSUE_ID} below with the actual Github issue id. --> <!-- Closes #${GITHUB_ISSUE_ID} --> # Rationale for this change Closes apache#1372, apache#2530 Based on apache#1377, apache#2536, apache#2658 Adds Python 3.13 throughout the repo Upgrade `ray` to a version built with python 3.13 Add `filterwarnings` for `ResourceWarnings` coming from `sqlite` and `ray` for now, will follow up with a proper fix ## Are these changes tested? Yes ``` PYTHON=3.13 make install PYTHON=3.13 make test PYTHON=3.13 make test-integration ``` ## Are there any user-facing changes? <!-- In the case of user-facing changes, please add the changelog label. --> --------- Co-authored-by: Saurabh Kumar <github@sa1.me> Co-authored-by: Saurabh Kumar <557509+sa1@users.noreply.github.com>
1 parent 2d8397e commit dea8078

8 files changed

Lines changed: 56 additions & 30 deletions

File tree

.github/workflows/pypi-build-artifacts.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
3.10
4646
3.11
4747
3.12
48+
3.13
4849
4950
- name: Install UV
5051
uses: astral-sh/setup-uv@v7
@@ -68,7 +69,7 @@ jobs:
6869
env:
6970
# Ignore 32 bit architectures
7071
CIBW_ARCHS: "auto64"
71-
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10"
72+
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10,<3.14"
7273
CIBW_TEST_REQUIRES: "pytest==7.4.2 moto==5.0.1"
7374
CIBW_TEST_COMMAND: "pytest {project}/tests/avro/test_decoder.py"
7475
# Ignore tests for pypy since not all dependencies are compiled for it

.github/workflows/python-ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
runs-on: ubuntu-latest
4848
strategy:
4949
matrix:
50-
python: ['3.10', '3.11', '3.12']
50+
python: ['3.10', '3.11', '3.12', '3.13']
5151

5252
steps:
5353
- uses: actions/checkout@v6
@@ -71,7 +71,7 @@ jobs:
7171
runs-on: ubuntu-latest
7272
strategy:
7373
matrix:
74-
python: ['3.10', '3.11', '3.12']
74+
python: ['3.10', '3.11', '3.12', '3.13']
7575

7676
steps:
7777
- uses: actions/checkout@v6

.github/workflows/svn-build-artifacts.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ jobs:
4545
3.10
4646
3.11
4747
3.12
48+
3.13
4849
4950
- name: Install UV
5051
uses: astral-sh/setup-uv@v7
@@ -63,7 +64,7 @@ jobs:
6364
env:
6465
# Ignore 32 bit architectures
6566
CIBW_ARCHS: "auto64"
66-
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10"
67+
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10,<3.14"
6768
CIBW_TEST_REQUIRES: "pytest==7.4.2 moto==5.0.1"
6869
CIBW_TEST_COMMAND: "pytest {project}/tests/avro/test_decoder.py"
6970
# Ignore tests for pypy since not all dependencies are compiled for it

pyproject.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ classifiers = [
2828
"Programming Language :: Python :: 3.10",
2929
"Programming Language :: Python :: 3.11",
3030
"Programming Language :: Python :: 3.12",
31+
"Programming Language :: Python :: 3.13",
3132
]
3233
dependencies = [
3334
"mmh3>=4.0.0,<6.0.0",
@@ -66,7 +67,7 @@ duckdb = [
6667
"pyarrow>=17.0.0",
6768
]
6869
ray = [
69-
"ray>=2.10.0,<=2.44.0",
70+
"ray>=2.10.0,<3.0.0",
7071
"pyarrow>=17.0.0",
7172
"pandas>=1.0.0,<3.0.0",
7273
]
@@ -160,6 +161,11 @@ filterwarnings = [
160161
"error",
161162
# Ignore Python version deprecation warning from google.api_core while we still support 3.10
162163
"ignore:You are using a Python version.*which Google will stop supporting:FutureWarning:google.api_core",
164+
# Python 3.13 sqlite3 module ResourceWarnings for unclosed database connections
165+
"ignore:unclosed database in <sqlite3.Connection object*:ResourceWarning",
166+
# Ignore Ray subprocess cleanup warnings
167+
"ignore:unclosed file:ResourceWarning",
168+
"ignore:subprocess.*is still running:ResourceWarning",
163169
]
164170

165171
[tool.black]

tests/catalog/test_base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# pylint:disable=redefined-outer-name
1818

1919

20+
from collections.abc import Generator
2021
from pathlib import PosixPath
2122

2223
import pyarrow as pa
@@ -51,8 +52,10 @@
5152

5253

5354
@pytest.fixture
54-
def catalog(tmp_path: PosixPath) -> InMemoryCatalog:
55-
return InMemoryCatalog("test.in_memory.catalog", **{WAREHOUSE: tmp_path.absolute().as_posix(), "test.key": "test.value"})
55+
def catalog(tmp_path: PosixPath) -> Generator[Catalog, None, None]:
56+
catalog = InMemoryCatalog("test.in_memory.catalog", **{WAREHOUSE: tmp_path.absolute().as_posix(), "test.key": "test.value"})
57+
yield catalog
58+
catalog.close()
5659

5760

5861
TEST_TABLE_IDENTIFIER = ("com", "organization", "department", "my_table")

tests/conftest.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2947,3 +2947,16 @@ def pyarrow_table_with_promoted_types(pyarrow_schema_with_promoted_types: "pa.Sc
29472947
},
29482948
schema=pyarrow_schema_with_promoted_types,
29492949
)
2950+
2951+
2952+
@pytest.fixture(scope="session")
2953+
def ray_session() -> Generator[Any, None, None]:
2954+
"""Fixture to manage Ray initialization and shutdown for tests."""
2955+
import ray
2956+
2957+
ray.init(
2958+
ignore_reinit_error=True,
2959+
runtime_env={"working_dir": None}, # Prevent Ray from serializing the working directory to workers
2960+
)
2961+
yield ray
2962+
ray.shutdown()

tests/integration/test_reads.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import uuid
2222
from datetime import datetime, timedelta
2323
from pathlib import PosixPath
24+
from typing import Any
2425
from urllib.parse import urlparse
2526

2627
import pyarrow as pa
@@ -357,16 +358,17 @@ def test_bodo_nan(catalog: Catalog, monkeypatch: pytest.MonkeyPatch) -> None:
357358
@pytest.mark.integration
358359
@pytest.mark.filterwarnings("ignore")
359360
@pytest.mark.parametrize("catalog", [pytest.lazy_fixture("session_catalog_hive"), pytest.lazy_fixture("session_catalog")])
360-
def test_ray_nan(catalog: Catalog) -> None:
361+
def test_ray_nan(catalog: Catalog, ray_session: Any) -> None:
361362
table_test_null_nan_rewritten = catalog.load_table("default.test_null_nan_rewritten")
362363
ray_dataset = table_test_null_nan_rewritten.scan().to_ray()
363364
assert ray_dataset.count() == 3
364365
assert math.isnan(ray_dataset.take()[0]["col_numeric"])
365366

366367

367368
@pytest.mark.integration
369+
@pytest.mark.filterwarnings("ignore")
368370
@pytest.mark.parametrize("catalog", [pytest.lazy_fixture("session_catalog_hive"), pytest.lazy_fixture("session_catalog")])
369-
def test_ray_nan_rewritten(catalog: Catalog) -> None:
371+
def test_ray_nan_rewritten(catalog: Catalog, ray_session: Any) -> None:
370372
table_test_null_nan_rewritten = catalog.load_table("default.test_null_nan_rewritten")
371373
ray_dataset = table_test_null_nan_rewritten.scan(
372374
row_filter=IsNaN("col_numeric"), selected_fields=("idx", "col_numeric")
@@ -377,17 +379,19 @@ def test_ray_nan_rewritten(catalog: Catalog) -> None:
377379

378380

379381
@pytest.mark.integration
382+
@pytest.mark.filterwarnings("ignore")
380383
@pytest.mark.parametrize("catalog", [pytest.lazy_fixture("session_catalog_hive"), pytest.lazy_fixture("session_catalog")])
381384
@pytest.mark.skip(reason="Fixing issues with NaN's: https://github.com/apache/arrow/issues/34162")
382-
def test_ray_not_nan_count(catalog: Catalog) -> None:
385+
def test_ray_not_nan_count(catalog: Catalog, ray_session: Any) -> None:
383386
table_test_null_nan_rewritten = catalog.load_table("default.test_null_nan_rewritten")
384387
ray_dataset = table_test_null_nan_rewritten.scan(row_filter=NotNaN("col_numeric"), selected_fields=("idx",)).to_ray()
385388
assert ray_dataset.count() == 2
386389

387390

388391
@pytest.mark.integration
392+
@pytest.mark.filterwarnings("ignore")
389393
@pytest.mark.parametrize("catalog", [pytest.lazy_fixture("session_catalog_hive"), pytest.lazy_fixture("session_catalog")])
390-
def test_ray_all_types(catalog: Catalog) -> None:
394+
def test_ray_all_types(catalog: Catalog, ray_session: Any) -> None:
391395
table_test_all_types = catalog.load_table("default.test_all_types")
392396
ray_dataset = table_test_all_types.scan().to_ray()
393397
pandas_dataframe = table_test_all_types.scan().to_pandas()

uv.lock

Lines changed: 17 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)