Skip to content

Commit ee1de5f

Browse files
Sfonxuslayoo
andauthored
Python 3.13 compatibility: CI jobs; alternative implementation of clock(); use numdifftools instead of discontinued scipy.misc.derivative (#553)
Co-authored-by: Sylwester Arabas <[email protected]>
1 parent 38a4a38 commit ee1de5f

File tree

5 files changed

+43
-18
lines changed

5 files changed

+43
-18
lines changed

.github/workflows/tests.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ jobs:
3333
with:
3434
submodules: recursive
3535
fetch-depth: 0
36-
- name: Set up Python 3.9
36+
- name: Set up Python
3737
uses: actions/[email protected]
3838
with:
39-
python-version: 3.9
39+
python-version: 3.11
4040
- name: Install dependencies
4141
run: |
4242
python -m pip install --upgrade pip
@@ -79,17 +79,21 @@ jobs:
7979

8080
nojit_and_codecov:
8181
needs: [ precommit, pylint, zenodo_json, devops ]
82+
strategy:
83+
matrix:
84+
python-version: ["3.9", "3.13"]
8285
runs-on: ubuntu-latest
8386
env:
8487
NUMBA_DISABLE_JIT: 1
88+
PYTHON: ${{ matrix.python-version }}
8589
steps:
8690
- uses: actions/checkout@master
8791
with:
8892
submodules: recursive
8993
fetch-depth: 0
9094
- uses: actions/[email protected]
9195
with:
92-
python-version: 3.9
96+
python-version: ${{ matrix.python-version }}
9397
- name: Generate coverage report
9498
run: |
9599
pip install -e .[tests] -e ./examples
@@ -98,6 +102,7 @@ jobs:
98102
- name: Upload coverage to Codecov
99103
uses: codecov/codecov-action@v4
100104
with:
105+
env_vars: PYTHON
101106
token: ${{ secrets.CODECOV_TOKEN }}
102107
fail_ci_if_error: true
103108
verbose: true
@@ -108,7 +113,7 @@ jobs:
108113
strategy:
109114
matrix:
110115
platform: [ubuntu-latest, macos-13, macos-14, windows-latest]
111-
python-version: ["3.9", "3.12"]
116+
python-version: ["3.9", "3.13"]
112117
exclude:
113118
- platform: macos-14
114119
python-version: "3.9"
@@ -148,7 +153,7 @@ jobs:
148153
strategy:
149154
matrix:
150155
platform: [ubuntu-latest, macos-13, macos-14, windows-latest]
151-
python-version: ["3.9", "3.12"]
156+
python-version: ["3.9", "3.13"]
152157
fail-fast: false
153158
runs-on: ${{ matrix.platform }}
154159
steps:
@@ -185,7 +190,7 @@ jobs:
185190
NUMBA_OPT: 1
186191
run: python -m pytest --durations=10 -p no:unraisableexception -We tests/devops_tests/test_notebooks.py
187192

188-
- if: ${{ matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.12'}}
193+
- if: ${{ matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.13'}}
189194
run: |
190195
mkdir -p /home/runner/work/_temp/_github_home/figures
191196
rm /tmp/pytest-of-runner/pytest-current/test_run_notebooks_examples_Pycurrent
@@ -199,7 +204,7 @@ jobs:
199204
# with:
200205
# limit-access-to-actor: true
201206

202-
- if: ${{ github.ref == 'refs/heads/main' && matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.12'}}
207+
- if: ${{ github.ref == 'refs/heads/main' && matrix.platform == 'ubuntu-latest' && matrix.python-version == '3.13'}}
203208
uses: eine/tip@master
204209
with:
205210
token: ${{ secrets.GITHUB_TOKEN }}

PyMPDATA/impl/clock.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,25 @@
22
no time unit guaranteed, returned value only for relative time measurements"""
33

44
import ctypes
5+
import sys
56

6-
clock = ctypes.pythonapi._PyTime_GetSystemClock # pylint:disable=protected-access
7-
clock.argtypes = []
8-
clock.restype = ctypes.c_int64
7+
import numba
8+
import numpy as np
9+
10+
if sys.version_info < (3, 13):
11+
clock = ctypes.pythonapi._PyTime_GetSystemClock # pylint:disable=protected-access
12+
clock.argtypes = []
13+
clock.restype = ctypes.c_int64
14+
else:
15+
clock_impl = ctypes.pythonapi.PyTime_Time
16+
clock_impl.argtypes = [ctypes.c_void_p]
17+
clock_impl.restype = ctypes.c_int64
18+
19+
assert ctypes.c_time_t == ctypes.c_int64 # pylint: disable=no-member
20+
21+
@numba.jit("int64()", nopython=True)
22+
def clock():
23+
"""Numba-JITable version of clock function for Python > 3.12"""
24+
result = np.empty(shape=(1,), dtype=np.int64)
25+
clock_impl(result.ctypes)
26+
return result[0]

examples/PyMPDATA_examples/Shipway_and_Hill_2012/settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
from typing import Optional
22

33
import numpy as np
4+
from numdifftools import Derivative
45
from PyMPDATA_examples.Olesik_et_al_2022.settings import ksi_1 as default_ksi_1
56
from pystrict import strict
67
from scipy.integrate import solve_ivp
78
from scipy.interpolate import interp1d
8-
from scipy.misc import derivative
99

1010
from . import formulae
1111
from .arakawa_c import arakawa_c
@@ -53,7 +53,7 @@ def drhod_dz(z, rhod):
5353
drhod_dz = formulae.drho_dz(const.g, p, T, self.qv(z), const.lv)
5454
if not apprx_drhod_dz: # to resolve issue #335
5555
qv = self.qv(z)
56-
dqv_dz = derivative(self.qv, z)
56+
dqv_dz = Derivative(self.qv)(z)
5757
drhod_dz = drhod_dz / (1 + qv) - rhod * dqv_dz / (1 + qv)
5858
return drhod_dz
5959

examples/setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ def get_long_description():
2929
"open-atmos-jupyter-utils",
3030
"pystrict",
3131
"matplotlib",
32-
"ipywidgets" + "<8.0.3" if CI else "",
32+
"ipywidgets" + "==8.1.7" if CI else "",
3333
"scipy",
3434
"pint",
3535
"joblib",
3636
"sympy",
3737
"imageio",
3838
"meshio",
39+
"numdifftools",
3940
],
4041
author="https://github.com/open-atmos/PyMPDATA/graphs/contributors",
4142
license="GPL-3.0",

setup.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def get_long_description():
3535
10: "==0.58.1",
3636
11: "==0.58.1",
3737
12: "==0.59.1",
38-
13: "==0.59.1",
38+
13: "==0.61.2",
3939
}[sys.version_info.minor]
4040
if CI and not _32bit
4141
else ""
@@ -48,7 +48,7 @@ def get_long_description():
4848
10: "==1.24.4",
4949
11: "==1.24.4",
5050
12: "==1.26.4",
51-
13: "==1.26.4",
51+
13: "==2.2.5",
5252
}[sys.version_info.minor]
5353
if CI
5454
else ""
@@ -67,14 +67,15 @@ def get_long_description():
6767
10: "==1.10.1",
6868
11: "==1.10.1",
6969
12: "==1.13.0",
70-
13: "==1.13.0",
70+
13: "==1.15.3",
7171
}[sys.version_info.minor]
7272
if CI and not _32bit
7373
else ""
7474
),
7575
"jupyter-core" + ("<5.0.0" if CI else ""),
76-
"ipywidgets" + ("!=8.0.3" if CI else ""),
77-
"ipykernel" + ("<6.22.0" if CI else ""),
76+
"jupyter_client" + ("==8.6.3" if CI else ""),
77+
"ipywidgets" + ("==8.1.7" if CI else ""),
78+
"ipykernel" + ("==7.0.0a1" if CI else ""),
7879
"ghapi",
7980
"pytest",
8081
"pytest-benchmark",

0 commit comments

Comments
 (0)