Repository: regionmask/regionmask

Issue:
better error when passing a single numpy array as coordinates
I had it happen more than once to do the following:

```python
import numpy as np
import regionmask

outline = np.array([[-80.0, 50.0], [-80.0, 28.0], [-100.0, 28.0], [-100.0, 50.0]])
region = regionmask.Regions(outline)
```

but this raises

```python-traceback
ValueError: Outline must be 2D
```

which is not terribly helpful. Because the correct pattern is 

```python
region = regionmask.Regions([outline])
```
thus, a better error message is in order. Something along the lines:

```python-traceback
ValueError: Cannot pass a single numpy array as region - please pass it as a list.
```





Discussion:

Patch:
diff --git a/docs/whats_new.rst b/docs/whats_new.rst
index 516139d..5a4c3b7 100644
--- a/docs/whats_new.rst
+++ b/docs/whats_new.rst
@@ -28,6 +28,7 @@ Enhancements
   regions (:pull:`361`, :issue:`346`).
 - The masking functions (e.g. :py:meth:`Regions.mask`) now warn if the `units` of the
   coordinates(``lat.attrs["units"]`` ) are given as "radians" (:issue:`279`).
+- Better error when passing a single region without wrapping it into a list or tuple (:issue:`372`).
 
 Deprecations
 ~~~~~~~~~~~~
diff --git a/regionmask/core/regions.py b/regionmask/core/regions.py
index 122a161..cf4d03f 100644
--- a/regionmask/core/regions.py
+++ b/regionmask/core/regions.py
@@ -91,6 +91,12 @@ class Regions:
         overlap=False,
     ):
 
+        if isinstance(outlines, (np.ndarray, Polygon, MultiPolygon)):
+            klass = type(outlines).__name__
+            raise ValueError(
+                f"Cannot pass a single {klass} as region - please pass it as a list."
+            )
+
         if numbers is None:
             numbers = range(len(outlines))
 
@@ -548,12 +554,15 @@ class _OneRegion:
             outline = np.asarray(outline)
 
             if outline.ndim != 2:
-                raise ValueError("Outline must be 2D")
+                raise ValueError(
+                    "Outline must be 2D. Did you pass a single region and need to wrap "
+                    "it in a list?"
+                )
 
             if outline.shape[1] != 2:
                 raise ValueError("Outline must have Nx2 elements")
 
-            self._coords = np.array(outline)
+            self._coords = outline
 
     def __repr__(self):
 


Test patch:
diff --git a/regionmask/tests/test_Regions.py b/regionmask/tests/test_Regions.py
index 2a47b37..7b227b1 100644
--- a/regionmask/tests/test_Regions.py
+++ b/regionmask/tests/test_Regions.py
@@ -29,6 +29,7 @@ abbrevs_dict = {1: "uSq1", 2: "uSq2"}
 poly1 = Polygon(outl1)
 poly2 = Polygon(outl2)
 poly = {1: poly1, 2: poly2}
+multipoly = MultiPolygon([poly1, poly2])
 
 test_regions2 = Regions(poly, numbers2, names_dict, abbrevs_dict, name=name)
 
@@ -48,6 +49,13 @@ all_first_numbers = (0, 1, 2)
 # =============================================================================
 
 
+def test_regions_single_region():
+
+    for o in [np.array(outl1), poly1, multipoly]:
+        with pytest.raises(ValueError, match="Cannot pass a single"):
+            Regions(o)
+
+
 @pytest.mark.parametrize("test_regions", all_test_regions)
 def test_len(test_regions):
     assert len(test_regions) == 2