Repository: pandas-dev/pandas
Pull request: BUG: Handle nested arrays in array_equivalent_object
- [x] closes #30841
- [x] tests added / passed
- [x] passes `black pandas`
- [x] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [x] whatsnew entry


Problem statement:
TestBaseCasting.test_to_numpy fails for ExtensionArrays that yield nested numpy arrays
The test case fails when data is e.g. `np.array([np.array([np.nan, None], dtype="object"), None], dtype="object")`. 

```python
def test_to_numpy(self, data):
        expected = np.asarray(data)

        result = data.to_numpy()
>       self.assert_equal(result, expected)

```

This happens in `fletcher` for the `list<item: string>` type.

Hints from issue discussion:

Commit message: BUG: Handle nested arrays in array_equivalent_object

Patch to review:
diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst
index 77e19953ba970..adbdee9276c1c 100755
--- a/doc/source/whatsnew/v1.0.0.rst
+++ b/doc/source/whatsnew/v1.0.0.rst
@@ -1074,6 +1074,7 @@ Other
 - Bug in :class:`DataFrame` constructor when passing a 2D ``ndarray`` and an extension dtype (:issue:`12513`)
 - Bug in :meth:`DaataFrame.to_csv` when supplied a series with a ``dtype="string"`` and a ``na_rep``, the ``na_rep`` was being truncated to 2 characters. (:issue:`29975`)
 - Bug where :meth:`DataFrame.itertuples` would incorrectly determine whether or not namedtuples could be used for dataframes of 255 columns (:issue:`28282`)
+- Handle nested NumPy ``object`` arrays in :func:`~pandas/core/dtypes/missing.array_equivalent` (:issue:`30841`)
 
 .. ---------------------------------------------------------------------------
 
diff --git a/pandas/_libs/lib.pyx b/pandas/_libs/lib.pyx
index 2b8ba06aa8a82..719db5c03f07f 100644
--- a/pandas/_libs/lib.pyx
+++ b/pandas/_libs/lib.pyx
@@ -19,7 +19,7 @@ PyDateTime_IMPORT
 
 import numpy as np
 cimport numpy as cnp
-from numpy cimport (ndarray, PyArray_GETITEM,
+from numpy cimport (ndarray, PyArray_Check, PyArray_GETITEM,
                     PyArray_ITER_DATA, PyArray_ITER_NEXT, PyArray_IterNew,
                     flatiter, NPY_OBJECT,
                     int64_t, float32_t, float64_t,
@@ -524,8 +524,11 @@ def array_equivalent_object(left: object[:], right: object[:]) -> bool:
         # we are either not equal or both nan
         # I think None == None will be true here
         try:
-            if not (PyObject_RichCompareBool(x, y, Py_EQ) or
-                    (x is None or is_nan(x)) and (y is None or is_nan(y))):
+            if PyArray_Check(x) and PyArray_Check(y):
+                if not array_equivalent_object(x, y):
+                    return False
+            elif not (PyObject_RichCompareBool(x, y, Py_EQ) or
+                      (x is None or is_nan(x)) and (y is None or is_nan(y))):
                 return False
         except TypeError as err:
             # Avoid raising TypeError on tzawareness mismatch
diff --git a/pandas/tests/dtypes/test_missing.py b/pandas/tests/dtypes/test_missing.py
index 7d4811857db5f..7ba59786bb0fa 100644
--- a/pandas/tests/dtypes/test_missing.py
+++ b/pandas/tests/dtypes/test_missing.py
@@ -294,6 +294,11 @@ def test_array_equivalent():
         np.array([np.nan, None], dtype="object"),
         np.array([np.nan, None], dtype="object"),
     )
+    # Check the handling of nested arrays in array_equivalent_object
+    assert array_equivalent(
+        np.array([np.array([np.nan, None], dtype="object"), None], dtype="object"),
+        np.array([np.array([np.nan, None], dtype="object"), None], dtype="object"),
+    )
     assert array_equivalent(
         np.array([np.nan, 1 + 1j], dtype="complex"),
         np.array([np.nan, 1 + 1j], dtype="complex"),


Code review comments:
diff_hunk: @@ -1074,6 +1074,7 @@ Other
 - Bug in :class:`DataFrame` constructor when passing a 2D ``ndarray`` and an extension dtype (:issue:`12513`)
 - Bug in :meth:`DaataFrame.to_csv` when supplied a series with a ``dtype="string"`` and a ``na_rep``, the ``na_rep`` was being truncated to 2 characters. (:issue:`29975`)
 - Bug where :meth:`DataFrame.itertuples` would incorrectly determine whether or not namedtuples could be used for dataframes of 255 columns (:issue:`28282`)
+- Handle nested NumPy ``object`` arrays in :func:`~pandas/core/dtypes/missing.array_equivalent` (:issue:`30841`)
path: doc/source/whatsnew/v1.0.0.rst
text: @user1:
This `:func:` link will not work (and it's also not a public function anyway), but I think you can mention it is in the pandas.testing.assert_frame/series_equal methods, as it is there eventually this array_equivalent is being used?