Repository: sktime/sktime
Pull request #7539 (2024-12-17 12:48:28)

[DOC] Docstring for PanelGluontsList added
Add short and long descriptions, conditions and capabilities in the docstring for PanelGluontsList. 

<!--
Welcome to sktime, and thanks for contributing!
Please have a look at our contribution guide:
https://www.sktime.net/en/latest/get_involved/contributing.html
-->

#### Reference Issues/PRs
Fixed docstrings for PanelGluontsList as per specifications in #7386.


#### What does this implement/fix? Explain your changes.
Added detailed description in documentation for PanelGluontsList. Also the older data type description "polars.DataFrame based specification of panel of time series." is clearly incorrect for PanelGluontsList (which is derived from the gluonTS library). It was likely carried/copied over from the preceding datatype PanelPolarsEager, which does have that description. Fixed that to have the correct description from MTYPE_REGISTER.

#### Does your contribution introduce a new dependency? If yes, which one?
No.

#### What should a reviewer concentrate their feedback on?

<!-- This section is particularly useful if you have a pull request that is still in development. You can guide the reviews to focus on the parts that are ready for their comments. We suggest using bullets (indicated by * or -) and filled checkboxes [x] here -->

#### Did you add any tests for the change?

<!-- This section is useful if you have added a test in addition to the existing ones. This will ensure that further changes to these files won't introduce the same kind of bug. It is considered good practice to add tests with newly added code to enforce the fact that the code actually works. This will reduce the chance of introducing logical bugs.
-->

#### Any other comments?
<!--
We value all user contributions, no matter how small or complex they are. If you have any questions, feel free to post
in the dev-chat channel on the sktime discord https://discord.com/invite/54ACzaFsn7. If we are slow to review (>3 working days), likewise feel free to ping us on discord. Thank you for your understanding during the review process.
-->

#### PR checklist
<!--
Please go through the checklist below. Please feel free to remove points if they are not applicable.
-->

