Repository: mne-tools/mne-python

Issue:
Consider removing jinja2 from `mne.sys_info()`
We've had many discussions on how we should handle dependencies, but given that we currently only include absolutely essential packages as core dependencies, I was wondering why we include `jinja2`. In my opinion, it would be better (more consistent) to make it an optional dependency. In addition, it is only imported in one location (`mne/html_templates/_templates.py`), and even there it is a nested import.


Discussion:
I'm pretty sure this has been discussed before, can you provide a cross ref to the past discussion(s)?
😄 yes, it was me who asked this question before in #11559. Apparently, it still bothers me, but I guess your opinions won't have changed, so feel free to close.
I think I know what bothers me: listing `jinja2` and `pooch` in the "Core" section of the output of `mne.sys_info()`. This doesn't really make sense, because they are small infrastructure packages (as opposed to core packages). So what about removing these two packages from the section? BTW, we don't include other required packages like `decorator`, `lazy-loader`, `packaging`, and `tqdm` either (and I think we shouldn't).

Current output:

```
Platform             macOS-14.3-arm64-arm-64bit
Python               3.12.1 (main, Jan 24 2024, 11:32:51) [Clang 15.0.0 (clang-1500.1.0.2.5)]
Executable           /Users/clemens/.pyenv/versions/3.12.1/envs/mne/bin/python3.12
CPU                  arm (12 cores)
Memory               32.0 GB

Core
├☑ mne               1.7.0.dev77+g566c6ea5a (devel, latest release is 1.6.1)
├☑ numpy             1.26.3 (OpenBLAS 0.3.23.dev with 12 threads)
├☑ scipy             1.12.0
├☑ matplotlib        3.8.2 (backend=MacOSX)
├☑ pooch             1.8.0
└☑ jinja2            3.1.3

Numerical (optional)
└☐ unavailable       sklearn, numba, nibabel, nilearn, dipy, openmeeg, cupy, pandas

Visualization (optional)
├☑ qtpy              2.4.1 (PySide6=6.6.1)
├☑ pyqtgraph         0.13.3
├☑ mne-qt-browser    0.6.1
└☐ unavailable       pyvista, pyvistaqt, vtk, ipympl, ipywidgets, trame_client, trame_server, trame_vtk, trame_vuetify

Ecosystem (optional)
└☐ unavailable       mne-bids, mne-nirs, mne-features, mne-connectivity, mne-icalabel, mne-bids-pipeline, neo
```
Good idea to make the core deps section smaller by narrowing it down to the essentials  👍
I'm open to that. Where should they go instead if not in "core"?

-------- Original Message --------
On 1/26/24 02:44, Clemens Brunner  wrote:

> I think I know what bothers me: listing jinja2 and pooch in the "Core" section of the output of mne.sys_info(). This doesn't really make sense, so what about removing these two packages from the section? We don't include lazy-loader either (which makes sense).
>
> —
> Reply to this email directly, [view it on GitHub](https://github.com/mne-tools/mne-python/issues/12387#issuecomment-1911680202), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AAN2AU4QKKFZUO2JCFTY5ELYQNUG7AVCNFSM6AAAAABCKJ2K2KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMJRGY4DAMRQGI).
> You are receiving this because you commented.Message ID: ***@***.***>
Nowhere, or to a new section called "infrastructure" or something like that.

Resolving patch:
diff --git a/mne/utils/config.py b/mne/utils/config.py
--- a/mne/utils/config.py
+++ b/mne/utils/config.py
@@ -649,8 +649,6 @@ def sys_info(
         "numpy",
         "scipy",
         "matplotlib",
-        "pooch",
-        "jinja2",
         "",
         "# Numerical (optional)",
         "sklearn",
@@ -701,6 +699,14 @@ def sys_info(
             "sphinx-gallery",
             "pydata-sphinx-theme",
             "",
+            "# Infrastructure",
+            "decorator",
+            "jinja2",
+            # "lazy-loader",
+            "packaging",
+            "pooch",
+            "tqdm",
+            "",
         )
     try:
         unicode = unicode and (sys.stdout.encoding.lower().startswith("utf"))
diff --git a/mne/utils/docs.py b/mne/utils/docs.py
--- a/mne/utils/docs.py
+++ b/mne/utils/docs.py
@@ -3298,7 +3298,7 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
               difference will be preserved.
 """
 
-docdict["reject_drop_bad"] = """
+docdict["reject_drop_bad"] = """\
 reject : dict | str | None
     Reject epochs based on **maximum** peak-to-peak signal amplitude (PTP)
     or custom functions. Peak-to-peak signal amplitude is defined as
@@ -3320,10 +3320,17 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
 
     Custom rejection criteria can be also be used by passing a callable,
     e.g., to check for 99th percentile of absolute values of any channel
-    across time being bigger than 1mV. The callable must return a good, reason tuple.
-    Where good must be bool and reason must be str, list, or tuple where each entry is a str.::
-
-        reject = dict(eeg=lambda x: ((np.percentile(np.abs(x), 99, axis=1) > 1e-3).any(),  "> 1mV somewhere"))
+    across time being bigger than :unit:`1 mV`. The callable must return a
+    ``(good, reason)`` tuple: ``good`` must be :class:`bool` and ``reason``
+    must be :class:`str`, :class:`list`, or :class:`tuple` where each entry
+    is a :class:`str`::
+
+        reject = dict(
+            eeg=lambda x: (
+                (np.percentile(np.abs(x), 99, axis=1) > 1e-3).any(),
+                "signal > 1 mV somewhere",
+            )
+        )
 
     .. note:: If rejection is based on a signal **difference**
             calculated for each channel separately, applying baseline
@@ -3332,6 +3339,7 @@ def _reflow_param_docstring(docstring, has_first_line=True, width=75):
 
     .. note:: If ``reject`` is a callable, than **any** criteria can be
             used to reject epochs (including maxima and minima).
+
     If ``reject`` is ``None``, no rejection is performed. If ``'existing'``
     (default), then the rejection parameters set at instantiation are used.
 """  # noqa: E501


Test patch: