Skip to content

Commit

Permalink
[MNT] remove soft dependency import warnings in modules and documente…
Browse files Browse the repository at this point in the history
…d requirements to add these (#4398)

Previously, modules that contained objects with soft dependencies were raising import warnings.
This would raise a lot of warnings in crawling based utilities such as `all_estimators` (and cause those utilities to have a longer runtime than otherwise).

In many cases, the warnings would be raised without a clear reason visible to the user, and would confuse more than they would help - contributing to some user frustration.
The information is still raised as an error when users try to construct the estimators in question - and there cause and effect are much clearer. Therefore, I would argue that it is an improvement to get rid of the module warnings.

This PR removes both the existing warnings in estimator modules and the convention itself:

* removed all calls to `_check_soft_dependencies` with warning level at module import, in estimator modules
* removed the instruction to write such checks from all extension templates
* removed the bullet point in the dependency handling guide that asked to add these, and rewrote adjacent content for coherence
  • Loading branch information
fkiraly committed Apr 2, 2023
1 parent 44da5d0 commit 4a8dc87
Show file tree
Hide file tree
Showing 42 changed files with 8 additions and 143 deletions.
6 changes: 2 additions & 4 deletions docs/source/developer_guide/dependencies.rst
Expand Up @@ -46,12 +46,10 @@ To add an estimator with a soft dependency, ensure the following:
* the ``python_dependencies`` tag of the estimator is populated with a ``str``,
or a ``list`` of ``str``, of import dependencies. Exceptions will automatically raised when constructing the estimator
in an environment without the required packages.
* in the python module containing the estimator, the ``_check_soft_dependencies`` utility is called
at the top of the module, with ``severity="warning"``. This will raise an informative warning message already at module import.
See `here <https://github.com/sktime/sktime/blob/main/sktime/utils/validation/_dependencies.py>`__
* In a case where the package import differs from the package name, i.e., ``import package_string`` is different from
``pip install different-package-string`` (usually the case for packages containing a dash in the name), the ``_check_soft_dependencies``
utility should be used in ``__init__``. Both the warning and constructor call should use the ``package_import_alias`` argument for this.
utility should be called in ``__init__`` before the ``super.__init__`` call, with ``severity="error"``.
The ``package_import_alias`` argument should be used to pass the information on package and import strings.
* If the soft dependencies require specific python versions, the ``python_version``
tag should also be populated, with a PEP 440 compliant version specification ``str`` such as ``"<3.10"`` or ``">3.6,~=3.8"``.
* If including docstring examples that use soft dependencies, ensure to skip doctest. To do this add a ``# doctest: +SKIP`` to the end of each
Expand Down
6 changes: 1 addition & 5 deletions extension_templates/classification.py
Expand Up @@ -42,11 +42,7 @@
# todo: add any necessary imports here

# todo: if any imports are sktime soft dependencies:
# * make sure to fill in the "python_dependencies" tag with the package import name
# * add a _check_soft_dependencies warning here, example:
#
# from sktime.utils.validation._dependencies import check_soft_dependencies
# _check_soft_dependencies("soft_dependency_name", severity="warning")
# make sure to fill in the "python_dependencies" tag with the package import name


class MyTimeSeriesClassifier(BaseClassifier):
Expand Down
6 changes: 1 addition & 5 deletions extension_templates/dist_kern_panel.py
Expand Up @@ -30,11 +30,7 @@
# todo: add any necessary imports here

# todo: if any imports are sktime soft dependencies:
# * make sure to fill in the "python_dependencies" tag with the package import name
# * add a _check_soft_dependencies warning here, example:
#
# from sktime.utils.validation._dependencies import check_soft_dependencies
# _check_soft_dependencies("soft_dependency_name", severity="warning")
# make sure to fill in the "python_dependencies" tag with the package import name


class MyTrafoPwPanel(BasePairwiseTransformerPanel):
Expand Down
6 changes: 1 addition & 5 deletions extension_templates/dist_kern_tab.py
Expand Up @@ -30,11 +30,7 @@
# todo: add any necessary imports here

# todo: if any imports are sktime soft dependencies:
# * make sure to fill in the "python_dependencies" tag with the package import name
# * add a _check_soft_dependencies warning here, example:
#
# from sktime.utils.validation._dependencies import check_soft_dependencies
# _check_soft_dependencies("soft_dependency_name", severity="warning")
# make sure to fill in the "python_dependencies" tag with the package import name


class MyTrafoPw(BasePairwiseTransformer):
Expand Down
6 changes: 1 addition & 5 deletions extension_templates/forecasting.py
Expand Up @@ -51,11 +51,7 @@
# todo: add any necessary imports here

# todo: if any imports are sktime soft dependencies:
# * make sure to fill in the "python_dependencies" tag with the package import name
# * add a _check_soft_dependencies warning here, example:
#
# from sktime.utils.validation._dependencies import check_soft_dependencies
# _check_soft_dependencies("soft_dependency_name", severity="warning")
# make sure to fill in the "python_dependencies" tag with the package import name


class MyForecaster(BaseForecaster):
Expand Down
6 changes: 1 addition & 5 deletions extension_templates/param_est.py
Expand Up @@ -38,11 +38,7 @@
# todo: add any necessary imports here

# todo: if any imports are sktime soft dependencies:
# * make sure to fill in the "python_dependencies" tag with the package import name
# * add a _check_soft_dependencies warning here, example:
#
# from sktime.utils.validation._dependencies import check_soft_dependencies
# _check_soft_dependencies("soft_dependency_name", severity="warning")
# make sure to fill in the "python_dependencies" tag with the package import name


class MyTimeSeriesParamFitter(BaseParamFitter):
Expand Down
6 changes: 1 addition & 5 deletions extension_templates/transformer.py
Expand Up @@ -49,11 +49,7 @@
# todo: add any necessary sktime internal imports here

# todo: if any imports are sktime soft dependencies:
# * make sure to fill in the "python_dependencies" tag with the package import name
# * add a _check_soft_dependencies warning here, example:
#
# from sktime.utils.validation._dependencies import check_soft_dependencies
# _check_soft_dependencies("soft_dependency_name", severity="warning")
# make sure to fill in the "python_dependencies" tag with the package import name


class MyTransformer(BaseTransformer):
Expand Down
8 changes: 0 additions & 8 deletions sktime/alignment/dtw_python.py
Expand Up @@ -12,14 +12,6 @@
from sktime.alignment.base import BaseAligner
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies(
"dtw-python",
package_import_alias={"dtw-python": "dtw"},
severity="warning",
obj="AlignerDTW or AlignerDTWfromDist",
suppress_import_stdout=True,
)


class AlignerDTW(BaseAligner):
"""Aligner interface for dtw-python.
Expand Down
2 changes: 0 additions & 2 deletions sktime/annotation/adapters/_pyod.py
Expand Up @@ -13,8 +13,6 @@

import pandas as pd

_check_soft_dependencies("pyod", severity="warning")


class PyODAnnotator(BaseSeriesAnnotator):
"""Transformer that applies outlier detector from pyOD.
Expand Down
3 changes: 0 additions & 3 deletions sktime/annotation/hmm_learn/gaussian.py
Expand Up @@ -8,13 +8,10 @@
"""

from sktime.annotation.hmm_learn import BaseHMMLearn
from sktime.utils.validation._dependencies import _check_soft_dependencies

__author__ = ["miraep8"]
__all__ = ["GaussianHMM"]

_check_soft_dependencies("hmmlearn.hmm", severity="warning")


class GaussianHMM(BaseHMMLearn):
"""Hidden Markov Model with Gaussian emissions.
Expand Down
4 changes: 0 additions & 4 deletions sktime/annotation/hmm_learn/gmm.py
Expand Up @@ -8,15 +8,11 @@
"""

from sktime.annotation.hmm_learn import BaseHMMLearn
from sktime.utils.validation._dependencies import _check_soft_dependencies

__author__ = ["miraep8"]
__all__ = ["GMMHMM"]


_check_soft_dependencies("hmmlearn.hmm", severity="warning")


class GMMHMM(BaseHMMLearn):
"""
Hidden Markov Model with Gaussian mixture emissions.
Expand Down
3 changes: 0 additions & 3 deletions sktime/annotation/hmm_learn/poisson.py
Expand Up @@ -8,13 +8,10 @@
"""

from sktime.annotation.hmm_learn import BaseHMMLearn
from sktime.utils.validation._dependencies import _check_soft_dependencies

__author__ = ["klam-data", "pyyim", "mgorlin"]
__all__ = ["PoissonHMM"]

_check_soft_dependencies("hmmlearn.hmm", severity="warning")


class PoissonHMM(BaseHMMLearn):
"""
Expand Down
2 changes: 0 additions & 2 deletions sktime/classification/deep_learning/cnn.py
Expand Up @@ -12,8 +12,6 @@
from sktime.networks.cnn import CNNNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class CNNClassifier(BaseDeepClassifier):
"""Time Convolutional Neural Network (CNN), as described in [1]_.
Expand Down
2 changes: 0 additions & 2 deletions sktime/classification/deep_learning/fcn.py
Expand Up @@ -12,8 +12,6 @@
from sktime.networks.fcn import FCNNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class FCNClassifier(BaseDeepClassifier):
"""Fully Connected Neural Network (FCN), as described in [1]_.
Expand Down
3 changes: 0 additions & 3 deletions sktime/classification/deep_learning/lstmfcn.py
Expand Up @@ -10,9 +10,6 @@

from sktime.classification.deep_learning.base import BaseDeepClassifier
from sktime.networks.lstmfcn import LSTMFCNNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class LSTMFCNClassifier(BaseDeepClassifier):
Expand Down
2 changes: 0 additions & 2 deletions sktime/classification/deep_learning/mlp.py
Expand Up @@ -12,8 +12,6 @@
from sktime.networks.mlp import MLPNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class MLPClassifier(BaseDeepClassifier):
"""Multi Layer Perceptron Network (MLP), as described in [1]_.
Expand Down
2 changes: 0 additions & 2 deletions sktime/classification/deep_learning/resnet.py
Expand Up @@ -12,8 +12,6 @@
from sktime.networks.resnet import ResNetNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class ResNetClassifier(BaseDeepClassifier):
"""
Expand Down
2 changes: 0 additions & 2 deletions sktime/classification/deep_learning/tapnet.py
Expand Up @@ -18,8 +18,6 @@
from sktime.networks.tapnet import TapNetNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class TapNetClassifier(BaseDeepClassifier):
"""Time series attentional prototype network (TapNet), as described in [1]_.
Expand Down
3 changes: 0 additions & 3 deletions sktime/clustering/k_shapes.py
Expand Up @@ -6,9 +6,6 @@
from numpy.random import RandomState

from sktime.clustering.base import BaseClusterer, TimeSeriesInstances
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("tslearn", severity="warning")


class TimeSeriesKShapes(BaseClusterer):
Expand Down
3 changes: 0 additions & 3 deletions sktime/clustering/kernel_k_means.py
Expand Up @@ -6,9 +6,6 @@
from numpy.random import RandomState

from sktime.clustering.base import BaseClusterer, TimeSeriesInstances
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("tslearn", severity="warning")


class TimeSeriesKernelKMeans(BaseClusterer):
Expand Down
2 changes: 0 additions & 2 deletions sktime/forecasting/adapters/_hcrystalball.py
Expand Up @@ -11,8 +11,6 @@
from sktime.forecasting.base import BaseForecaster
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("hcrystalball", severity="warning")


def _check_fh(fh, cutoff):
if fh is not None:
Expand Down
3 changes: 0 additions & 3 deletions sktime/forecasting/arima.py
Expand Up @@ -7,9 +7,6 @@
__all__ = ["AutoARIMA", "ARIMA"]

from sktime.forecasting.base.adapters._pmdarima import _PmdArimaAdapter
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("pmdarima", severity="warning")


class AutoARIMA(_PmdArimaAdapter):
Expand Down
3 changes: 0 additions & 3 deletions sktime/forecasting/bats.py
Expand Up @@ -13,9 +13,6 @@
__all__ = ["BATS"]

from sktime.forecasting.base.adapters import _TbatsAdapter
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("tbats", severity="warning")


class BATS(_TbatsAdapter):
Expand Down
3 changes: 0 additions & 3 deletions sktime/forecasting/fbprophet.py
Expand Up @@ -9,9 +9,6 @@

from sktime.forecasting.base._base import DEFAULT_ALPHA
from sktime.forecasting.base.adapters import _ProphetAdapter
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("prophet", severity="warning")


class Prophet(_ProphetAdapter):
Expand Down
3 changes: 0 additions & 3 deletions sktime/forecasting/statsforecast.py
Expand Up @@ -9,9 +9,6 @@
from typing import Dict, Optional

from sktime.forecasting.base.adapters._statsforecast import _StatsForecastAdapter
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("statsforecast", severity="warning")


class StatsForecastAutoARIMA(_StatsForecastAdapter):
Expand Down
3 changes: 0 additions & 3 deletions sktime/forecasting/tbats.py
Expand Up @@ -13,9 +13,6 @@
__all__ = ["TBATS"]

from sktime.forecasting.base.adapters import _TbatsAdapter
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("tbats", severity="warning")


class TBATS(_TbatsAdapter):
Expand Down
2 changes: 0 additions & 2 deletions sktime/networks/cnn.py
Expand Up @@ -6,8 +6,6 @@
from sktime.networks.base import BaseDeepNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class CNNNetwork(BaseDeepNetwork):
"""Establish the network structure for a CNN.
Expand Down
2 changes: 0 additions & 2 deletions sktime/networks/fcn.py
Expand Up @@ -6,8 +6,6 @@
from sktime.networks.base import BaseDeepNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class FCNNetwork(BaseDeepNetwork):
"""Establish the network structure for a FCN.
Expand Down
3 changes: 0 additions & 3 deletions sktime/networks/lstmfcn.py
Expand Up @@ -4,9 +4,6 @@
__author__ = ["jnrusson1", "solen0id"]

from sktime.networks.base import BaseDeepNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class LSTMFCNNetwork(BaseDeepNetwork):
Expand Down
5 changes: 0 additions & 5 deletions sktime/networks/lstmfcn_layers.py
Expand Up @@ -2,11 +2,6 @@
"""Attention Layers used in by the LSTM-FCN Network. Ported over from sktime-dl."""


from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


def make_attention_lstm():
"""Return AttentionLSTM class used by the LSTM-FCN Network."""
from tensorflow.keras import activations
Expand Down
2 changes: 0 additions & 2 deletions sktime/networks/mlp.py
Expand Up @@ -6,8 +6,6 @@
from sktime.networks.base import BaseDeepNetwork
from sktime.utils.validation._dependencies import _check_dl_dependencies

_check_dl_dependencies(severity="warning")


class MLPNetwork(BaseDeepNetwork):
"""Establish the network structure for a MLP.
Expand Down
7 changes: 0 additions & 7 deletions sktime/networks/tapnet.py
Expand Up @@ -15,13 +15,6 @@
_check_soft_dependencies,
)

_check_soft_dependencies(
"keras-self-attention",
package_import_alias={"keras-self-attention": "keras_self_attention"},
severity="warning",
)
_check_dl_dependencies(severity="warning")


class TapNetNetwork(BaseDeepNetwork):
"""Establish Network structure for TapNet.
Expand Down
3 changes: 0 additions & 3 deletions sktime/transformations/panel/catch22wrapper.py
Expand Up @@ -14,9 +14,6 @@
from sktime.transformations.base import BaseTransformer
from sktime.transformations.panel import catch22
from sktime.utils.validation import check_n_jobs
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("pycatch22", severity="warning")


class Catch22Wrapper(BaseTransformer):
Expand Down
3 changes: 0 additions & 3 deletions sktime/transformations/panel/signature_based/_compute.py
Expand Up @@ -8,9 +8,6 @@
_rescale_signature,
)
from sktime.transformations.panel.signature_based._window import _window_getter
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("esig", severity="warning")


class _WindowSignatureTransform(BaseTransformer):
Expand Down
4 changes: 0 additions & 4 deletions sktime/transformations/panel/signature_based/_rescaling.py
Expand Up @@ -12,10 +12,6 @@

import numpy as np

from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("esig", severity="warning")


def _rescale_path(path, depth):
"""Rescale input path by depth! ** (1 / depth).
Expand Down
3 changes: 0 additions & 3 deletions sktime/transformations/panel/tsfresh.py
Expand Up @@ -10,9 +10,6 @@
from sktime.datatypes._panel._convert import from_nested_to_long
from sktime.transformations.base import BaseTransformer
from sktime.utils.validation import check_n_jobs
from sktime.utils.validation._dependencies import _check_soft_dependencies

_check_soft_dependencies("tsfresh", severity="warning")


class _TSFreshFeatureExtractor(BaseTransformer):
Expand Down

0 comments on commit 4a8dc87

Please sign in to comment.