Skip to content

Commit 8e7f1fa

Browse files
committed
Python 3.14 support
1 parent 5da04d0 commit 8e7f1fa

8 files changed

Lines changed: 87 additions & 28 deletions

File tree

.github/workflows/tests.yaml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,13 @@ jobs:
2626
fail-fast: false
2727
matrix:
2828
os: [ubuntu-latest, windows-latest, macos-latest]
29-
environment: [mindeps, "3.10", "3.11", "3.12", "3.13"]
29+
environment: [mindeps, "3.10", "3.11", "3.12", "3.13", "3.14"]
3030
label: [default]
3131
extra_packages: [null]
3232
# Cherry-pick test modules to split the overall runtime roughly in half
3333
partition: [ci1, not ci1]
3434

3535
exclude:
36-
# MacOS CI does not have any hosts available; run it on 3.12 only
37-
- os: macos-latest
38-
environment: mindeps
39-
- os: macos-latest
40-
environment: "3.10"
41-
- os: macos-latest
42-
environment: "3.11"
43-
- os: macos-latest
44-
environment: "3.13"
45-
4636
- os: windows-latest
4737
environment: mindeps
4838

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: dask-distributed-313
2+
channels:
3+
- conda-forge
4+
dependencies:
5+
- python=3.14
6+
- packaging
7+
- pip
8+
- asyncssh
9+
- bokeh>3
10+
- click
11+
- cloudpickle
12+
- coverage
13+
- dask # overridden by git tip below
14+
- fsspec # overridden by git tip below
15+
# - gilknocker # conda-forge package not yet available for Python 3.14
16+
- h5py
17+
- ipykernel
18+
- ipywidgets
19+
- jinja2
20+
- jupyter_events<0.11
21+
- jupyter-server-proxy
22+
- jupyterlab
23+
- locket
24+
- msgpack-python
25+
- netcdf4
26+
- paramiko
27+
- pre-commit
28+
- prometheus_client
29+
- psutil
30+
- pyarrow
31+
- pytest<8.4 # Pin due to https://github.com/pytest-dev/pytest-cov/issues/693
32+
- pytest-cov
33+
- pytest-faulthandler
34+
- pytest-repeat
35+
- pytest-rerunfailures
36+
- pytest-timeout
37+
- requests
38+
- scikit-learn
39+
- scipy
40+
- sortedcollections
41+
- tblib !=3.2.0,!=3.2.1
42+
- toolz
43+
- tornado
44+
- zict # overridden by git tip below
45+
- zstandard
46+
# Temporary fix for https://github.com/pypa/setuptools/issues/4496
47+
- setuptools < 71
48+
# Temporary fix for https://github.com/jupyterlab/jupyterlab/issues/17012
49+
- httpx<0.28.0
50+
- pip:
51+
- git+https://github.com/dask/dask
52+
- git+https://github.com/dask/zict
53+
- git+https://github.com/fsspec/filesystem_spec
54+
- keras
55+
- gilknocker # conda-forge package not yet available for Python 3.14

distributed/client.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3250,8 +3250,20 @@ def _get_computation_code(
32503250
"|".join([f"(?:{mod})" for mod in ignore_modules])
32513251
)
32523252
if ignore_files:
3253+
# Given ignore-files = [foo], match:
3254+
# /path/to/foo
3255+
# /path/to/foo.py[c]
3256+
# /path/to/foo/bar.py[c]
3257+
# \path\to\foo
3258+
# \path\to\foo.py[c]
3259+
# \path\to\foo\bar.py[c]
3260+
# <frozen foo>
3261+
# Do not match files that have 'foo' as a substring,
3262+
# unless the user explicitly states '.*foo.*'.
3263+
ignore_files_or = "|".join(mod for mod in ignore_files)
32533264
fname_pattern = re.compile(
3254-
r".*[\\/](" + "|".join(mod for mod in ignore_files) + r")([\\/]|$)"
3265+
rf".*[\\/]({ignore_files_or})([\\/]|\.pyc?$|$)"
3266+
rf"|<frozen ({ignore_files_or})>$"
32553267
)
32563268
else:
32573269
# stacklevel 0 or less - shows dask internals which likely isn't helpful

distributed/cluster_dump.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ def to_yamls(
304304
import yaml
305305

306306
root_dir = Path(root_dir) if root_dir else Path.cwd()
307-
dumper = yaml.CSafeDumper
307+
# libyaml C bindings may be missing
308+
dumper = getattr(yaml, "CSafeDumper", yaml.SafeDumper)
308309
scheduler_expand_keys = set(scheduler_expand_keys)
309310
worker_expand_keys = set(worker_expand_keys)
310311

distributed/distributed.yaml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,15 @@ distributed:
289289
- __channelexec__ # more xdist
290290
- execnet # more xdist
291291
ignore-files:
292-
- runpy\.py # `python -m pytest` (or other module) shell command
293-
- pytest # `pytest` shell command
294-
- py\.test # `py.test` shell command
295-
- pytest-script\.py # `pytest` shell command in Windows
296-
- _pytest # pytest implementation
292+
# `python -m pytest` (or other module)
293+
# runpy.py on Python <=3.13; <frozen runpy> on >=3.14
294+
- runpy
295+
# Many variations of pytest:
296+
# pytest, py.test, pytest-script (on Windows),
297+
# _pytest (implementation), vscode_pytest
298+
- .*py\.?test.*
297299
- pycharm # Run pytest from PyCharm GUI
298-
- vscode_pytest
299-
- get_output_via_markers\.py
300+
- get_output_via_markers
300301
erred-tasks:
301302
max-history: 100
302303

distributed/protocol/tests/test_protocol.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,16 +162,15 @@ def test_sizeof_serialize(Wrapper, Wrapped):
162162
@pytest.mark.skipif(WINDOWS, reason="On windows this is triggering a stackoverflow")
163163
def test_deeply_nested_structures():
164164
# These kind of deeply nested structures are generated in our profiling code
165-
def gen_deeply_nested(depth, msg=None):
166-
d = msg or {}
167-
while depth:
168-
depth -= 1
165+
def gen_deeply_nested(depth):
166+
d = {}
167+
for _ in range(depth):
169168
d = {"children": d}
170169
return d
171170

172-
msg = {}
173-
for _ in range(10):
174-
msg = gen_deeply_nested(sys.getrecursionlimit() // 2, msg=msg)
171+
# Note: Python <=3.13 already fails with 2x the recursion limit;
172+
# 3.14 keeps working until 14x for some reason
173+
msg = gen_deeply_nested(sys.getrecursionlimit() * 14)
175174

176175
with pytest.raises(RecursionError):
177176
copy.deepcopy(msg)

distributed/shuffle/tests/test_shuffle_plugins.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from __future__ import annotations
22

3-
from asyncio import iscoroutinefunction
43

54
import pytest
65

76
from distributed.shuffle._scheduler_plugin import ShuffleSchedulerPlugin
87
from distributed.shuffle._worker_plugin import ShuffleWorkerPlugin
8+
from distributed.utils import iscoroutinefunction
99
from distributed.utils_test import gen_cluster
1010

1111
pd = pytest.importorskip("pandas")

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ classifiers = [
2020
"Programming Language :: Python :: 3.11",
2121
"Programming Language :: Python :: 3.12",
2222
"Programming Language :: Python :: 3.13",
23+
"Programming Language :: Python :: 3.14",
2324
"Topic :: Scientific/Engineering",
2425
"Topic :: System :: Distributed Computing",
2526
]

0 commit comments

Comments
 (0)