Skip to content

Commit bd8ae77

Browse files
authored
[MNT] extend CI to newer python versions, deprecate python versions 3.8, 3.9 after EOL, marking further failing tests as xfail (#1579)
The CI runs only on python versions 3.8 and 3.9 both of which have already reached end of life. This PR updates the python versions, deprecating any logic that runs tests on python versions 3.8 and 3.9, or `scikit-learn` versions of that age. #### Metadata Reference Issue: #1544 Depends on #1584 fofr a fix, which should be merged first. #### Details * The test matrix is updated to python versions, 3.10-3.13. * Further failing tests are skipped using `mark.xfail` with `reason="failures_issue_1544" ` for all the remaining failed tests (after #1572) in issue: #1544
1 parent 6e78858 commit bd8ae77

8 files changed

Lines changed: 69 additions & 34 deletions

File tree

.github/workflows/test.yml

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,74 +23,97 @@ jobs:
2323
test:
2424
name: (${{ matrix.os }}, Py${{ matrix.python-version }}, sk${{ matrix.scikit-learn }}, sk-only:${{ matrix.sklearn-only }})
2525
runs-on: ${{ matrix.os }}
26+
2627
strategy:
28+
fail-fast: false
2729
matrix:
28-
python-version: ["3.11"]
29-
scikit-learn: ["1.3.*", "1.4.*", "1.5.*"]
30+
python-version: ["3.10", "3.11", "3.12", "3.13"]
31+
scikit-learn: ["1.3.*", "1.4.*", "1.5.*", "1.6.*", "1.7.*"]
3032
os: [ubuntu-latest]
3133
sklearn-only: ["true"]
32-
fail-fast: false
34+
35+
exclude:
36+
# incompatible version combinations
37+
- python-version: "3.13"
38+
scikit-learn: "1.3.*"
39+
- python-version: "3.13"
40+
scikit-learn: "1.4.*"
41+
42+
include:
43+
# Full test run on Windows
44+
- os: windows-latest
45+
python-version: "3.12"
46+
scikit-learn: "1.5.*"
47+
sklearn-only: "false"
48+
49+
# Coverage run
50+
- os: ubuntu-latest
51+
python-version: "3.12"
52+
scikit-learn: "1.5.*"
53+
sklearn-only: "false"
54+
code-cov: true
3355

3456
steps:
3557
- uses: actions/checkout@v6
3658
with:
3759
fetch-depth: 2
60+
3861
- name: Setup Python ${{ matrix.python-version }}
39-
if: matrix.os != 'windows-latest' # windows-latest only uses preinstalled Python (3.9.13)
4062
uses: actions/setup-python@v5
4163
with:
4264
python-version: ${{ matrix.python-version }}
43-
- name: Install test dependencies
65+
66+
- name: Install test dependencies and scikit-learn
4467
run: |
4568
python -m pip install --upgrade pip
46-
pip install -e .[test]
47-
- name: Install scikit-learn ${{ matrix.scikit-learn }}
48-
run: |
49-
pip install scikit-learn==${{ matrix.scikit-learn }}
50-
- name: Install numpy for Python 3.8
51-
# Python 3.8 & scikit-learn<0.24 requires numpy<=1.23.5
52-
if: ${{ matrix.python-version == '3.8' && matrix.scikit-learn == '0.23.1' }}
53-
run: |
54-
pip install numpy==1.23.5
55-
- name: "Install NumPy 1.x and SciPy <1.11 for scikit-learn < 1.4"
56-
if: ${{ contains(fromJSON('["1.0.*", "1.1.*", "1.2.*", "1.3.*"]'), matrix.scikit-learn) }}
57-
run: |
58-
# scipy has a change to the 'mode' behavior which breaks scikit-learn < 1.4
59-
# numpy 2.0 has several breaking changes
60-
pip install "numpy<2.0" "scipy<1.11"
61-
- name: Install scipy ${{ matrix.scipy }}
62-
if: ${{ matrix.scipy }}
63-
run: |
64-
pip install scipy==${{ matrix.scipy }}
69+
pip install -e .[test] scikit-learn==${{ matrix.scikit-learn }}
70+
6571
- name: Store repository status
6672
id: status-before
6773
if: matrix.os != 'windows-latest'
6874
run: |
6975
git_status=$(git status --porcelain -b)
7076
echo "BEFORE=$git_status" >> $GITHUB_ENV
7177
echo "Repository status before tests: $git_status"
78+
7279
- name: Show installed dependencies
7380
run: python -m pip list
81+
7482
- name: Run tests on Ubuntu Test
7583
if: matrix.os == 'ubuntu-latest'
7684
run: |
77-
if [ ${{ matrix.code-cov }} ]; then codecov='--cov=openml --long --cov-report=xml'; fi
78-
# Most of the time, running only the scikit-learn tests is sufficient
79-
if [ ${{ matrix.sklearn-only }} = 'true' ]; then marks='sklearn and not production'; else marks='not production'; fi
80-
echo pytest -n 4 --durations=20 --dist load -sv $codecov -o log_cli=true -m "$marks"
85+
if [ "${{ matrix.code-cov }}" = "true" ]; then
86+
codecov="--cov=openml --long --cov-report=xml"
87+
fi
88+
89+
if [ "${{ matrix.sklearn-only }}" = "true" ]; then
90+
marks="sklearn and not production"
91+
else
92+
marks="not production"
93+
fi
94+
8195
pytest -n 4 --durations=20 --dist load -sv $codecov -o log_cli=true -m "$marks"
96+
8297
- name: Run tests on Ubuntu Production
8398
if: matrix.os == 'ubuntu-latest'
8499
run: |
85-
if [ ${{ matrix.code-cov }} ]; then codecov='--cov=openml --long --cov-report=xml'; fi
86-
# Most of the time, running only the scikit-learn tests is sufficient
87-
if [ ${{ matrix.sklearn-only }} = 'true' ]; then marks='sklearn and production'; else marks='production'; fi
88-
echo pytest -n 4 --durations=20 --dist load -sv $codecov -o log_cli=true -m "$marks"
100+
if [ "${{ matrix.code-cov }}" = "true" ]; then
101+
codecov="--cov=openml --long --cov-report=xml"
102+
fi
103+
104+
if [ "${{ matrix.sklearn-only }}" = "true" ]; then
105+
marks="sklearn and production"
106+
else
107+
marks="production"
108+
fi
109+
89110
pytest -n 4 --durations=20 --dist load -sv $codecov -o log_cli=true -m "$marks"
111+
90112
- name: Run tests on Windows
91113
if: matrix.os == 'windows-latest'
92114
run: | # we need a separate step because of the bash-specific if-statement in the previous one.
93115
pytest -n 4 --durations=20 --dist load -sv --reruns 5 --reruns-delay 1
116+
94117
- name: Check for files left behind by test
95118
if: matrix.os != 'windows-latest' && always()
96119
run: |
@@ -102,6 +125,7 @@ jobs:
102125
echo "Not all generated files have been deleted!"
103126
exit 1
104127
fi
128+
105129
- name: Upload coverage
106130
if: matrix.code-cov && always()
107131
uses: codecov/codecov-action@v4

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,11 @@ classifiers = [
5050
"Operating System :: Unix",
5151
"Operating System :: MacOS",
5252
"Programming Language :: Python :: 3",
53-
"Programming Language :: Python :: 3.8",
54-
"Programming Language :: Python :: 3.9",
5553
"Programming Language :: Python :: 3.10",
5654
"Programming Language :: Python :: 3.11",
5755
"Programming Language :: Python :: 3.12",
5856
"Programming Language :: Python :: 3.13",
57+
"Programming Language :: Python :: 3.14",
5958
]
6059
license = { file = "LICENSE" }
6160

tests/test_runs/test_run_functions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ def _run_and_upload_regression(
625625
sentinel=sentinel,
626626
)
627627

628+
@pytest.mark.skip(reason="failures_issue_1544")
628629
@pytest.mark.sklearn()
629630
def test_run_and_upload_logistic_regression(self):
630631
lr = LogisticRegression(solver="lbfgs", max_iter=1000)
@@ -633,6 +634,7 @@ def test_run_and_upload_logistic_regression(self):
633634
n_test_obs = self.TEST_SERVER_TASK_SIMPLE["n_test_obs"]
634635
self._run_and_upload_classification(lr, task_id, n_missing_vals, n_test_obs, "62501")
635636

637+
@pytest.mark.skip(reason="failures_issue_1544")
636638
@pytest.mark.sklearn()
637639
def test_run_and_upload_linear_regression(self):
638640
lr = LinearRegression()
@@ -663,6 +665,7 @@ def test_run_and_upload_linear_regression(self):
663665
n_test_obs = self.TEST_SERVER_TASK_REGRESSION["n_test_obs"]
664666
self._run_and_upload_regression(lr, task_id, n_missing_vals, n_test_obs, "62501")
665667

668+
@pytest.mark.skip(reason="failures_issue_1544")
666669
@pytest.mark.sklearn()
667670
def test_run_and_upload_pipeline_dummy_pipeline(self):
668671
pipeline1 = Pipeline(
@@ -676,6 +679,7 @@ def test_run_and_upload_pipeline_dummy_pipeline(self):
676679
n_test_obs = self.TEST_SERVER_TASK_SIMPLE["n_test_obs"]
677680
self._run_and_upload_classification(pipeline1, task_id, n_missing_vals, n_test_obs, "62501")
678681

682+
@pytest.mark.skip(reason="failures_issue_1544")
679683
@pytest.mark.sklearn()
680684
@unittest.skipIf(
681685
Version(sklearn.__version__) < Version("0.20"),
@@ -740,6 +744,7 @@ def get_ct_cf(nominal_indices, numeric_indices):
740744
sentinel=sentinel,
741745
)
742746

747+
@pytest.mark.skip(reason="failures_issue_1544")
743748
@pytest.mark.sklearn()
744749
@unittest.skip("https://github.com/openml/OpenML/issues/1180")
745750
@unittest.skipIf(
@@ -792,6 +797,7 @@ def test_run_and_upload_knn_pipeline(self, warnings_mock):
792797
call_count += 1
793798
assert call_count == 3
794799

800+
@pytest.mark.skip(reason="failures_issue_1544")
795801
@pytest.mark.sklearn()
796802
def test_run_and_upload_gridsearch(self):
797803
estimator_name = (
@@ -847,6 +853,7 @@ def test_run_and_upload_randomsearch(self):
847853
trace = openml.runs.get_run_trace(run.run_id)
848854
assert len(trace.trace_iterations) == 5
849855

856+
@pytest.mark.skip(reason="failures_issue_1544")
850857
@pytest.mark.sklearn()
851858
def test_run_and_upload_maskedarrays(self):
852859
# This testcase is important for 2 reasons:

tests/test_tasks/test_learning_curve_task.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from __future__ import annotations
33

44
import pandas as pd
5+
import pytest
56

67
from openml.tasks import TaskType, get_task
78

tests/test_tasks/test_regression_task.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import ast
55

66
import pandas as pd
7+
import pytest
78

89
import openml
910
from openml.exceptions import OpenMLServerException

tests/test_tasks/test_supervised_task.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pandas as pd
77

88
from openml.tasks import get_task
9+
import pytest
910

1011
from .test_task import OpenMLTaskTest
1112

tests/test_tasks/test_task_functions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ def test_get_task_lazy(self):
174174
)
175175

176176
@mock.patch("openml.tasks.functions.get_dataset")
177+
@pytest.mark.xfail(reason="failures_issue_1544")
177178
def test_removal_upon_download_failure(self, get_dataset):
178179
class WeirdException(Exception):
179180
pass

tests/test_tasks/test_task_methods.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import openml
77
from openml.testing import TestBase
8+
import pytest
89

910

1011
# Common methods between tasks

0 commit comments

Comments
 (0)