Repository: napari/napari

Issue:
Allow Path object in `magic_read`
## 🚀 Feature
<!-- A clear and concise description of the feature proposal -->

## Motivation
I tend to use `pahtlib.Path` objects a lot for path manipulation, and passing such an object to `io.magic_read` fails due to:
```py
    if len(filenames) == 0:
        return None
```

`Path` object should be accepted as input to `magic_read`

Allow Path object in `magic_read`
## 🚀 Feature
<!-- A clear and concise description of the feature proposal -->

## Motivation
I tend to use `pahtlib.Path` objects a lot for path manipulation, and passing such an object to `io.magic_read` fails due to:
```py
    if len(filenames) == 0:
        return None
```

`Path` object should be accepted as input to `magic_read`



Discussion:

Resolving patch:
diff --git a/napari/components/viewer_model.py b/napari/components/viewer_model.py
--- a/napari/components/viewer_model.py
+++ b/napari/components/viewer_model.py
@@ -470,7 +470,8 @@ def add_image(
         visible : bool
             Whether the layer visual is currently being displayed.
         path : str or list of str
-            Path or list of paths to image data.
+            Path or list of paths to image data. Paths can be passed as strings
+            or `pathlib.Path` instances.
 
         Returns
         -------
diff --git a/napari/util/io.py b/napari/util/io.py
--- a/napari/util/io.py
+++ b/napari/util/io.py
@@ -1,5 +1,7 @@
 import os
+
 from glob import glob
+from pathlib import Path
 
 import numpy as np
 from skimage import io
@@ -18,7 +20,9 @@ def magic_imread(filenames, *, use_dask=None, stack=True):
     Parameters
     -------
     filenames : list
-        List of filenames or directories to be opened
+        List of filenames or directories to be opened.
+        A list of `pathlib.Path` objects and a single filename or `Path` object
+        are also accepted.
     use_dask : bool
         Whether to use dask to create a lazy array, rather than NumPy.
         Default of None will resolve to True if filenames contains more than
@@ -32,6 +36,10 @@ def magic_imread(filenames, *, use_dask=None, stack=True):
     image : array-like
         Array or list of images
     """
+    # cast Path to string
+    if isinstance(filenames, Path):
+        filenames = filenames.as_posix()
+
     if len(filenames) == 0:
         return None
     if isinstance(filenames, str):
diff --git a/napari/view_layers.py b/napari/view_layers.py
--- a/napari/view_layers.py
+++ b/napari/view_layers.py
@@ -85,7 +85,8 @@ def view_image(
     visible : bool
         Whether the layer visual is currently being displayed.
     path : str or list of str
-        Path or list of paths to image data.
+        Path or list of paths to image data. Paths can be passed as strings
+        or `pathlib.Path` instances.
     title : string
         The title of the viewer window.
     ndisplay : {2, 3}


Test patch:
diff --git a/napari/util/tests/test_io.py b/napari/util/tests/test_io.py
--- a/napari/util/tests/test_io.py
+++ b/napari/util/tests/test_io.py
@@ -1,4 +1,6 @@
 import os
+from pathlib import Path
+
 import numpy as np
 from dask import array as da
 from skimage.data import data_dir
@@ -50,6 +52,20 @@ def test_single_png_defaults(single_png):
     assert images.shape == (512, 512)
 
 
+def test_single_png_single_file(single_png):
+    image_files = single_png[0]
+    images = io.magic_imread(image_files)
+    assert isinstance(images, np.ndarray)
+    assert images.shape == (512, 512)
+
+
+def test_single_png_pathlib(single_png):
+    image_files = Path(single_png[0])
+    images = io.magic_imread(image_files)
+    assert isinstance(images, np.ndarray)
+    assert images.shape == (512, 512)
+
+
 def test_multi_png_defaults(two_pngs):
     image_files = two_pngs
     images = io.magic_imread(image_files)
@@ -57,6 +73,13 @@ def test_multi_png_defaults(two_pngs):
     assert images.shape == (2, 512, 512)
 
 
+def test_multi_png_pathlib(two_pngs):
+    image_files = [Path(png) for png in two_pngs]
+    images = io.magic_imread(image_files)
+    assert isinstance(images, da.Array)
+    assert images.shape == (2, 512, 512)
+
+
 def test_multi_png_no_dask(two_pngs):
     image_files = two_pngs
     images = io.magic_imread(image_files, use_dask=False)