Skip to content

MAINT remove deprecated function #888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 1 addition & 44 deletions doc/developers_utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ E.g., renaming an attribute ``labels_`` to ``classes_`` can be done as::
def labels_(self):
return self.classes_

If a parameter has to be deprecated, use ``DeprecationWarning`` appropriately.
If a parameter has to be deprecated, use ``FutureWarning`` appropriately.
In the following example, k is deprecated and renamed to n_clusters::

import warnings
Expand Down Expand Up @@ -106,49 +106,6 @@ On the top of all the functionality provided by scikit-learn. imbalanced-learn
provides :func:`deprecate_parameter`: which is used to deprecate a sampler's
parameter (attribute) by another one.

Testing utilities
~~~~~~~~~~~~~~~~~
Currently, imbalanced-learn provide a warning management utility. This feature
is going to be merge in pytest and will be removed when the pytest release will
have it.

If using Python 2.7 or above, you may use this function as a
context manager::

>>> import warnings
>>> from imblearn.utils.testing import warns
>>> with warns(RuntimeWarning):
... warnings.warn("my runtime warning", RuntimeWarning)

>>> with warns(RuntimeWarning):
... pass
Traceback (most recent call last):
...
Failed: DID NOT WARN. No warnings of type ...RuntimeWarning... was emitted...

>>> with warns(RuntimeWarning):
... warnings.warn(UserWarning)
Traceback (most recent call last):
...
Failed: DID NOT WARN. No warnings of type ...RuntimeWarning... was emitted...

In the context manager form you may use the keyword argument ``match`` to assert
that the exception matches a text or regex::

>>> import warnings
>>> from imblearn.utils.testing import warns
>>> with warns(UserWarning, match='must be 0 or None'):
... warnings.warn("value must be 0 or None", UserWarning)

>>> with warns(UserWarning, match=r'must be \d+$'):
... warnings.warn("value must be 42", UserWarning)

>>> with warns(UserWarning, match=r'must be \d+$'):
... warnings.warn("this is not here", UserWarning)
Traceback (most recent call last):
...
AssertionError: 'must be \d+$' pattern not found in ['this is not here']

Making a release
----------------
This section document the different steps that are necessary to make a new
Expand Down
5 changes: 2 additions & 3 deletions imblearn/metrics/tests/test_classification.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
from imblearn.metrics import classification_report_imbalanced
from imblearn.metrics import macro_averaged_mean_absolute_error

from imblearn.utils.testing import warns

RND_SEED = 42
R_TOL = 1e-2

Expand Down Expand Up @@ -182,7 +180,8 @@ def test_sensitivity_specificity_support_errors():

