Skip to content

Commit a1d7528

Browse files
committed
Python support up to 3.14
1 parent 66e4459 commit a1d7528

63 files changed

Lines changed: 360 additions & 275 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/tests.yml

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
strategy:
1919
matrix:
2020
backend: [numpy, pytorch, jax]
21-
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
21+
python-version: ["3.11", "3.12", "3.13", "3.14"]
2222
permissions:
2323
checks: write
2424
pull-requests: write
@@ -27,6 +27,24 @@ jobs:
2727
- name: Check out repository
2828
uses: actions/checkout@v4
2929

30+
- name: Install system build dependencies (when binary not available)
31+
run: |
32+
sudo apt-get update
33+
sudo apt-get install -y \
34+
gfortran pkg-config ninja-build \
35+
libopenblas-dev liblapack-dev \
36+
libfftw3-dev
37+
38+
- name: Install LLVM toolchain for llvmlite (cp314 only)
39+
if: ${{ matrix.python-version == '3.14' }}
40+
run: |
41+
sudo apt-get install -y \
42+
llvm-20 llvm-20-dev clang-20 \
43+
libedit-dev libcurl4-openssl-dev cmake
44+
echo "LLVM_CONFIG=/usr/lib/llvm-20/bin/llvm-config" >> $GITHUB_ENV
45+
echo "CC=clang-20" >> $GITHUB_ENV
46+
echo "CXX=clang++-20" >> $GITHUB_ENV
47+
3048
- name: Set up Python
3149
uses: actions/setup-python@v5
3250
with:
@@ -39,11 +57,10 @@ jobs:
3957
poetry env use python
4058
poetry install --extras "healpy_support"
4159
42-
- name: Install pytorch specific dependencies
60+
- name: Install pytorch specific dependencies afterward
4361
if: ${{ matrix.backend == 'pytorch' }}
4462
run: |
4563
poetry install --extras "healpy_support" --extras "pytorch_support"
46-
poetry run python -m pip install torch==2.1.0+cpu torchaudio==2.1.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
4764
4865
- name: Run tests
4966
run: |
@@ -55,7 +72,7 @@ jobs:
5572
- name: Upload test result artifact
5673
uses: actions/upload-artifact@v4
5774
with:
58-
name: ${{ matrix.backend }}-test-results
75+
name: ${{ matrix.backend }}-${{ matrix.python-version }}-test-results
5976
path: junit_test_results_${{ matrix.backend }}.xml
6077

6178
publish-results:

poetry.lock

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

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ authors = ["Florian Pfaff <pfaff@ias.uni-stuttgart.de>"]
66
version = "0.8.0"
77

88
[tool.poetry.dependencies]
9-
python = ">=3.10,<3.13"
9+
python = ">=3.11,<3.15"
1010
numpy = "*"
1111
scipy = "^1.14.1"
1212
matplotlib = "*"

pyrecest/_backend/__init__.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,11 @@ def _create_backend_module(self, backend_name: str):
280280
new_module = types.ModuleType(self._path)
281281
new_module.__file__ = getattr(backend, "__file__", None)
282282

283+
# expose chosen backend
284+
new_module.__backend_name__ = backend_name
285+
new_module.BACKEND_NAME = backend_name
286+
new_module.get_backend_name = staticmethod(lambda: backend_name)
287+
283288
for module_name, attributes in BACKEND_ATTRIBUTES.items():
284289
if module_name:
285290
try:
@@ -336,5 +341,8 @@ def exec_module(self, module):
336341
module.set_default_dtype("float64")
337342
logging.info(f"Using {BACKEND_NAME} backend")
338343

339-
# Insert at the *front* of sys.meta_path to ensure it takes precedence
340-
sys.meta_path.insert(0, BackendImporter("pyrecest.backend"))
344+
TARGET = "pyrecest.backend"
345+
if not any(isinstance(f, BackendImporter) and getattr(f, "_path", None) == TARGET
346+
for f in sys.meta_path):
347+
# put it in front so it intercepts 'pyrecest.backend'
348+
sys.meta_path.insert(0, BackendImporter(TARGET))

pyrecest/distributions/abstract_custom_distribution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def normalize(self, verify: bool | None = None) -> "AbstractCustomDistribution":
6464
:returns: A copy of the original distribution, with the PDF normalized.
6565
"""
6666
assert (
67-
pyrecest.backend.__name__ == "pyrecest.numpy"
67+
pyrecest.backend.__backend_name__ == "numpy"
6868
), "Only supported for numpy backend"
6969
cd = copy.deepcopy(self)
7070

pyrecest/distributions/abstract_manifold_specific_distribution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def sample_metropolis_hastings(
8282
# jscpd:ignore-end
8383
"""Metropolis Hastings sampling algorithm."""
8484
assert (
85-
pyrecest.backend.__name__ != "pyrecest.jax"
85+
pyrecest.backend.__backend_name__ != "jax"
8686
), "Not supported on this backend"
8787
if proposal is None or start_point is None:
8888
raise NotImplementedError(

pyrecest/distributions/cart_prod/abstract_hypercylindrical_distribution.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,9 @@ def mode_numerical(self, starting_point=None):
300300
m : ndarray
301301
The mode of the distribution.
302302
"""
303-
assert pyrecest.backend.__name__ in (
304-
"pyrecest.numpy",
305-
"pyrecest.pytorch",
303+
assert pyrecest.backend.__backend_name__ in (
304+
"numpy",
305+
"pytorch",
306306
), "Not supported for this backend."
307307
if starting_point is None:
308308
starting_point = concatenate(

pyrecest/distributions/circle/circular_fourier_distribution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ def from_distribution(
313313
else:
314314
xs = arange(
315315
0.0, 2.0 * pi, 2.0 * pi / n
316-
) # Like linspace without endpoint but with compatbiility for pytroch
316+
) # Like linspace without endpoint but with compatbiility for pytorch
317317
fvals = distribution.pdf(xs)
318318
if transformation == "identity":
319319
pass

pyrecest/distributions/circle/wrapped_normal_distribution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def pdf(self, xs):
6969
x = where(x < 0, x + 2.0 * pi, x)
7070
x -= self.mu
7171
max_iterations: int = 1000
72-
if pyrecest.backend.__name__ != "pyrecest.jax":
72+
if pyrecest.backend.__backend_name__ != "jax":
7373
n_inputs = xs.shape[0]
7474
result = zeros(n_inputs)
7575

pyrecest/distributions/hypersphere_subset/abstract_hyperhemispherical_distribution.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ def integrate_fun_over_domain(
151151
)
152152

153153
def mode_numerical(self):
154-
assert pyrecest.backend.__name__ in (
155-
"pyrecest.numpy",
156-
"pyrecest.pytorch",
154+
assert pyrecest.backend.__backend_name__ in (
155+
"numpy",
156+
"pytorch",
157157
), "Not supported for this backend."
158158

159159
def objective_function_2d(s):

0 commit comments

Comments
 (0)