diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0a227a3..6917dd1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,12 +10,10 @@ jobs: strategy: matrix: include: - - {runs-on: ubuntu-24.04, python-version: "3.10"} - - {runs-on: ubuntu-24.04, python-version: "3.11"} - {runs-on: ubuntu-24.04, python-version: "3.12"} - - {runs-on: macos-13, python-version: "3.10"} - - {runs-on: macos-13, python-version: "3.11"} - - {runs-on: macos-13, python-version: "3.12"} + - {runs-on: ubuntu-24.04, python-version: "3.13"} + - {runs-on: ubuntu-24.04, python-version: "3.14"} + - {runs-on: macos-15-intel, python-version: "3.12"} steps: - name: Check out repository uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index 6a582e6..28c9cba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pystan" -version = "3.10.0" +version = "3.10.1" description = "Python interface to Stan, a package for Bayesian inference" authors = [ "Allen Riddell ", @@ -22,21 +22,21 @@ classifiers = [ ] [tool.poetry.dependencies] -python = "^3.10" +python = "^3.12" aiohttp = "^3.6" httpstan = "~4.13" -pysimdjson = ">=5.0.2,<7" +pysimdjson = ">=5.0.2" numpy = ">=1.19" clikit = "^0.6" setuptools = "*" [tool.poetry.dev-dependencies] -pytest = "^6.2" -pytest-asyncio = "^0.18.3" +pytest = "^9.0.2" +pytest-asyncio = "^1.3" pandas = ">=1.0,<3" -black = "22.6.0" +black = "26.3.0" isort = "^5.9" -mypy = "0.982" +mypy = "1.19" types-setuptools = "^57.4" # documentation # NOTE: when changing these, update docs-requirements.txt diff --git a/stan/common.py b/stan/common.py index d60a2de..60000ab 100644 --- a/stan/common.py +++ b/stan/common.py @@ -1,4 +1,5 @@ """Common routines""" + import socket import typing diff --git a/stan/fit.py b/stan/fit.py index 3dda627..978a484 100644 --- a/stan/fit.py +++ b/stan/fit.py @@ -96,6 +96,7 @@ def __init__( ) draw_row = tuple(msg["values"].values()) # a "row" of values from a single draw from Stan C++ + draw_row = cast(Tuple[float, ...], draw_row) self._draws[:, draw_index, chain_index] = draw_row draw_index += 1 finally: diff --git a/stan/plugins.py b/stan/plugins.py index 0a59d43..ea0d9dc 100644 --- a/stan/plugins.py +++ b/stan/plugins.py @@ -1,14 +1,12 @@ import abc -from typing import Generator - -import pkg_resources +import importlib.metadata import stan.fit -def get_plugins() -> Generator[pkg_resources.EntryPoint, None, None]: +def get_plugins() -> importlib.metadata.EntryPoints: """Iterate over available plugins.""" - return pkg_resources.iter_entry_points(group="stan.plugins") + return importlib.metadata.entry_points(group="stan.plugins") class PluginBase(abc.ABC): diff --git a/tests/conftest.py b/tests/conftest.py index 64adb55..3fd181e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ """pytest configuration for all tests.""" + import pytest diff --git a/tests/test_build_exceptions.py b/tests/test_build_exceptions.py index fbecc06..5c3c0b5 100644 --- a/tests/test_build_exceptions.py +++ b/tests/test_build_exceptions.py @@ -1,4 +1,5 @@ """Tests for build related exceptions.""" + import pytest import stan diff --git a/tests/test_build_program.py b/tests/test_build_program.py index 334af2c..04756c7 100644 --- a/tests/test_build_program.py +++ b/tests/test_build_program.py @@ -1,4 +1,5 @@ """Test building a Stan program.""" + import pytest import stan diff --git a/tests/test_constrain_pars.py b/tests/test_constrain_pars.py index 4bf6723..a9f7cc7 100644 --- a/tests/test_constrain_pars.py +++ b/tests/test_constrain_pars.py @@ -1,4 +1,5 @@ """Test constrain parameters.""" + import random import numpy as np diff --git a/tests/test_corr_matrix.py b/tests/test_corr_matrix.py index bf5f2d5..c9fd206 100644 --- a/tests/test_corr_matrix.py +++ b/tests/test_corr_matrix.py @@ -1,4 +1,5 @@ """CPU-intensive test, useful for testing progress bars.""" + import stan program_code = """ diff --git a/tests/test_eight_schools_large.py b/tests/test_eight_schools_large.py index 7cad048..9f1af11 100644 --- a/tests/test_eight_schools_large.py +++ b/tests/test_eight_schools_large.py @@ -3,6 +3,7 @@ Introduced in response to a macOS bug that only triggered when a larger number of parameters were used. """ + import pytest import stan diff --git a/tests/test_fit_basic_array.py b/tests/test_fit_basic_array.py index 522ca65..1172334 100644 --- a/tests/test_fit_basic_array.py +++ b/tests/test_fit_basic_array.py @@ -1,4 +1,5 @@ """Test model with array parameter.""" + import numpy as np import pytest diff --git a/tests/test_fit_basic_matrix.py b/tests/test_fit_basic_matrix.py index d0e02f2..8d05200 100644 --- a/tests/test_fit_basic_matrix.py +++ b/tests/test_fit_basic_matrix.py @@ -1,4 +1,5 @@ """Test model with a matrix parameter.""" + import pytest import stan diff --git a/tests/test_fit_basic_scalar.py b/tests/test_fit_basic_scalar.py index 6c6c7e2..9e58452 100644 --- a/tests/test_fit_basic_scalar.py +++ b/tests/test_fit_basic_scalar.py @@ -1,4 +1,5 @@ """Test model with a scalar parameter.""" + import numpy as np import pytest diff --git a/tests/test_fit_basic_vector.py b/tests/test_fit_basic_vector.py index cf8f0e2..a8c6b4e 100644 --- a/tests/test_fit_basic_vector.py +++ b/tests/test_fit_basic_vector.py @@ -1,4 +1,5 @@ """Test model with a vector parameter.""" + import numpy as np import pytest diff --git a/tests/test_fit_cache.py b/tests/test_fit_cache.py index 66f0987..a0c4492 100644 --- a/tests/test_fit_cache.py +++ b/tests/test_fit_cache.py @@ -1,4 +1,5 @@ """Tests related to cached fits.""" + import os import pathlib import random diff --git a/tests/test_fit_shape.py b/tests/test_fit_shape.py index 8122c22..ac2f47d 100644 --- a/tests/test_fit_shape.py +++ b/tests/test_fit_shape.py @@ -1,4 +1,5 @@ """Test model parameter shapes.""" + import pytest import stan diff --git a/tests/test_grad_log_prob.py b/tests/test_grad_log_prob.py index 96a17e6..31848b4 100644 --- a/tests/test_grad_log_prob.py +++ b/tests/test_grad_log_prob.py @@ -1,4 +1,5 @@ """Test model with array parameter.""" + import random import numpy as np diff --git a/tests/test_log_prob.py b/tests/test_log_prob.py index 18f8407..810aba2 100644 --- a/tests/test_log_prob.py +++ b/tests/test_log_prob.py @@ -1,4 +1,5 @@ """Test model with array parameter.""" + import numpy as np import pytest diff --git a/tests/test_model_build_data.py b/tests/test_model_build_data.py index 39605fa..ef823aa 100644 --- a/tests/test_model_build_data.py +++ b/tests/test_model_build_data.py @@ -1,4 +1,5 @@ """Test handling of `data` dictionary.""" + import copy import numpy as np diff --git a/tests/test_nan_inf.py b/tests/test_nan_inf.py index 0926349..77f8094 100644 --- a/tests/test_nan_inf.py +++ b/tests/test_nan_inf.py @@ -1,4 +1,5 @@ """Test serialization of nan and inf values.""" + import math import stan diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 628296c..e3fa365 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -1,4 +1,5 @@ -import pkg_resources +import importlib.metadata + import pytest import stan @@ -20,7 +21,7 @@ def load(): return DummyPlugin -def mock_iter_entry_points(group): +def mock_entry_points(group): return iter([MockEntryPoint]) @@ -31,7 +32,7 @@ def normal_posterior(): def test_get_plugins(monkeypatch): - monkeypatch.setattr(pkg_resources, "iter_entry_points", mock_iter_entry_points) + monkeypatch.setattr(importlib.metadata, "entry_points", mock_entry_points) entry_points = stan.plugins.get_plugins() Plugin = next(entry_points).load() @@ -40,7 +41,7 @@ def test_get_plugins(monkeypatch): def test_dummy_plugin(monkeypatch, capsys, normal_posterior): - monkeypatch.setattr(pkg_resources, "iter_entry_points", mock_iter_entry_points) + monkeypatch.setattr(importlib.metadata, "entry_points", mock_entry_points) fit = normal_posterior.sample(stepsize=0.001) assert fit is not None and "y" in fit @@ -65,10 +66,10 @@ def load(): def test_two_plugins(monkeypatch, capsys, normal_posterior): """Make sure that both plugins are used.""" - def mock_iter_entry_points(group): + def mock_entry_points(group): return iter([MockEntryPoint, OtherMockEntryPoint]) - monkeypatch.setattr(pkg_resources, "iter_entry_points", mock_iter_entry_points) + monkeypatch.setattr(importlib.metadata, "entry_points", mock_entry_points) fit = normal_posterior.sample(stepsize=0.001) assert fit is not None and "y" in fit diff --git a/tests/test_sample_exceptions.py b/tests/test_sample_exceptions.py index 09bf919..89db294 100644 --- a/tests/test_sample_exceptions.py +++ b/tests/test_sample_exceptions.py @@ -1,4 +1,5 @@ """Tests for sampling related exceptions.""" + import pytest import stan diff --git a/tests/test_stanc_warnings.py b/tests/test_stanc_warnings.py index baf561e..154cdc9 100644 --- a/tests/test_stanc_warnings.py +++ b/tests/test_stanc_warnings.py @@ -1,4 +1,5 @@ """Test that stanc warnings are visible.""" + import contextlib import io diff --git a/tests/test_transformed_data_rng.py b/tests/test_transformed_data_rng.py index 637303f..813af5d 100644 --- a/tests/test_transformed_data_rng.py +++ b/tests/test_transformed_data_rng.py @@ -1,4 +1,5 @@ """Verify that the RNG in the transformed data block uses the overall seed.""" + import numpy as np import stan diff --git a/tests/test_unconstrain_pars.py b/tests/test_unconstrain_pars.py index bd6b1ce..06f88ca 100644 --- a/tests/test_unconstrain_pars.py +++ b/tests/test_unconstrain_pars.py @@ -1,4 +1,5 @@ """Test constrain parameters.""" + import random import numpy as np