Skip to content

Commit

Permalink
feat: numpy 2.0rc support (#651)
Browse files Browse the repository at this point in the history
* numpy 2.0rc support

* pep compliant specification

* typo

* extra requirement with matrix

* add marker info
  • Loading branch information
FBruzzesi authored Apr 20, 2024
1 parent 35dd279 commit 8cabda3
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 25 deletions.
35 changes: 31 additions & 4 deletions .github/workflows/schedule-dependencies.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:


jobs:
cron:
cron-base:
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -30,9 +30,36 @@ jobs:
- name: Install dependencies
run: |
uv pip install wheel --system
uv pip install ${{ matrix.pre-release-dependencies }} scikit-lego --system
uv pip install ${{ matrix.pre-release-dependencies }} --system -e ".[test-dep]"
uv pip freeze
- name: Test with pytest
run: pytest -n auto --disable-warnings --cov=sklego -m "not cvxpy and not formulaic and not umap"

cron-extra:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.10"]
os: [macos-latest, ubuntu-latest, windows-latest]
pre-release-dependencies: ["--pre", ""]
extra: ["cvxpy", "formulaic", "umap"]
steps:
- name: Checkout source code
uses: actions/checkout@v4
- name: Install uv (Unix)
if: runner.os != 'Windows'
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Install uv (Windows)
if: runner.os == 'Windows'
run: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
uv pip install -e ".[test]" --system
make test
uv pip install wheel --system
uv pip install ${{ matrix.pre-release-dependencies }} -e ".[test-dep,${{ matrix.extra }}]" --system
uv pip freeze
- name: Test with pytest
run: pytest -n auto --disable-warnings --cov=sklego -m "${{ matrix.extra }}"
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv pip install -e ".[test]" --system
run: uv pip install -e ".[test-all]" --system
- name: Test with pytest
run: make test
16 changes: 11 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ issue-tracker = "https://github.com/koaning/scikit-lego/issues"
documentation = "https://koaning.github.io/scikit-lego/"

[project.optional-dependencies]
cvxpy = ["cmake", "osqp", "cvxpy>=1.1.8"]
cvxpy = ["cmake", "osqp", "cvxpy>=1.1.8", "numpy<2.0"]
formulaic = ["formulaic>=0.6.0"]
umap = ["umap-learn>=0.4.6"]
umap = ["umap-learn>=0.4.6", "numpy<2.0"]

all = ["scikit-lego[cvxpy,formulaic,umap]"]

Expand All @@ -60,14 +60,17 @@ docs = [
"mkdocstrings-python>=1.7.3",
]

test = [
"scikit-lego[all]",
test-dep = [
"pytest>=6.2.5",
"pytest-xdist>=1.34.0",
"pytest-cov>=2.6.1",
"pytest-mock>=1.6.3",
]

test-all = [
"scikit-lego[all,test-dep]",
]

utils = [
"matplotlib>=3.0.2",
"jupyter>=1.0.0",
Expand Down Expand Up @@ -104,5 +107,8 @@ ignore = [

[tool.pytest.ini_options]
markers = [
"cvxpy: tests that require cvxpy (deselect with '-m \"not cvxpy\"')"
"cvxpy: tests that require cvxpy (deselect with '-m \"not cvxpy\"')",
"formulaic: tests that require formulaic (deselect with '-m \"not formulaic\"')",
"umap: tests that require umap (deselect with '-m \"not umap\"')"
]

2 changes: 1 addition & 1 deletion sklego/meta/_shrinkage_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def _set_shrinkage_function(self):

def no_shrinkage_function(x):
n = len(self.fitted_levels_[-1])
return np.lib.pad([1], (len(x) - 1, n - len(x)), "constant", constant_values=(0))
return np.pad([1], (len(x) - 1, n - len(x)), "constant", constant_values=(0))

shrinkage_function_ = no_shrinkage_function

Expand Down
2 changes: 1 addition & 1 deletion sklego/meta/hierarchical_predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ def _predict_estimators(self, X, method_name):
raw_pred = getattr(_estimator, method_name)(grp_frame.drop(columns=self.groups_))

preds[np.ix_(grp_idx, [level_idx], last_dim_ix)] = np.atleast_3d(raw_pred[:, None])
shrinkage[np.ix_(grp_idx)] = np.lib.pad(
shrinkage[np.ix_(grp_idx)] = np.pad(
_shrinkage_factor, (0, self.n_levels_ - len(_shrinkage_factor)), "constant", constant_values=(0)
)

Expand Down
2 changes: 1 addition & 1 deletion sklego/pandas_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ def _add_lagged_numpy_columns(X, cols, lags, drop_na):
if not all([col < X.shape[1] for col in cols]):
raise KeyError("The column does not exist")

combos = (shift(X[:, col], -lag, cval=np.NaN) for col in cols for lag in lags)
combos = (shift(X[:, col], -lag, cval=np.nan) for col in cols for lag in lags)

# In integer-based ndarrays, NaN values are represented as
# -9223372036854775808, so we convert back and forth from
Expand Down
7 changes: 2 additions & 5 deletions tests/test_estimators/test_demographic_parity.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from sklego.metrics import p_percent_score
from tests.conftest import classifier_checks, general_checks, nonmeta_checks, select_tests

pytestmark = pytest.mark.cvxpy


@pytest.mark.parametrize(
"test_fn",
Expand All @@ -20,7 +22,6 @@
exclude=["check_sample_weights_invariance", "check_sample_weights_list", "check_sample_weights_pandas_series"],
),
)
@pytest.mark.cvxpy
def test_standard_checks(test_fn):
trf = DemographicParityClassifier(
covariance_threshold=None,
Expand Down Expand Up @@ -70,7 +71,6 @@ def _test_same(dataset):
assert np.sum(lr.predict(X_without_sens) != fair.predict(X)) / len(X) < 0.01


@pytest.mark.cvxpy
def test_same_logistic(random_xy_dataset_clf):
"""
Tests whether the fair classifier performs similar to logistic regression
Expand All @@ -80,7 +80,6 @@ def test_same_logistic(random_xy_dataset_clf):
_test_same(random_xy_dataset_clf)


@pytest.mark.cvxpy
def test_same_logistic_multiclass(random_xy_dataset_multiclf):
"""
Tests whether the fair classifier performs similar to logistic regression
Expand All @@ -90,7 +89,6 @@ def test_same_logistic_multiclass(random_xy_dataset_multiclf):
_test_same(random_xy_dataset_multiclf)


@pytest.mark.cvxpy
def test_regularization(sensitive_classification_dataset):
"""Tests whether increasing regularization decreases the norm of the coefficient vector"""
X, y = sensitive_classification_dataset
Expand All @@ -103,7 +101,6 @@ def test_regularization(sensitive_classification_dataset):
prev_theta_norm = theta_norm


@pytest.mark.cvxpy
def test_fairness(sensitive_classification_dataset):
"""tests whether fairness (measured by p percent score) increases as we decrease the covariance threshold"""
X, y = sensitive_classification_dataset
Expand Down
7 changes: 2 additions & 5 deletions tests/test_estimators/test_equal_opportunity.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from sklego.metrics import equal_opportunity_score
from tests.conftest import classifier_checks, general_checks, nonmeta_checks, select_tests

pytestmark = pytest.mark.cvxpy


@pytest.mark.parametrize(
"test_fn",
Expand All @@ -15,7 +17,6 @@
exclude=["check_sample_weights_invariance", "check_sample_weights_list", "check_sample_weights_pandas_series"],
),
)
@pytest.mark.cvxpy
def test_standard_checks(test_fn):
trf = EqualOpportunityClassifier(
covariance_threshold=None,
Expand Down Expand Up @@ -69,7 +70,6 @@ def _test_same(dataset):
assert np.sum(lr.predict(X_without_sens) != fair.predict(X)) / len(X) < 0.01


@pytest.mark.cvxpy
def test_same_logistic(random_xy_dataset_clf):
"""
Tests whether the fair classifier performs similar to logistic regression
Expand All @@ -79,7 +79,6 @@ def test_same_logistic(random_xy_dataset_clf):
_test_same(random_xy_dataset_clf)


@pytest.mark.cvxpy
def test_same_logistic_multiclass(random_xy_dataset_multiclf):
"""
Tests whether the fair classifier performs similar to logistic regression
Expand All @@ -89,7 +88,6 @@ def test_same_logistic_multiclass(random_xy_dataset_multiclf):
_test_same(random_xy_dataset_multiclf)


@pytest.mark.cvxpy
def test_regularization(sensitive_classification_dataset):
"""Tests whether increasing regularization decreases the norm of the coefficient vector"""
X, y = sensitive_classification_dataset
Expand All @@ -104,7 +102,6 @@ def test_regularization(sensitive_classification_dataset):
prev_theta_norm = theta_norm


@pytest.mark.cvxpy
def test_fairness(sensitive_classification_dataset):
"""tests whether fairness (measured by p percent score) increases as we decrease the covariance threshold"""
X, y = sensitive_classification_dataset
Expand Down
4 changes: 2 additions & 2 deletions tests/test_estimators/test_probweight_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from sklego.linear_model import ProbWeightRegression
from tests.conftest import general_checks, nonmeta_checks, regressor_checks, select_tests

pytestmark = pytest.mark.cvxpy


@pytest.mark.parametrize(
"test_fn",
Expand All @@ -13,15 +15,13 @@
exclude=["check_sample_weights_invariance", "check_sample_weights_list", "check_sample_weights_pandas_series"],
),
)
@pytest.mark.cvxpy
def test_estimator_checks(test_fn):
regr_min_zero = ProbWeightRegression(non_negative=True)
test_fn(ProbWeightRegression.__name__ + "_min_zero_true", regr_min_zero)
regr_not_min_zero = ProbWeightRegression(non_negative=False)
test_fn(ProbWeightRegression.__name__ + "_min_zero_true_false", regr_not_min_zero)


@pytest.mark.cvxpy
def test_shape_trained_model(random_xy_dataset_regr):
X, y = random_xy_dataset_regr
mod_no_intercept = ProbWeightRegression()
Expand Down
2 changes: 2 additions & 0 deletions tests/test_estimators/test_umap_reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from sklego.decomposition import UMAPOutlierDetection
from tests.conftest import general_checks, nonmeta_checks, outlier_checks, select_tests

pytestmark = pytest.mark.umap


@pytest.mark.parametrize(
"test_fn",
Expand Down
2 changes: 2 additions & 0 deletions tests/test_preprocessing/test_formulaic_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

from sklego.preprocessing import FormulaicTransformer

pytestmark = pytest.mark.formulaic


@pytest.fixture()
def df():
Expand Down
2 changes: 2 additions & 0 deletions tests/test_preprocessing/test_interval_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from sklego.preprocessing import IntervalEncoder
from tests.conftest import general_checks, transformer_checks

pytestmark = pytest.mark.cvxpy


@pytest.mark.parametrize(
"test_fn",
Expand Down

0 comments on commit 8cabda3

Please sign in to comment.