Skip to content

Commit e1b222b

Browse files
authored
Python 3.11 support (#887)
1 parent b7b7ae1 commit e1b222b

11 files changed

+58
-66
lines changed

.github/workflows/run-operators-unit-tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
strategy:
2828
fail-fast: false
2929
matrix:
30-
python-version: ["3.8", "3.9", "3.10"]
30+
python-version: ["3.8", "3.9", "3.10", "3.11"]
3131

3232
steps:
3333
- uses: actions/checkout@v4

.github/workflows/run-unittests-default_setup.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: "[Py3.8][Py3.9][Py3.10] tests/unitary/default_setup/**"
1+
name: "[Py3.8-3.11] - Default Tests"
22

33
on:
44
workflow_dispatch:
@@ -33,7 +33,7 @@ jobs:
3333
strategy:
3434
fail-fast: false
3535
matrix:
36-
python-version: ["3.8", "3.9", "3.10"]
36+
python-version: ["3.8", "3.9", "3.10", "3.11"]
3737

3838
steps:
3939
- uses: actions/checkout@v4

.github/workflows/run-unittests-py38-cov-report.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: "[Py3.8][COV REPORT] tests/unitary/**"
1+
name: "[Py3.8][COV REPORT] - All Unit Tests"
22

33
on:
44
workflow_dispatch:
@@ -44,6 +44,7 @@ jobs:
4444
ignore-path: |
4545
--ignore tests/unitary/with_extras/model \
4646
--ignore tests/unitary/with_extras/feature_store \
47+
--ignore tests/unitary/with_extras/operator/feature-store \
4748
--ignore tests/unitary/with_extras/operator/forecast \
4849
--ignore tests/unitary/with_extras/hpo
4950
- name: "slow_tests"

.github/workflows/run-unittests-py39-py310.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: "[Py3.9][Py3.10] - tests/unitary/**"
1+
name: "[Py3.9-3.11] - All Unit Tests"
22

33
on:
44
workflow_dispatch:
@@ -33,7 +33,7 @@ jobs:
3333
strategy:
3434
fail-fast: false
3535
matrix:
36-
python-version: ["3.9", "3.10"]
36+
python-version: ["3.9", "3.10", "3.11"]
3737
name: ["unitary", "slow_tests"]
3838
include:
3939
- name: "unitary"
@@ -46,6 +46,7 @@ jobs:
4646
ignore-path: |
4747
--ignore tests/unitary/with_extras/model \
4848
--ignore tests/unitary/with_extras/feature_store \
49+
--ignore tests/unitary/with_extras/operator/feature-store \
4950
--ignore tests/unitary/with_extras/operator/forecast \
5051
--ignore tests/unitary/with_extras/operator/pii \
5152
--ignore tests/unitary/with_extras/hpo

.github/workflows/test-env-setup/action.yml

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ runs:
77
using: composite
88
steps:
99
- shell: bash
10+
env:
11+
# torch > v2.1.0 brings nvidia dependency by default, we want to install torch for cpu for tests.
12+
# Fot that --index-url https://download.pytorch.org/whl/cpu needed - https://pytorch.org/get-started/locally/.
13+
# Setting env variable here instead of flag --index-url (docs: https://pip.pypa.io/en/stable/cli/pip_install/):
14+
PIP_EXTRA_INDEX_URL: "https://download.pytorch.org/whl/cpu"
1015
run: |
1116
set -x # print commands that are executed
1217

.pre-commit-config.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
repos:
22
# ruff
33
- repo: https://github.com/astral-sh/ruff-pre-commit
4-
rev: v0.4.9
4+
rev: v0.5.0
55
hooks:
66
- id: ruff
77
types_or: [ python, pyi, jupyter ]
@@ -13,7 +13,7 @@ repos:
1313
exclude: ^docs/
1414
# Standard hooks
1515
- repo: https://github.com/pre-commit/pre-commit-hooks
16-
rev: v4.4.0
16+
rev: v4.6.0
1717
hooks:
1818
- id: check-ast
1919
exclude: ^docs/
@@ -42,7 +42,7 @@ repos:
4242
files: ^docs/
4343
# Hardcoded secrets and ocids detector
4444
- repo: https://github.com/gitleaks/gitleaks
45-
rev: v8.17.0
45+
rev: v8.18.4
4646
hooks:
4747
- id: gitleaks
4848
exclude: .github/workflows/reusable-actions/set-dummy-conf.yml

dev-requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Do not add test dependencies here. Use pyproject.toml [project.optional-dependencies] 'testsuite' section.
2+
# Reason - it is flexible to specify different version for specific python
13
-r test-requirements.txt
24
-e ".[aqua,bds,data,geo,huggingface,llm,notebook,onnx,opctl,optuna,spark,tensorflow,text,torch,viz]"
35
-e ".[testsuite]"

pyproject.toml

+33-19
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ classifiers = [
4848
"Programming Language :: Python :: 3.8",
4949
"Programming Language :: Python :: 3.9",
5050
"Programming Language :: Python :: 3.10",
51+
"Programming Language :: Python :: 3.11",
5152
]
5253

5354
# PEP 508 – Dependency specification for Python Software Packages - https://peps.python.org/pep-0508/
@@ -61,8 +62,8 @@ dependencies = [
6162
"fsspec>=0.8.7",
6263
"gitpython>=3.1.2",
6364
"jinja2>=2.11.2",
64-
"matplotlib>=3.1.3, <=3.8.4",
65-
"numpy>=1.19.2, <2.0.0",
65+
"matplotlib>=3.1.3,<=3.8.4",
66+
"numpy>=1.19.2,<2.0.0",
6667
"oci>=2.125.3",
6768
"ocifs>=1.1.3",
6869
"pandas>1.2.1; python_version<'3.9'", # starting pandas v2.1.0 requires-python = '>=3.9'
@@ -79,7 +80,7 @@ dependencies = [
7980
# Copied from extras_require list in setup.py, setup.py got removed in favor of this config file
8081
bds = ["hdfs[kerberos]", "ibis-framework[impala]", "sqlalchemy"]
8182
boosted = [
82-
"lightgbm<4.0.0", # relax when the official releases of skl2onnx (v1.16.0) and onnxmltools (1.11.3), https://github.com/sdpython/mlprodict/issues/488
83+
"lightgbm",
8384
"xgboost",
8485
]
8586
data = [
@@ -89,18 +90,24 @@ data = [
8990
"openpyxl>=3.0.7",
9091
"oracledb>=1.0",
9192
"pandavro>=1.6.0",
92-
"sqlalchemy>=1.4.1, <=1.4.46",
93+
"sqlalchemy>=1.4.1,<=1.4.46",
94+
]
95+
geo = [
96+
"geopandas<1.0.0", # in v1.0.0 removed the built-in dataset 'naturalearth_lowres', fix when relax version of geopandas needed
97+
"oracle_ads[viz]"
98+
]
99+
huggingface = [
100+
"transformers",
101+
"tf-keras" # Keras 3 installed in py3.11+, but this is not yet supported in Transformers. Need to install the backwards-compatible tf-keras
93102
]
94-
geo = ["geopandas", "oracle_ads[viz]"]
95-
huggingface = ["transformers"]
96103
notebook = ["ipython>=7.23.1, <8.0", "ipywidgets~=7.6.3"]
97104
onnx = [
98-
"lightgbm<4.0.0", # relax when the official releases of skl2onnx (v1.16.0) and onnxmltools (1.11.3), https://github.com/sdpython/mlprodict/issues/488
99-
"onnx>=1.12.0",
105+
"lightgbm",
106+
"onnx>=1.12.0,<=1.15.0", # v 1.15.0 set base on onnxrutime version and onnx opset support - https://onnxruntime.ai/docs/reference/compatibility.html#onnx-opset-support
100107
"onnxmltools>=1.10.0",
101-
"onnxruntime>=1.10.0,<1.16", # v1.16 introduced issues https://github.com/microsoft/onnxruntime/issues/17631, revealed by unit tests
108+
"onnxruntime~=1.17.0,!=1.16.0", # v1.17.0 used in Oracle Database 23ai; avoid v1.16 https://github.com/microsoft/onnxruntime/issues/17631, revealed by unit tests
102109
"oracle_ads[viz]",
103-
"protobuf<=3.20",
110+
"protobuf",
104111
"skl2onnx>=1.10.4",
105112
"tf2onnx",
106113
"xgboost<=1.7",
@@ -119,11 +126,21 @@ opctl = [
119126
]
120127
optuna = ["optuna==2.9.0", "oracle_ads[viz]"]
121128
spark = ["pyspark>=3.0.0"]
122-
tensorflow = ["oracle_ads[viz]", "tensorflow"]
123-
text = ["spacy", "wordcloud>=1.8.1"]
124-
torch = ["oracle_ads[viz]", "torch", "torchvision"]
129+
tensorflow = [
130+
"oracle_ads[viz]",
131+
"tensorflow<=2.15.1" # v2.16.1 with consequence on tf2onnx v1.16.1 (latest) has an issue with Keras 3 installed in py3.11+ (https://github.com/onnx/tensorflow-onnx/issues/2319)
132+
]
133+
text = [
134+
"spacy>=3.4.2", # the first version of spacy that supports python 3.11 is spacy v3.4.2
135+
"wordcloud>=1.8.1"
136+
]
137+
torch = [
138+
"oracle_ads[viz]",
139+
"torch",
140+
"torchvision"
141+
]
125142
viz = [
126-
"bokeh>=3.0.0, <3.2.0", # starting 3.2.0 bokeh not supporting python3.8; relax after ADS will drop py3.8 support
143+
"bokeh>=3.0.0,<3.2.0", # starting 3.2.0 bokeh not supporting python3.8; relax after ADS will drop py3.8 support
127144
"folium>=0.12.1",
128145
"graphviz<0.17",
129146
"scipy>=1.5.4",
@@ -182,13 +199,9 @@ aqua = ["jupyter_server"]
182199
# trying to use. Ref - https://pip.pypa.io/en/stable/topics/dependency-resolution/#possible-ways-to-reduce-backtracking.
183200
# Revisit this section continuously and update to recent version of libraries. focus on pyt3.9/3.10 versions.
184201
testsuite = [
185-
"dask==2023.5.0; python_version=='3.8'",
186-
"dask==2023.10.1; python_version>='3.9'", # oci-cli depends on click==8.0.4, dask>2023.10.1 depends on "click>=8.1"
187202
"arff",
188203
"category_encoders==2.6.3", # set version to avoid backtracking
189204
"cohere==4.53", # set version to avoid backtracking
190-
"dask==2023.10.1; python_version>='3.9'", # oci-cli depends on click==8.0.4, dask>2023.10.1 depends on "click>=8.1"
191-
"dask==2023.5.0; python_version=='3.8'",
192205
"faiss-cpu",
193206
"fastparquet==2024.2.0", # set version to avoid backtracking
194207
"imbalanced-learn",
@@ -199,10 +212,11 @@ testsuite = [
199212
"opensearch-py",
200213
"pdfplumber",
201214
"py4j",
202-
"pyarrow",
215+
"pyarrow>=15.0.0",
203216
"statsmodels; python_version=='3.8'",
204217
"statsmodels>=0.14.1; python_version>='3.9'", # cython3.0 compatibility added in v0.14.1
205218
"tables",
219+
"tables>3.9.0; python_version>='3.9'",
206220
"xlrd>=1.2.0",
207221
]
208222

test-requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Include here only libraries required to run test methods, like mock, pytest, coverage etc.
2+
# Add dependencies for ADS to pyproject.toml [project.optional-dependencies] 'testsuite' section.
13
-e .
24
click
35
coverage
@@ -8,5 +10,4 @@ pip
810
pytest
911
pytest-cov
1012
pytest-xdist
11-
kubernetes
1213
ruff

tests/unitary/default_setup/common/test_common_ADSData.py

+4-18
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
#!/usr/bin/env python
22

3-
# Copyright (c) 2021, 2023 Oracle and/or its affiliates.
3+
# Copyright (c) 2021, 2024 Oracle and/or its affiliates.
44
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
55

66
"""
77
Contains tests for ads.common.data
88
"""
9+
910
import os
1011
import pandas as pd
1112
import pytest
1213
import unittest
1314

1415
from ads.common.data import ADSData
1516

17+
1618
#
1719
# run with:
1820
# python -m pytest -v -p no:warnings --cov-config=.coveragerc --cov=./ --cov-report html /home/datascience/advanced-ds/tests/unitary/test_common_data_ADSData.py
@@ -112,7 +114,7 @@ def test_ADSData_build_bad_input(self):
112114
Test corner cases and error handling
113115
"""
114116
bad_input = [(None, None), ("test", None), (None, "test")]
115-
for (X, y) in bad_input:
117+
for X, y in bad_input:
116118
with pytest.raises(ValueError):
117119
ADSData.build(X, y)
118120

@@ -149,22 +151,6 @@ def test_ADSData_build_valid_input_using_target_vector(self):
149151
assert expected.y.name == "target"
150152
assert expected.y.shape == (3,)
151153

152-
@pytest.mark.skipif("NoDependency" in os.environ, reason="skip for dependency test")
153-
def test_ADSData_build_valid_input_dask_dataframe(self):
154-
"""
155-
Ensures build method takes dask dataframe
156-
"""
157-
import dask
158-
159-
X = dask.datasets.timeseries().drop("y", axis=1)
160-
y = dask.datasets.timeseries()["y"]
161-
expected = ADSData.build(X, y)
162-
assert sorted(expected.X.columns.tolist()) == sorted(["id", "name", "x"])
163-
assert expected.X.shape[0] == 2592000
164-
assert expected.X.shape[1] == 3
165-
assert expected.y.name == "y"
166-
assert expected.y.shape[0] == 2592000
167-
168154
@pytest.mark.skip("api change. this test should be re-written.")
169155
def test_ADSData_build_with_data(self):
170156
"""

tests/unitary/default_setup/feature_types/test_feature_domain_schema.py

+1-19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
22

3-
# Copyright (c) 2021, 2023 Oracle and/or its affiliates.
3+
# Copyright (c) 2021, 2024 Oracle and/or its affiliates.
44
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
55

66
import os
@@ -524,24 +524,6 @@ def test_populate_schema_list(self):
524524
self.model_artifact.populate_schema(X_sample=list(self.X))
525525
mock_warning.assert_called()
526526

527-
@pytest.mark.skipif("NoDependency" in os.environ, reason="skip for dependency test")
528-
def test_populate_schema_dask_tuple(self):
529-
import dask.dataframe as dd
530-
531-
self.model_artifact.populate_schema(
532-
X_sample=dd.from_array(self.X), y_sample=tuple(self.y)
533-
)
534-
assert isinstance(self.model_artifact.schema_input, Schema)
535-
assert isinstance(self.model_artifact.schema_output, Schema)
536-
537-
# Test wide data
538-
with patch.object(Schema, "validate_size", side_effect=SchemaSizeTooLarge(100)):
539-
with patch.object(logger, "warning") as mock_warning:
540-
self.model_artifact.populate_schema(
541-
X_sample=dd.from_array(self.X), y_sample=tuple(self.y)
542-
)
543-
mock_warning.assert_called()
544-
545527
def test_simple_constraint(self):
546528
self.df["sepal length (cm)"].ads.feature_type = ["category"]
547529
domain = self.df["sepal length (cm)"].ads.feature_domain()

0 commit comments

Comments
 (0)