Skip to content

Commit

Permalink
Add future warnings about breaking changes in 3.0.0 (#765)
Browse files Browse the repository at this point in the history
* add future warnings on breaking changes in 3.0.0

* remove rogue comma

* adjust warning filter in test

* format the warnings properly

* temporarily skip warning test for criteria

* remove outdated line

* Only warn when using deprecated behavior

---------

Co-authored-by: Martin Stancsics <[email protected]>
  • Loading branch information
MatthiasSchmidtblaicherQC and stanmart authored Feb 16, 2024
1 parent 461de0f commit 96e6534
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Unreleased
- Require Python>=3.9 in line with `NEP 29 <https://numpy.org/neps/nep-0029-deprecation_policy.html#support-table>`_
- Build and test with Python 3.12 in CI.
- Added line search stopping criterion for tiny loss improvements based on gradient information.
- Added warnings about breaking changes in future versions.

2.6.0 - 2023-09-05
------------------
Expand Down
16 changes: 15 additions & 1 deletion src/glum/_glm.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
_least_squares_solver,
_trust_constr_solver,
)
from ._util import _align_df_categories, _safe_toarray
from ._util import _align_df_categories, _positional_args_deprecated, _safe_toarray

_float_itemsize_to_dtype = {8: np.float64, 4: np.float32, 2: np.float16}

Expand Down Expand Up @@ -1118,6 +1118,7 @@ def _solve_regularization_path(

return self.coef_path_

@_positional_args_deprecated()
def report_diagnostics(
self, full_report: bool = False, custom_columns: Optional[Iterable] = None
) -> None:
Expand All @@ -1144,6 +1145,7 @@ def report_diagnostics(
with pd.option_context("display.max_rows", None, "display.max_columns", None):
print(diagnostics)

@_positional_args_deprecated()
def get_formatted_diagnostics(
self, full_report: bool = False, custom_columns: Optional[Iterable] = None
) -> Union[str, pd.DataFrame]:
Expand Down Expand Up @@ -1201,6 +1203,7 @@ def _find_alpha_index(self, alpha):
f"{self._alphas}. Consider specifying the index directly via 'alpha_index'."
)

@_positional_args_deprecated(("X", "offset"))
def linear_predictor(
self,
X: ArrayLike,
Expand Down Expand Up @@ -1276,6 +1279,7 @@ def linear_predictor(

return xb

@_positional_args_deprecated(unchanged_args=("X", "sample_weight", "offset"))
def predict(
self,
X: ShapedArrayLike,
Expand Down Expand Up @@ -1338,6 +1342,7 @@ def predict(
sample_weight = _check_weights(sample_weight, X.shape[0], X.dtype)
return mu * sample_weight

@_positional_args_deprecated(("X", "y", "sample_weight", "offset"), 0)
def coef_table(
self,
confidence_level=0.95,
Expand Down Expand Up @@ -1432,6 +1437,7 @@ def coef_table(
index=names,
)

@_positional_args_deprecated(("X", "y", "sample_weight", "offset"), 0)
def wald_test(
self,
R: Optional[np.ndarray] = None,
Expand Down Expand Up @@ -1738,6 +1744,7 @@ def _wald_test_feature_names(
expected_information=expected_information,
)

@_positional_args_deprecated(("X", "y", "sample_weight", "offset"), 2)
def std_errors(
self,
X=None,
Expand Down Expand Up @@ -1801,6 +1808,7 @@ def std_errors(
).diagonal()
)

@_positional_args_deprecated(("X", "y", "sample_weight", "offset"), 2)
def covariance_matrix(
self,
X=None,
Expand Down Expand Up @@ -2727,6 +2735,7 @@ class GeneralizedLinearRegressor(GeneralizedLinearRegressorBase):
https://www.csie.ntu.edu.tw/~cjlin/papers/l1_glmnet/long-glmnet.pdf
"""

@_positional_args_deprecated()
def __init__(
self,
alpha=None,
Expand Down Expand Up @@ -2763,6 +2772,10 @@ def __init__(
robust: bool = True,
expected_information: bool = False,
):
if alpha is None:
warnings.warn(
"The default value of `alpha` will become `0` in 3.0.0.", FutureWarning
)
self.alphas = alphas
self.alpha = alpha
super().__init__(
Expand Down Expand Up @@ -2837,6 +2850,7 @@ def _validate_hyperparameters(self) -> None:
)
super()._validate_hyperparameters()

@_positional_args_deprecated(("X", "y", "sample_weight", "offset"))
def fit(
self,
X: ArrayLike,
Expand Down
4 changes: 3 additions & 1 deletion src/glum/_glm_cv.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
setup_p2,
)
from ._link import Link, LogLink
from ._util import _safe_lin_pred
from ._util import _positional_args_deprecated, _safe_lin_pred


class GeneralizedLinearRegressorCV(GeneralizedLinearRegressorBase):
Expand Down Expand Up @@ -282,6 +282,7 @@ class GeneralizedLinearRegressorCV(GeneralizedLinearRegressorBase):
Only relevant when computing robust standard errors.
"""

@_positional_args_deprecated()
def __init__(
self,
l1_ratio=0,
Expand Down Expand Up @@ -370,6 +371,7 @@ def _validate_hyperparameters(self) -> None:
)
super()._validate_hyperparameters()

@_positional_args_deprecated(("X", "y", "sample_weight", "offset"))
def fit(
self,
X: ArrayLike,
Expand Down
37 changes: 37 additions & 0 deletions src/glum/_util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
import warnings
from functools import wraps
from typing import Union

import numpy as np
Expand Down Expand Up @@ -106,3 +108,38 @@ def _safe_toarray(X) -> np.ndarray:
return X.toarray()
else:
return np.asarray(X)


def _positional_args_deprecated(unchanged_args=(), unchanged_args_number=None):
"""
Raise a FutureWarning if more than `unchanged_args_number` positional
arguments are passed.
"""
if unchanged_args_number is None:
unchanged_args_number = len(unchanged_args)

def decorator(func):
first_part = "Arguments" if unchanged_args else "All arguments"
exceptions = (
" other than " + ", ".join(f"`{arg}`" for arg in unchanged_args)
if unchanged_args
else ""
)

msg = (
f"{first_part} to `{func.__qualname__}`{exceptions} "
"will become keyword-only in 3.0.0."
)

@wraps(func)
def wrapper(*args, **kwargs):
if len(args) > unchanged_args_number + 1: # +1 for self
warnings.warn(
msg,
FutureWarning,
)
return func(*args, **kwargs)

return wrapper

return decorator
1 change: 1 addition & 0 deletions tests/glm/test_glm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2310,6 +2310,7 @@ def test_information_criteria(regression_data):
)


@pytest.mark.skip(reason="Skip while future warnings are raised.")
@pytest.mark.filterwarnings("ignore: There is no")
def test_information_criteria_raises_correct_warnings_and_errors(regression_data):
X, y = regression_data
Expand Down

0 comments on commit 96e6534

Please sign in to comment.