def test_sensitivity_specificity_unused_pos_label():
# but average != 'binary'; even if data is binary
with warns(UserWarning, r"use labels=\[pos_label\] to specify a single"):
msg = r"use labels=\[pos_label\] to specify a single"
with pytest.warns(UserWarning, match=msg):
sensitivity_specificity_support(
[1, 2, 1], [1, 2, 2], pos_label=2, average="macro"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
# Christos Aridas
# License: MIT

import warnings

import numpy as np
from scipy import sparse

Expand All @@ -18,7 +16,6 @@

from ..base import BaseUnderSampler
from ...utils import Substitution
from ...utils._docstring import _n_jobs_docstring
from ...utils._docstring import _random_state_docstring
from ...utils._validation import _deprecate_positional_args

Expand All @@ -27,7 +24,6 @@

@Substitution(
sampling_strategy=BaseUnderSampler._sampling_strategy_docstring,
n_jobs=_n_jobs_docstring,
random_state=_random_state_docstring,
)
class ClusterCentroids(BaseUnderSampler):
Expand Down Expand Up @@ -65,11 +61,6 @@ class ClusterCentroids(BaseUnderSampler):

.. versionadded:: 0.3.0

{n_jobs}

.. deprecated:: 0.7
`n_jobs` was deprecated in 0.7 and will be removed in 0.9.

Attributes
----------
sampling_strategy_ : dict
Expand Down Expand Up @@ -125,21 +116,14 @@ def __init__(
random_state=None,
estimator=None,
voting="auto",
n_jobs="deprecated",
):
super().__init__(sampling_strategy=sampling_strategy)
self.random_state = random_state
self.estimator = estimator
self.voting = voting
self.n_jobs = n_jobs

def _validate_estimator(self):
"""Private function to create the KMeans estimator"""
if self.n_jobs != "deprecated":
warnings.warn(
"'n_jobs' was deprecated in 0.7 and will be removed in 0.9",
FutureWarning,
)
if self.estimator is None:
self.estimator_ = KMeans(random_state=self.random_state)
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,6 @@ def test_fit_resample_error(cluster_centroids_params, err_msg):
cc.fit_resample(X, Y)


def test_cluster_centroids_n_jobs():
# check that we deprecate the `n_jobs` parameter.
cc = ClusterCentroids(n_jobs=1)
with pytest.warns(FutureWarning) as record:
cc.fit_resample(X, Y)
assert len(record) == 1
assert "'n_jobs' was deprecated" in record[0].message.args[0]


def test_cluster_centroids_hard_target_class():
# check that the samples selecting by the hard voting corresponds to the
# targeted class
Expand Down
4 changes: 2 additions & 2 deletions imblearn/utils/deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ def deprecate_parameter(sampler, version_deprecation, param_deprecated, new_para
f"'{param_deprecated}' is deprecated from {version_deprecation} and "
f" will be removed in {version_removed} for the estimator "
f"{sampler.__class__}.",
category=DeprecationWarning,
category=FutureWarning,
)
else:
if getattr(sampler, param_deprecated) is not None:
warnings.warn(
f"'{param_deprecated}' is deprecated from {version_deprecation} and "
f"will be removed in {version_removed} for the estimator "
f"{sampler.__class__}. Use '{new_param}' instead.",
category=DeprecationWarning,
category=FutureWarning,
)
setattr(sampler, new_param, getattr(sampler, param_deprecated))
56 changes: 0 additions & 56 deletions imblearn/utils/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@

import inspect
import pkgutil
import warnings
from contextlib import contextmanager
from importlib import import_module
from operator import itemgetter
from pathlib import Path
from re import compile

from scipy import sparse
from pytest import warns as _warns

from sklearn.base import BaseEstimator
from sklearn.neighbors import KDTree
Expand Down Expand Up @@ -116,58 +112,6 @@ def is_abstract(c):
return sorted(set(estimators), key=itemgetter(0))


@contextmanager
def warns(expected_warning, match=None):
r"""Assert that a warning is raised with an optional matching pattern.

.. deprecated:: 0.8
This function is deprecated in 0.8 and will be removed in 0.10.
Use `pytest.warns()` instead.

Assert that a code block/function call warns ``expected_warning``
and raise a failure exception otherwise. It can be used within a context
manager ``with``.

Parameters
----------
expected_warning : Warning
Warning type.

match : regex str or None, optional
The pattern to be matched. By default, no check is done.

Yields
------
Nothing.

Examples
--------
>>> import warnings
>>> from imblearn.utils.testing import warns
>>> with warns(UserWarning, match=r'must be \d+$'):
... warnings.warn("value must be 42", UserWarning)
"""
warnings.warn(
"The warns function is deprecated in 0.8 and will be removed in 0.10. "
"Use pytest.warns() instead."
)

with _warns(expected_warning) as record:
yield

if match is not None:
for each in record:
if compile(match).search(str(each.message)) is not None:
break
else:
msg = "'{}' pattern not found in {}".format(
match, "{}".format([str(r.message) for r in record])
)
assert False, msg
else:
pass


class _CustomNearestNeighbors(BaseEstimator):
"""Basic implementation of nearest neighbors not relying on scikit-learn.

Expand Down
7 changes: 4 additions & 3 deletions imblearn/utils/tests/test_deprecation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
# Authors: Guillaume Lemaitre <g.lemaitre58@gmail.com>
# License: MIT

import pytest

from imblearn.utils.deprecation import deprecate_parameter
from imblearn.utils.testing import warns


class Sampler:
Expand All @@ -14,7 +15,7 @@ def __init__(self):


def test_deprecate_parameter():
with warns(DeprecationWarning, match="is deprecated from"):
with pytest.warns(FutureWarning, match="is deprecated from"):
deprecate_parameter(Sampler(), "0.2", "a")
with warns(DeprecationWarning, match="Use 'b' instead."):
with pytest.warns(FutureWarning, match="Use 'b' instead."):
deprecate_parameter(Sampler(), "0.2", "a", "b")
36 changes: 0 additions & 36 deletions imblearn/utils/tests/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
from imblearn.base import SamplerMixin
from imblearn.utils.testing import all_estimators, _CustomNearestNeighbors

from imblearn.utils.testing import warns


def test_all_estimators():
# check if the filtering is working with a list or a single string
Expand All @@ -31,40 +29,6 @@ def test_all_estimators():
all_estimators(type_filter=type_filter)


@pytest.mark.filterwarnings("ignore:The warns function is deprecated in 0.8")
def test_warns():
import warnings

with warns(UserWarning, match=r"must be \d+$"):
warnings.warn("value must be 42", UserWarning)

with pytest.raises(AssertionError, match="pattern not found"):
with warns(UserWarning, match=r"must be \d+$"):
warnings.warn("this is not here", UserWarning)

with warns(UserWarning, match=r"aaa"):
warnings.warn("cccccccccc", UserWarning)
warnings.warn("bbbbbbbbbb", UserWarning)
warnings.warn("aaaaaaaaaa", UserWarning)

a, b, c = ("aaa", "bbbbbbbbbb", "cccccccccc")
expected_msg = r"'{}' pattern not found in \['{}', '{}'\]".format(a, b, c)
with pytest.raises(AssertionError, match=expected_msg):
with warns(UserWarning, match=r"aaa"):
warnings.warn("bbbbbbbbbb", UserWarning)
warnings.warn("cccccccccc", UserWarning)


# TODO: remove in 0.9
def test_warns_deprecation():
import warnings

with pytest.warns(None) as record:
with warns(UserWarning):
warnings.warn("value must be 42")
assert "The warns function is deprecated" in str(record[0].message)


def test_custom_nearest_neighbors():
"""Check that our custom nearest neighbors can be used for our internal
duck-typing."""
Expand Down
10 changes: 3 additions & 7 deletions imblearn/utils/tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from imblearn.utils import check_neighbors_object
from imblearn.utils import check_sampling_strategy
from imblearn.utils import check_target_type
from imblearn.utils.testing import warns, _CustomNearestNeighbors
from imblearn.utils.testing import _CustomNearestNeighbors
from imblearn.utils._validation import ArraysTransformer
from imblearn.utils._validation import _deprecate_positional_args

Expand Down Expand Up @@ -262,12 +262,8 @@ def test_check_sampling_strategy(
def test_sampling_strategy_dict_over_sampling():
y = np.array([1] * 50 + [2] * 100 + [3] * 25)
sampling_strategy = {1: 70, 2: 140, 3: 70}
expected_msg = (
r"After over-sampling, the number of samples \(140\) in"
r" class 2 will be larger than the number of samples in"
r" the majority class \(class #2 -> 100\)"
)
with warns(UserWarning, expected_msg):
expected_msg = "After over-sampling, the number of samples "
with pytest.warns(UserWarning, match=expected_msg):
check_sampling_strategy(sampling_strategy, y, "over-sampling")


Expand Down