Repository: mne-tools/mne-python

Issue:
filename issue with the new _repr_html_ when creating RawArray directly
#### Describe the bug
After creating a RawArray from scratch, for instance after importing data with neo, the representation of the array fails in Jupyter notebook. The bug seems to be related to _repr_html_ introduced in 0.23.0., where the basename is not found for RawArrays created from scratch.

#### Steps to reproduce
You can simply reproduce by executing this [MNE example](https://mne.tools/stable/auto_examples/io/read_neo_format.html#sphx-glr-auto-examples-io-read-neo-format-py) in a Jupyter notebook, and then run 
```python
raw
```

#### Expected results
Would expect the actual nice html representation introduced in 0.23.0, with the filenames left empty.


#### Actual results
```python
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/anaconda3/envs/neo_mne/lib/python3.9/site-packages/IPython/core/formatters.py in __call__(self, obj)
    343             method = get_real_method(obj, self.print_method)
    344             if method is not None:
--> 345                 return method()
    346             return None
    347         else:

~/anaconda3/envs/neo_mne/lib/python3.9/site-packages/mne/io/base.py in _repr_html_(self, caption)
   1761 
   1762     def _repr_html_(self, caption=None):
-> 1763         basenames = [os.path.basename(f) for f in self._filenames]
   1764         m, s = divmod(self._last_time - self.first_time, 60)
   1765         h, m = divmod(m, 60)

~/anaconda3/envs/neo_mne/lib/python3.9/site-packages/mne/io/base.py in <listcomp>(.0)
   1761 
   1762     def _repr_html_(self, caption=None):
-> 1763         basenames = [os.path.basename(f) for f in self._filenames]
   1764         m, s = divmod(self._last_time - self.first_time, 60)
   1765         h, m = divmod(m, 60)

~/anaconda3/envs/neo_mne/lib/python3.9/posixpath.py in basename(p)
    140 def basename(p):
    141     """Returns the final component of a pathname"""
--> 142     p = os.fspath(p)
    143     sep = _get_sep(p)
    144     i = p.rfind(sep) + 1

TypeError: expected str, bytes or os.PathLike object, not NoneType

```


#### Additional information
```python
Platform:      Linux-5.4.0-72-generic-x86_64-with-glibc2.31
Python:        3.9.2 | packaged by conda-forge | (default, Feb 21 2021, 05:02:46)  [GCC 9.3.0]
Executable:    ~/anaconda3/envs/neo_mne/bin/python
CPU:           x86_64: 24 cores
Memory:        250.2 GB

mne:           0.23.0
numpy:         1.19.2 {blas=openblas, lapack=openblas}
scipy:         1.5.3
matplotlib:    3.3.4 {backend=module://ipykernel.pylab.backend_inline}

sklearn:       0.23.2
numba:         0.53.1
nibabel:       3.2.1
nilearn:       0.7.1
dipy:          1.2.0
cupy:          Not found
pandas:        1.2.4
mayavi:        4.7.2
pyvista:       0.29.1 {pyvistaqt=0.3.0, OpenGL 4.5.0 NVIDIA 390.143 via Quadro P5000/PCIe/SSE2}
vtk:           9.0.1
PyQt5:         5.12.3
```



Discussion:
Hello! 👋 Thanks for opening your first issue here! ❤️ We will try to get back to you soon. 🚴🏽‍♂️

Indeed we should check to see if it's None before trying to do any file-like operation on it. @timpx would you be up for making a PR to fix it?

Resolving patch:
diff --git a/mne/data/html_templates.py b/mne/data/html_templates.py
--- a/mne/data/html_templates.py
+++ b/mne/data/html_templates.py
@@ -65,10 +65,12 @@
 
 raw_template = Template("""
 {{info_repr[:-9]}}
+    {{if filenames}}
     <tr>
         <th>Filenames</th>
         <td>{{', '.join(filenames)}}</td>
     </tr>
+    {{endif}}
     <tr>
         <th>Duration</th>
         <td>{{duration}} (HH:MM:SS)</td>
diff --git a/mne/io/base.py b/mne/io/base.py
--- a/mne/io/base.py
+++ b/mne/io/base.py
@@ -1760,7 +1760,9 @@ def __repr__(self):  # noqa: D105
         return "<%s | %s>" % (self.__class__.__name__, s)
 
     def _repr_html_(self, caption=None):
-        basenames = [os.path.basename(f) for f in self._filenames]
+        basenames = [
+            os.path.basename(f) for f in self._filenames if f is not None
+        ]
         m, s = divmod(self._last_time - self.first_time, 60)
         h, m = divmod(m, 60)
         duration = f'{int(h):02d}:{int(m):02d}:{int(s):02d}'


Test patch:
diff --git a/mne/io/tests/test_raw.py b/mne/io/tests/test_raw.py
--- a/mne/io/tests/test_raw.py
+++ b/mne/io/tests/test_raw.py
@@ -556,9 +556,11 @@ def test_repr():
     """Test repr of Raw."""
     sfreq = 256
     info = create_info(3, sfreq)
-    r = repr(RawArray(np.zeros((3, 10 * sfreq)), info))
+    raw = RawArray(np.zeros((3, 10 * sfreq)), info)
+    r = repr(raw)
     assert re.search('<RawArray | 3 x 2560 (10.0 s), ~.* kB, data loaded>',
                      r) is not None, r
+    assert raw._repr_html_()
 
 
 # A class that sets channel data to np.arange, for testing _test_raw_reader