Skip to content

Commit f0d6889

Browse files
committed
Merge branch 'main' into pr/1606
2 parents f1e7a3c + c5f68bf commit f0d6889

26 files changed

+233
-142
lines changed

.github/workflows/dist.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- name: Setup Python
2828
uses: actions/setup-python@v5
2929
with:
30-
python-version: 3.8
30+
python-version: "3.10"
3131
- name: Build dist
3232
run: |
3333
pip install build

.github/workflows/docs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Setup Python
2929
uses: actions/setup-python@v5
3030
with:
31-
python-version: 3.8
31+
python-version: "3.10"
3232
- name: Install dependencies
3333
run: |
3434
pip install -e .[docs,examples]

.github/workflows/test.yml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---
12
name: Tests
23

34
on:
@@ -21,13 +22,13 @@ concurrency:
2122

2223
jobs:
2324
test:
24-
name: (${{ matrix.os }}, Py${{ matrix.python-version }}, sk${{ matrix.scikit-learn }}, sk-only:${{ matrix.sklearn-only }})
25+
name: (${{ matrix.os }},Py${{ matrix.python-version }},sk${{ matrix.scikit-learn }},sk-only:${{ matrix.sklearn-only }})
2526
runs-on: ${{ matrix.os }}
2627

2728
strategy:
2829
fail-fast: false
2930
matrix:
30-
python-version: ["3.10", "3.11", "3.12", "3.13"]
31+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
3132
scikit-learn: ["1.3.*", "1.4.*", "1.5.*", "1.6.*", "1.7.*"]
3233
os: [ubuntu-latest]
3334
sklearn-only: ["true"]
@@ -38,8 +39,18 @@ jobs:
3839
scikit-learn: "1.3.*"
3940
- python-version: "3.13"
4041
scikit-learn: "1.4.*"
42+
- python-version: "3.14"
43+
scikit-learn: "1.3.*"
44+
- python-version: "3.14"
45+
scikit-learn: "1.4.*"
4146

4247
include:
48+
# Full test run on ubuntu, 3.14
49+
- os: ubuntu-latest
50+
python-version: "3.14"
51+
scikit-learn: "1.7.*"
52+
sklearn-only: "false"
53+
4354
# Full test run on Windows
4455
- os: windows-latest
4556
python-version: "3.12"
@@ -87,9 +98,9 @@ jobs:
8798
fi
8899
89100
if [ "${{ matrix.sklearn-only }}" = "true" ]; then
90-
marks="sklearn and not production"
101+
marks="sklearn and not production and not uses_test_server"
91102
else
92-
marks="not production"
103+
marks="not production and not uses_test_server"
93104
fi
94105
95106
pytest -n 4 --durations=20 --dist load -sv $codecov -o log_cli=true -m "$marks"
@@ -102,17 +113,17 @@ jobs:
102113
fi
103114
104115
if [ "${{ matrix.sklearn-only }}" = "true" ]; then
105-
marks="sklearn and production"
116+
marks="sklearn and production and not uses_test_server"
106117
else
107-
marks="production"
118+
marks="production and not uses_test_server"
108119
fi
109120
110121
pytest -n 4 --durations=20 --dist load -sv $codecov -o log_cli=true -m "$marks"
111122
112123
- name: Run tests on Windows
113124
if: matrix.os == 'windows-latest'
114125
run: | # we need a separate step because of the bash-specific if-statement in the previous one.
115-
pytest -n 4 --durations=20 --dist load -sv --reruns 5 --reruns-delay 1
126+
pytest -n 4 --durations=20 --dist load -sv --reruns 5 --reruns-delay 1 -m "not uses_test_server"
116127
117128
- name: Check for files left behind by test
118129
if: matrix.os != 'windows-latest' && always()

.gitignore

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,17 @@ dmypy.sock
9898

