Repository: scikit-hep/awkward

Issue:
`NumpyLike.to_rectilinear` fails for NumPy arrays
### Version of Awkward Array

1.8.3rc0

### Description and code to reproduce

This bug is most easily triggered when invoking a NumPy function with a rectilinear Awkward argument and NumPy rectilinear argument, e.g. `np.isin`:
```pycon
>>> reference = np.r_[1,2,3,4]
>>> test = ak.Array([1,2,9,0])
>>> np.isin(test, reference)
```

which gives the following traceback:

```pytb
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 5, in isin
  File "/home/angus/Git/awkward-1.0/awkward/highlevel.py", line 1440, in __array_function__
    return ak._connect._numpy.array_function(func, types, args, kwargs)
  File "/home/angus/Git/awkward-1.0/awkward/_connect/_numpy.py", line 40, in array_function
    args = tuple(_to_rectilinear(x) for x in args)
  File "/home/angus/Git/awkward-1.0/awkward/_connect/_numpy.py", line 40, in <genexpr>
    args = tuple(_to_rectilinear(x) for x in args)
  File "/home/angus/Git/awkward-1.0/awkward/_connect/_numpy.py", line 32, in _to_rectilinear
    return nplike.to_rectilinear(arg, allow_missing=False)
  File "/home/angus/Git/awkward-1.0/awkward/nplike.py", line 422, in to_rectilinear
    return [self.to_rectilinear(x, *args, **kwargs) for x in array]
  File "/home/angus/Git/awkward-1.0/awkward/nplike.py", line 422, in <listcomp>
    return [self.to_rectilinear(x, *args, **kwargs) for x in array]
  File "/home/angus/Git/awkward-1.0/awkward/nplike.py", line 425, in to_rectilinear
    raise TypeError("to_rectilinear argument must be iterable")
TypeError: to_rectilinear argument must be iterable
```

I think we need to handle the case where an array is `np.ndarray`. 


Discussion:

Resolving patch:
diff --git a/src/awkward/nplike.py b/src/awkward/nplike.py
--- a/src/awkward/nplike.py
+++ b/src/awkward/nplike.py
@@ -400,7 +400,10 @@ def __call__(self, *args):
 
 class Numpy(NumpyLike):
     def to_rectilinear(self, array, *args, **kwargs):
-        if isinstance(
+        if isinstance(array, numpy.ndarray):
+            return array
+
+        elif isinstance(
             array,
             (
                 ak.Array,


Test patch:
diff --git a/tests/test_1247-numpy-to_rectilinear-ndarray.py b/tests/test_1247-numpy-to_rectilinear-ndarray.py
new file mode 100644
--- /dev/null
+++ b/tests/test_1247-numpy-to_rectilinear-ndarray.py
@@ -0,0 +1,13 @@
+# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE
+
+import pytest  # noqa: F401
+import numpy as np  # noqa: F401
+import awkward as ak  # noqa: F401
+
+
+def test():
+    array = np.array([1, 2, 9, 0])
+    nplike = ak.nplike.of(array)
+
+    ak_array = ak.from_numpy(array)
+    assert ak.to_list(nplike.to_rectilinear(array)) == ak.to_list(ak_array)
diff --git a/tests/v2/test_1247-numpy-to_rectilinear-ndarray.py b/tests/v2/test_1247-numpy-to_rectilinear-ndarray.py
new file mode 100644
--- /dev/null
+++ b/tests/v2/test_1247-numpy-to_rectilinear-ndarray.py
@@ -0,0 +1,12 @@
+# BSD 3-Clause License; see https://github.com/scikit-hep/awkward-1.0/blob/main/LICENSE
+
+import pytest  # noqa: F401
+import numpy as np  # noqa: F401
+import awkward as ak  # noqa: F401
+
+
+def test():
+    array = np.array([1, 2, 9, 0])
+    nplike = ak.nplike.of(array)
+    ak_array = ak._v2.operations.convert.from_numpy(array)
+    assert nplike.to_rectilinear(array).tolist() == ak_array.tolist()