##### For all contributions
- [x] I've added myself to the [list of contributors](https://github.com/sktime/sktime/blob/main/CONTRIBUTORS.md) with any new badges I've earned :-)
  How to: add yourself to the [all-contributors file](https://github.com/sktime/sktime/blob/main/.all-contributorsrc) in the `sktime` root directory (not the `CONTRIBUTORS.md`). Common badges: `code` - fixing a bug, or adding code logic. `doc` - writing or improving documentation or docstrings. `bug` - reporting or diagnosing a bug (get this plus `code` if you also fixed the bug in the PR).`maintenance` - CI, test framework, release.
  See here for [full badge reference](https://allcontributors.org/docs/en/emoji-key)
- [ ] Optionally, for added estimators: I've added myself and possibly to the `maintainers` tag - do this if you want to become the owner or maintainer of an estimator you added.
  See here for further details on the [algorithm maintainer role](https://www.sktime.net/en/latest/get_involved/governance.html#algorithm-maintainers).
- [x] The PR title starts with either [ENH], [MNT], [DOC], or [BUG]. [BUG] - bugfix, [MNT] - CI, test framework, [ENH] - adding or improving code, [DOC] - writing or improving documentation or docstrings.

##### For new estimators
- [ ] I've added the estimator to the API reference - in `docs/source/api_reference/taskname.rst`, follow the pattern.
- [ ] I've added one or more illustrative usage examples to the docstring, in a pydocstyle compliant `Examples` section.
- [ ] If the estimator relies on a soft dependency, I've set the `python_dependencies` tag and ensured
  dependency isolation, see the [estimator dependencies guide](https://www.sktime.net/en/latest/developer_guide/dependencies.html#adding-a-soft-dependency).

<!--
Thanks for contributing!
-->


yarnabrina: Hi @b9junkers won't it make better sense to have these changes and the polars typo fix as part of same PR?
b9junkers: > Hi @b9junkers won't it make better sense to have these changes and the polars typo fix as part of same PR?

Added the change here. I closed the other pull request. Is this okay?

b9junkers: >     * also, I assume there must be some "equal length" requierments on the index under `"start"`? If so, this shoul be stated.

Apologies for this one. I hadn't ever used ``pandas.Period`` before, so I assumed it would represent the time index.  Further, the nomenclature is misleading too.

``pandas.Period`` actually represents a timestamp, which can be specified with a frequency. So if I have a time series starting on 2024-01-01 and sampled daily, I would use ``pandas.Period("2024-01-01", freq="D")`` to denote the start. So for a time point ``j`` down, the time index would simply be ``pandas.Period("2024-01-01", freq="D") + j``.
fkiraly: Ah, I see! This makes sense.

This also looks like the first example of an mtype that can represent unequally supported series, but *not* unequally spaced series.

Should we add this as another bullet point? I.e., can support unequally supported, but cannot support unequally spaced.

Patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
index 7db6a11b5..1d0b821da 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -3296,6 +3296,15 @@
         "code"
       ]
     },
+    {
+      "login": "b9junkers",
+      "name": "Shounak Shirodkar",
+      "avatar_url": "https://avatars.githubusercontent.com/u/54496663?v=4",
+      "profile": "https://github.com/b9junkers",
+      "contributions": [
+        "doc"
+      ]
+    },
     {
       "login": "VjayRam",
       "name": "Vijay Ram Enaganti",
diff --git a/sktime/datatypes/_panel/_check.py b/sktime/datatypes/_panel/_check.py
index f0040ac44..723056216 100644
--- a/sktime/datatypes/_panel/_check.py
+++ b/sktime/datatypes/_panel/_check.py
@@ -1184,7 +1184,58 @@ def _check_polars_panel(obj, return_metadata=False, var_name="obj", scitype="Pan
 
 
 class PanelGluontsList(ScitypePanel):
-    """Data type: polars.DataFrame based specification of panel of time series.
+    """Data type: gluonTS representation of univariate and multivariate time series.
+
+    Name: ``"gluonts_ListDataset_panel"``
+
+    Short description:
+
+    A ``list`` of ``dict``,
+    with list index = instances, ``dict['target']`` rows = time points,
+    ``dict['target']`` cols = variables, and ``dict['start']`` marking the interval.
+    Identical to ``gluonts.dataset.common.ListDataset``.
+
+    Long description:
+
+    The ``"gluonts_ListDataset_panel"`` :term:`mtype` is a concrete specification
+    that implements the ``Panel`` :term:`scitype`, i.e., the abstract
+    type of a collection of time series.
+
+    An object ``obj: list`` follows the specification iff:
+
+    * structure convention: ``obj`` must be a ``list`` of ``dict``.
+      Each ``dict`` must contain a key ``"target"``which
+      maps to a 1D ``numpy.ndarray`` for a univariate, and
+      2D ``numpy.ndarray`` for a multivariate time series.
+      Optionally, it may also contain a key ``"start"``
+      that maps to a ``pandas.Period`` object.
+      eg: ``pandas.Period("2024-01-01", freq="D")`` for a time series starting
+      on 2024-01-01 and sampled daily.
+    * instances: instances correspond to different list elements of ``obj``.
+    * instance index: the instance index of an instance is the list index at which
+      it is located in ``obj``. That is, the data at ``obj[i]``
+      correspond to observations of the instance with index ``i``.
+    * time points: rows of ``obj[i]['target']`` correspond to
+      different, distinct time points, at which
+      instance ``i`` is observed.
+    * time index: the time index is implicit and by-convention.
+      The ``j``-th element (for an integer ``j``) of instance ``i`` is interpreted
+      as an observation at the time point ``j``.
+      If ``"start"`` key is present, the time index for
+      the ``j``-th element of instance ``i`` is ``obj[i]['start'] + j``.
+    * variables: columns of ``obj[i]['target']`` correspond to different variables
+      available for instance ``i``.
+    * variable names: ``numpy`` mtypes cannot represent variable names. If required,
+      then variable names are assigned ``"value_{k}``
+      where ``k`` is the feature column index.
+
+    Capabilities:
+
+    * can represent panels of multivariate series
+    * can not represent panels of unequally spaced series
+    * can represent panels of unequally supported series
+    * can represent panels of series with different sets of variables
+    * can represent missing values
 
     Parameters
     ----------
diff --git a/sktime/performance_metrics/forecasting/_classes.py b/sktime/performance_metrics/forecasting/_classes.py
index 18866c221..955295b47 100644
--- a/sktime/performance_metrics/forecasting/_classes.py
+++ b/sktime/performance_metrics/forecasting/_classes.py
@@ -711,7 +711,7 @@ class BaseForecastingErrorMetric(BaseMetric):
                 return y.X_multiindex
 
             valid, msg, metadata = check_is_scitype(
-                y, scitype=SCITYPES, return_metadata=True, var_name=var_name
+                y, scitype=SCITYPES, return_metadata=[], var_name=var_name
             )
             if not valid:
                 raise TypeError(msg)
diff --git a/sktime/utils/dependencies/_dependencies.py b/sktime/utils/dependencies/_dependencies.py
index 1c4a1322b..34e5b84bc 100644
--- a/sktime/utils/dependencies/_dependencies.py
+++ b/sktime/utils/dependencies/_dependencies.py
@@ -1,7 +1,5 @@
 """Utility to check soft dependency imports, and raise warnings or errors."""
 
-__author__ = ["fkiraly", "mloning"]
-
 import sys
 import warnings
 from functools import lru_cache
@@ -131,23 +129,20 @@ def _check_soft_dependencies(
         if pkg_env_version is None:
             if obj is None and msg is None:
                 msg = (
-                    f"{package!r} not found. "
-                    f"{package!r} is a soft dependency and not included in the "
-                    f"base sktime installation. Please run: `pip install {package}` to "
-                    f"install the {package} package. "
-                    f"To install all soft dependencies, run: `pip install "
-                    f"sktime[all_extras]`"
+                    f"{class_name} requires package {package!r} to be present "
+                    f"in the python environment, but {package!r} was not found. "
                 )
             elif msg is None:  # obj is not None, msg is None
                 msg = (
                     f"{class_name} requires package {package!r} to be present "
                     f"in the python environment, but {package!r} was not found. "
-                    f"{package!r} is a soft dependency and not included in the base "
-                    f"sktime installation. Please run: `pip install {package}` to "
-                    f"install the {package} package. "
-                    f"To install all soft dependencies, run: `pip install "
-                    f"sktime[all_extras]`"
+                    f"{package!r} is a dependency of {class_name} and required "
+                    f"to construct it. "
                 )
+            msg = msg + (
+                f"To install the requirement {package!r}, please run: "
+                f"pip install {package}` "
+            )
             # if msg is not None, none of the above is executed,
             # so if msg is passed it overrides the default messages
 
@@ -221,10 +216,10 @@ def _check_mlflow_dependencies(msg=None, severity="error"):
     Parameters
     ----------
     msg: str, optional, default= default message (msg below)
-        error message to be returned when `ModuleNotFoundError` is raised.
+        error message to be returned when ``ModuleNotFoundError`` is raised.
     severity: str, either of "error", "warning" or "none"
         behaviour for raising errors or warnings
-        "error" - raises a `ModuleNotFound` if mlflow-related packages are not found.
+        "error" - raises a ``ModuleNotFound`` if mlflow-related packages are not found.
         "warning" - raises a warning message if any mlflow-related package is not
             installed also returns False. In case all packages are present,
             returns True.


Test patch:
diff --git a/sktime/tests/test_softdeps.py b/sktime/tests/test_softdeps.py
index 599dd7fb4..800623058 100644
--- a/sktime/tests/test_softdeps.py
+++ b/sktime/tests/test_softdeps.py
@@ -83,9 +83,7 @@ def is_soft_dep_missing_message(msg):
     missing_version_msg = "to be present in the python environment, with version"
     cond1 = missing_version_msg in msg
     # message if dependency is missing entirely
-    missing_dep_entirely_msg = (
-        "is a soft dependency and not included in the base sktime installation"
-    )
+    missing_dep_entirely_msg = "requires package"
     cond2 = missing_dep_entirely_msg in msg
     # special message for deep learning dependencies
     error_msg_dl = "required for deep learning"
diff --git a/sktime/utils/_testing/tests/test_check_imports.py b/sktime/utils/_testing/tests/test_check_imports.py
index 52ea182ba..4c1210848 100644
--- a/sktime/utils/_testing/tests/test_check_imports.py
+++ b/sktime/utils/_testing/tests/test_check_imports.py
@@ -5,8 +5,9 @@ from sktime.utils.dependencies import _check_soft_dependencies
 
 def test_check_soft_dependencies_raises_error():
     """Test the _check_soft_dependencies() function."""
-    with pytest.raises(ModuleNotFoundError, match=r".* soft dependency .*"):
-        _check_soft_dependencies("unavailable_module")
+    MODULE = "unavailable_module"
+    with pytest.raises(ModuleNotFoundError, match=r".* requires package .*"):
+        _check_soft_dependencies(MODULE)
 
-    with pytest.raises(ModuleNotFoundError, match=r".* soft dependency .*"):
-        _check_soft_dependencies("unavailable_module_1", "unavailable_module_2")
+    with pytest.raises(ModuleNotFoundError, match=r".* requires package .*"):
+        _check_soft_dependencies(MODULE + "_1", MODULE + "_2")