Repository: napari/napari

Issue:
Warnings are displayed when new label is added
## 🐛 Bug

When adding a new label a warning is displayed in Windows and Mac

## To Reproduce

Steps to reproduce the behavior:

1. Open napari
2. Click on File -> Open Sample -> napari -> "any option"
3. Click on any of the buttons on the layer list
4. Pay attention to warnings


## Expected behavior

Warning should not be displayed


https://user-images.githubusercontent.com/63799148/157496090-8f1052b8-a4cc-4b54-877d-d133624ae5ba.mov



## Environment

napari: 0.4.15rc3
Platform: Windows-10-10.0.17763-SP0
Python: 3.8.12 | packaged by conda-forge | (default, Oct 12 2021, 21:22:46) [MSC v.1916 64 bit (AMD64)]
Qt: 5.12.9
PySide2: 5.13.2
NumPy: 1.22.3
SciPy: 1.8.0
Dask: 2022.02.1
VisPy: 0.9.6

napari: 0.4.15rc3
Platform: macOS-11.6.4-x86_64-i386-64bit
System: MacOS 11.6.4
Python: 3.9.10 | packaged by conda-forge | (main, Feb 1 2022, 21:28:27) [Clang 11.1.0 ]
Qt: 5.12.9
PySide2: 5.13.2
NumPy: 1.22.3
SciPy: 1.8.0
Dask: 2022.02.1
VisPy: 0.9.6




Discussion:
Ah! This is what I was seeing the other day, also on macOS (12.2.1) but arm64.
https://github.com/napari/napari/issues/3568#issuecomment-1061049259


Resolving patch:
diff --git a/napari/utils/misc.py b/napari/utils/misc.py
--- a/napari/utils/misc.py
+++ b/napari/utils/misc.py
@@ -8,6 +8,7 @@
 import os
 import re
 import sys
+import warnings
 from enum import Enum, EnumMeta
 from os import fspath
 from os import path as os_path
@@ -458,6 +459,12 @@ def ensure_list_of_layer_data_tuple(val):
     )
 
 
+def _quiet_array_equal(*a, **k):
+    with warnings.catch_warnings():
+        warnings.filterwarnings("ignore", "elementwise comparison")
+        return np.array_equal(*a, **k)
+
+
 def pick_equality_operator(obj) -> Callable[[Any, Any], bool]:
     """Return a function that can check equality between ``obj`` and another.
 
@@ -486,11 +493,11 @@ def pick_equality_operator(obj) -> Callable[[Any, Any], bool]:
     # yes, it's a little riskier, but we are checking namespaces instead of
     # actual `issubclass` here to avoid slow import times
     _known_arrays = {
-        'numpy.ndarray': np.array_equal,  # numpy.ndarray
+        'numpy.ndarray': _quiet_array_equal,  # numpy.ndarray
         'dask.Array': operator.is_,  # dask.array.core.Array
         'dask.Delayed': operator.is_,  # dask.delayed.Delayed
         'zarr.Array': operator.is_,  # zarr.core.Array
-        'xarray.DataArray': np.array_equal,  # xarray.core.dataarray.DataArray
+        'xarray.DataArray': _quiet_array_equal,  # xarray.core.dataarray.DataArray
     }
     for base in type_.mro():
         key = f'{base.__module__.split(".", maxsplit=1)[0]}.{base.__name__}'


Test patch:
diff --git a/napari/layers/points/_tests/test_points.py b/napari/layers/points/_tests/test_points.py
--- a/napari/layers/points/_tests/test_points.py
+++ b/napari/layers/points/_tests/test_points.py
@@ -930,7 +930,6 @@ def test_out_of_slice_display():
     assert layer.out_of_slice_display is True
 
 
-@pytest.mark.filterwarnings("ignore:elementwise comparison fail:FutureWarning")
 @pytest.mark.parametrize("attribute", ['edge', 'face'])
 def test_switch_color_mode(attribute):
     """Test switching between color modes"""
diff --git a/napari/layers/shapes/_tests/test_shapes.py b/napari/layers/shapes/_tests/test_shapes.py
--- a/napari/layers/shapes/_tests/test_shapes.py
+++ b/napari/layers/shapes/_tests/test_shapes.py
@@ -1342,7 +1342,6 @@ def test_blending():
     assert layer.blending == 'opaque'
 
 
-@pytest.mark.filterwarnings("ignore:elementwise comparison fail:FutureWarning")
 @pytest.mark.parametrize("attribute", ['edge', 'face'])
 def test_switch_color_mode(attribute):
     """Test switching between color modes"""
diff --git a/napari/layers/vectors/_tests/test_vectors.py b/napari/layers/vectors/_tests/test_vectors.py
--- a/napari/layers/vectors/_tests/test_vectors.py
+++ b/napari/layers/vectors/_tests/test_vectors.py
@@ -475,7 +475,6 @@ def test_edge_color_map_non_numeric_property():
         layer.edge_color_mode = 'colormap'
 
 
-@pytest.mark.filterwarnings("ignore:elementwise comparis:FutureWarning:numpy")
 def test_switching_edge_color_mode():
     """Test transitioning between all color modes"""
     np.random.seed(0)
diff --git a/napari/utils/_tests/test_misc.py b/napari/utils/_tests/test_misc.py
--- a/napari/utils/_tests/test_misc.py
+++ b/napari/utils/_tests/test_misc.py
@@ -6,6 +6,7 @@
 
 from napari.utils.misc import (
     StringEnum,
+    _quiet_array_equal,
     abspath_or_url,
     ensure_iterable,
     ensure_sequence_of_iterables,
@@ -185,10 +186,14 @@ def test_equality_operator():
     class MyNPArray(np.ndarray):
         pass
 
-    assert pick_equality_operator(np.ones((1, 1))) == np.array_equal
-    assert pick_equality_operator(MyNPArray([1, 1])) == np.array_equal
+    assert pick_equality_operator(np.ones((1, 1))) == _quiet_array_equal
+    assert pick_equality_operator(MyNPArray([1, 1])) == _quiet_array_equal
     assert pick_equality_operator(da.ones((1, 1))) == operator.is_
     assert pick_equality_operator(zarr.ones((1, 1))) == operator.is_
     assert (
-        pick_equality_operator(xr.DataArray(np.ones((1, 1)))) == np.array_equal
+        pick_equality_operator(xr.DataArray(np.ones((1, 1))))
+        == _quiet_array_equal
     )
+    eq = pick_equality_operator(np.asarray([]))
+    # make sure this doesn't warn
+    assert not eq(np.asarray([]), np.asarray([], '<U32'))