9999
# Tests
100100
.pytest_cache
101+
102+
# Virtual environments
103+
oenv/
104+
venv/
105+
.env/
101106
.venv
107+
.venv/
108+
109+
# Python cache
110+
__pycache__/
111+
*.pyc
102112

103113
# Ruff
104-
.ruff-cache/
114+
.ruff-cache/

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
## The Python API for a World of Data and More :dizzy:
1616

1717
[![Latest Release](https://img.shields.io/github/v/release/openml/openml-python)](https://github.com/openml/openml-python/releases)
18-
[![Python Versions](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://pypi.org/project/openml/)
18+
[![Python Versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://pypi.org/project/openml/)
1919
[![Downloads](https://static.pepy.tech/badge/openml)](https://pepy.tech/project/openml)
2020
[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
2121
<!-- Add green badges for CI and precommit -->
@@ -60,7 +60,7 @@ for task_id in suite.tasks:
6060

6161
## :magic_wand: Installation
6262

63-
OpenML-Python is supported on Python 3.8 - 3.13 and is available on Linux, MacOS, and Windows.
63+
OpenML-Python is supported on Python 3.10 - 3.14 and is available on Linux, MacOS, and Windows.
6464

6565
You can install OpenML-Python with:
6666

openml/evaluations/evaluation.py

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
# License: BSD 3-Clause
22
from __future__ import annotations
33

4+
from dataclasses import asdict, dataclass
5+
46
import openml.config
57
import openml.datasets
68
import openml.flows
79
import openml.runs
810
import openml.tasks
911

1012

11-
# TODO(eddiebergman): A lot of this class is automatically
12-
# handled by a dataclass
13+
@dataclass
1314
class OpenMLEvaluation:
1415
"""
1516
Contains all meta-information about a run / evaluation combination,
@@ -48,55 +49,23 @@ class OpenMLEvaluation:
4849
(e.g., in case of precision, auroc, recall)
4950
"""
5051

51-
def __init__( # noqa: PLR0913
52-
self,
53-
run_id: int,
54-
task_id: int,
55-
setup_id: int,
56-
flow_id: int,
57-
flow_name: str,
58-
data_id: int,
59-
data_name: str,
60-
function: str,
61-
upload_time: str,
62-
uploader: int,
63-
uploader_name: str,
64-
value: float | None,
65-
values: list[float] | None,
66-
array_data: str | None = None,
67-
):
68-
self.run_id = run_id
69-
self.task_id = task_id
70-
self.setup_id = setup_id
71-
self.flow_id = flow_id
72-
self.flow_name = flow_name
73-
self.data_id = data_id
74-
self.data_name = data_name
75-
self.function = function
76-
self.upload_time = upload_time
77-
self.uploader = uploader
78-
self.uploader_name = uploader_name
79-
self.value = value
80-
self.values = values
81-
self.array_data = array_data
52+
run_id: int
53+
task_id: int
54+
setup_id: int
55+
flow_id: int
56+
flow_name: str
57+
data_id: int
58+
data_name: str
59+
function: str
60+
upload_time: str
61+
uploader: int
62+
uploader_name: str
63+
value: float | None
64+
values: list[float] | None
65+
array_data: str | None = None
8266

8367
def _to_dict(self) -> dict:
84-
return {
85-
"run_id": self.run_id,
86-
"task_id": self.task_id,
87-
"setup_id": self.setup_id,
88-
"flow_id": self.flow_id,
89-
"flow_name": self.flow_name,
90-
"data_id": self.data_id,
91-
"data_name": self.data_name,
92-
"function": self.function,
93-
"upload_time": self.upload_time,
94-
"uploader": self.uploader,
95-
"uploader_name": self.uploader_name,
96-
"value": self.value,
97-
"values": self.values,
98-
"array_data": self.array_data,
99-
}
68+
return asdict(self)
10069

10170
def __repr__(self) -> str:
10271
header = "OpenML Evaluation"
@@ -119,11 +88,12 @@ def __repr__(self) -> str:
11988
}
12089

12190
order = [
122-
"Uploader Date",
91+
"Upload Date",
12392
"Run ID",
12493
"OpenML Run URL",
12594
"Task ID",
126-
"OpenML Task URL" "Flow ID",
95+
"OpenML Task URL",
96+
"Flow ID",
12797
"OpenML Flow URL",
12898
"Setup ID",
12999
"Data ID",

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ dependencies = [
2121
"pyarrow",
2222
"tqdm", # For MinIO download progress bars
2323
]
24-
requires-python = ">=3.8"
24+
requires-python = ">=3.10,<3.15"
2525
maintainers = [
2626
{ name = "Pieter Gijsbers", email="p.gijsbers@tue.nl"},
2727
{ name = "Lennart Purucker"},

tests/test_datasets/test_dataset.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ def test_equality_comparison(self):
278278
self.assertNotEqual(self.titanic, "Wrong_object")
279279

280280

281+
@pytest.mark.uses_test_server()
281282
def test_tagging():
282283
dataset = openml.datasets.get_dataset(125, download_data=False)
283284

@@ -294,7 +295,7 @@ def test_tagging():
294295
datasets = openml.datasets.list_datasets(tag=tag)
295296
assert datasets.empty
296297

297-
@pytest.mark.xfail(reason="failures_issue_1544")
298+
@pytest.mark.uses_test_server()
298299
def test_get_feature_with_ontology_data_id_11():
299300
# test on car dataset, which has built-in ontology references
300301
dataset = openml.datasets.get_dataset(11)
@@ -303,13 +304,15 @@ def test_get_feature_with_ontology_data_id_11():
303304
assert len(dataset.features[2].ontologies) >= 1
304305
assert len(dataset.features[3].ontologies) >= 1
305306

307+
@pytest.mark.uses_test_server()
306308
def test_add_remove_ontology_to_dataset():
307309
did = 1
308310
feature_index = 1
309311
ontology = "https://www.openml.org/unittest/" + str(time())
310312
openml.datasets.functions.data_feature_add_ontology(did, feature_index, ontology)
311313
openml.datasets.functions.data_feature_remove_ontology(did, feature_index, ontology)
312314

315+
@pytest.mark.uses_test_server()
313316
def test_add_same_ontology_multiple_features():
314317
did = 1
315318
ontology = "https://www.openml.org/unittest/" + str(time())
@@ -318,6 +321,7 @@ def test_add_same_ontology_multiple_features():
318321
openml.datasets.functions.data_feature_add_ontology(did, i, ontology)
319322

320323

324+
@pytest.mark.uses_test_server()
321325
def test_add_illegal_long_ontology():
322326
did = 1
323327
ontology = "http://www.google.com/" + ("a" * 257)
@@ -329,6 +333,7 @@ def test_add_illegal_long_ontology():
329333

330334

331335

336+
@pytest.mark.uses_test_server()
332337
def test_add_illegal_url_ontology():
333338
did = 1
334339
ontology = "not_a_url" + str(time())
@@ -400,6 +405,7 @@ def test_get_sparse_categorical_data_id_395(self):
400405
assert len(feature.nominal_values) == 25
401406

402407

408+
@pytest.mark.uses_test_server()
403409
def test__read_features(mocker, workdir, static_cache_dir):
404410
"""Test we read the features from the xml if no cache pickle is available.
405411
This test also does some simple checks to verify that the features are read correctly
@@ -431,6 +437,7 @@ def test__read_features(mocker, workdir, static_cache_dir):
431437
assert pickle_mock.dump.call_count == 1
432438

433439

440+
@pytest.mark.uses_test_server()
434441
def test__read_qualities(static_cache_dir, workdir, mocker):
435442
"""Test we read the qualities from the xml if no cache pickle is available.
436443
This test also does some minor checks to ensure that the qualities are read correctly.

0 commit comments

Comments
 (0)