From db64d79255ed6ae4986bd403eb82e352820a7edb Mon Sep 17 00:00:00 2001 From: Sebastian Cadavid Sanchez Date: Wed, 23 Jul 2025 03:06:40 -0500 Subject: [PATCH 1/3] Bump statsmodels to 0.14.5 to fix scipy 1.16+ import error (#420) --- requirements.txt | 2 +- tests/test_statsmodels_scipy_compatibility.py | 97 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 tests/test_statsmodels_scipy_compatibility.py diff --git a/requirements.txt b/requirements.txt index a28eda36..c2d70487 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ numpy==1.26.4 matplotlib==3.10.1 dask[array, distributed]==2025.2.0 requests==2.32.3 -statsmodels==0.14.4 +statsmodels==0.14.5 pytest==8.4.1 pytest-cov==6.2.1 zarr==2.18.4 diff --git a/tests/test_statsmodels_scipy_compatibility.py b/tests/test_statsmodels_scipy_compatibility.py new file mode 100644 index 00000000..af984018 --- /dev/null +++ b/tests/test_statsmodels_scipy_compatibility.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +""" +Compatibility test: statsmodels vs scipy + +This script verifies that statsmodels >= 0.14.5 is compatible with scipy >= 1.16.0, +resolving the import error caused by the removal of `_lazywhere` in scipy internals. + +Reference: +- statsmodels 0.14.5 release notes: https://github.com/statsmodels/statsmodels/releases/tag/v0.14.5 + +Usage: + python test_statsmodels_scipy_compatibility.py + pytest test_statsmodels_scipy_compatibility.py +""" + +import sys +import importlib + + +def check_versions(): + """Print installed versions of relevant packages.""" + print("Installed package versions:") + for pkg in ["scipy", "statsmodels", "numpy"]: + try: + mod = importlib.import_module(pkg) + print(f" {pkg:<12} {mod.__version__}") + except ImportError: + print(f" {pkg:<12} not installed") + print() + + +def test_statsmodels_import(): + """Ensure statsmodels can be imported and has expected version.""" + import statsmodels + assert statsmodels.__version__ >= "0.14.5" + + +def test_statsmodels_api_import(): + """Ensure statsmodels.api can be imported without triggering ImportError.""" + import statsmodels.api as sm + assert hasattr(sm, "OLS") + assert len(dir(sm)) > 10 # Sanity check + + +def test_problematic_modules(): + """Test modules previously affected by _lazywhere import failure.""" + problematic_modules = [ + "statsmodels.genmod._tweedie_compound_poisson", + "statsmodels.distributions.discrete", + ] + + for module_name in problematic_modules: + module = importlib.import_module(module_name) + assert module is not None + + +def run_cli_mode(): + """Run all tests manually in CLI mode with status output.""" + print("=" * 60) + print("Running statsmodels/scipy compatibility checks") + print("=" * 60) + check_versions() + + all_passed = True + + try: + test_statsmodels_import() + print("statsmodels import: PASSED") + except Exception as e: + print(f"statsmodels import: FAILED ({e})") + all_passed = False + + try: + test_statsmodels_api_import() + print("statsmodels.api import: PASSED") + except Exception as e: + print(f"statsmodels.api import: FAILED ({e})") + all_passed = False + + try: + test_problematic_modules() + print("problematic module imports: PASSED") + except Exception as e: + print(f"problematic module imports: FAILED ({e})") + all_passed = False + + print("=" * 60) + if all_passed: + print("All compatibility checks passed.") + sys.exit(0) + else: + print("One or more compatibility checks failed.") + sys.exit(1) + + +if __name__ == "__main__": + run_cli_mode() From 9e2afda148ee2d72ac8f1c83b7f1fefa0dda2589 Mon Sep 17 00:00:00 2001 From: Sebastian Cadavid Sanchez Date: Wed, 23 Jul 2025 03:23:29 -0500 Subject: [PATCH 2/3] Fix formatting of compatibility test to pass ruff check --- tests/test_statsmodels_scipy_compatibility.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_statsmodels_scipy_compatibility.py b/tests/test_statsmodels_scipy_compatibility.py index af984018..a3ca1c3f 100644 --- a/tests/test_statsmodels_scipy_compatibility.py +++ b/tests/test_statsmodels_scipy_compatibility.py @@ -32,12 +32,14 @@ def check_versions(): def test_statsmodels_import(): """Ensure statsmodels can be imported and has expected version.""" import statsmodels + assert statsmodels.__version__ >= "0.14.5" def test_statsmodels_api_import(): """Ensure statsmodels.api can be imported without triggering ImportError.""" import statsmodels.api as sm + assert hasattr(sm, "OLS") assert len(dir(sm)) > 10 # Sanity check From 2331872ab11de99def07a4aa208bac612f796a7b Mon Sep 17 00:00:00 2001 From: Sebastian Cadavid Sanchez Date: Wed, 23 Jul 2025 14:01:25 -0500 Subject: [PATCH 3/3] Remove redundant unit test --- tests/test_statsmodels_scipy_compatibility.py | 99 ------------------- 1 file changed, 99 deletions(-) delete mode 100644 tests/test_statsmodels_scipy_compatibility.py diff --git a/tests/test_statsmodels_scipy_compatibility.py b/tests/test_statsmodels_scipy_compatibility.py deleted file mode 100644 index a3ca1c3f..00000000 --- a/tests/test_statsmodels_scipy_compatibility.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env python3 -""" -Compatibility test: statsmodels vs scipy - -This script verifies that statsmodels >= 0.14.5 is compatible with scipy >= 1.16.0, -resolving the import error caused by the removal of `_lazywhere` in scipy internals. - -Reference: -- statsmodels 0.14.5 release notes: https://github.com/statsmodels/statsmodels/releases/tag/v0.14.5 - -Usage: - python test_statsmodels_scipy_compatibility.py - pytest test_statsmodels_scipy_compatibility.py -""" - -import sys -import importlib - - -def check_versions(): - """Print installed versions of relevant packages.""" - print("Installed package versions:") - for pkg in ["scipy", "statsmodels", "numpy"]: - try: - mod = importlib.import_module(pkg) - print(f" {pkg:<12} {mod.__version__}") - except ImportError: - print(f" {pkg:<12} not installed") - print() - - -def test_statsmodels_import(): - """Ensure statsmodels can be imported and has expected version.""" - import statsmodels - - assert statsmodels.__version__ >= "0.14.5" - - -def test_statsmodels_api_import(): - """Ensure statsmodels.api can be imported without triggering ImportError.""" - import statsmodels.api as sm - - assert hasattr(sm, "OLS") - assert len(dir(sm)) > 10 # Sanity check - - -def test_problematic_modules(): - """Test modules previously affected by _lazywhere import failure.""" - problematic_modules = [ - "statsmodels.genmod._tweedie_compound_poisson", - "statsmodels.distributions.discrete", - ] - - for module_name in problematic_modules: - module = importlib.import_module(module_name) - assert module is not None - - -def run_cli_mode(): - """Run all tests manually in CLI mode with status output.""" - print("=" * 60) - print("Running statsmodels/scipy compatibility checks") - print("=" * 60) - check_versions() - - all_passed = True - - try: - test_statsmodels_import() - print("statsmodels import: PASSED") - except Exception as e: - print(f"statsmodels import: FAILED ({e})") - all_passed = False - - try: - test_statsmodels_api_import() - print("statsmodels.api import: PASSED") - except Exception as e: - print(f"statsmodels.api import: FAILED ({e})") - all_passed = False - - try: - test_problematic_modules() - print("problematic module imports: PASSED") - except Exception as e: - print(f"problematic module imports: FAILED ({e})") - all_passed = False - - print("=" * 60) - if all_passed: - print("All compatibility checks passed.") - sys.exit(0) - else: - print("One or more compatibility checks failed.") - sys.exit(1) - - -if __name__ == "__main__": - run_cli_mode()