Repository: spyder-ide/spyder

Issue:
ValueError when opening array within array
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

```python
connection=np.dtype([
    ('value', np.bool, (1)),
    ('connection',np.bool, (N,N))   
])

grille=np.zeros((N,N),dtype=connection)
```

#Open variable explorer and selection from there the sub array in the connection window

### Traceback
```python-traceback
  File "C:\Users\joeda\Anaconda3\lib\site-packages\spyder\plugins\variableexplorer\widgets\arrayeditor.py", line 396, in createEditor
    value = not value
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
```

## Versions

* Spyder version: 4.1.3 
* Python version: 3.7.7
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Windows 10

### Dependencies

```

# Mandatory:
atomicwrites >=1.2.0           :  1.4.0 (OK)
chardet >=2.0.0                :  3.0.4 (OK)
cloudpickle >=0.5.0            :  1.4.1 (OK)
diff_match_patch >=20181111    :  20181111 (OK)
intervaltree                   :  None (OK)
IPython >=4.0                  :  7.13.0 (OK)
jedi =0.15.2                   :  0.15.2 (OK)
nbconvert >=4.0                :  5.6.1 (OK)
numpydoc >=0.6.0               :  0.9.2 (OK)
paramiko >=2.4.0               :  2.7.1 (OK)
parso =0.5.2                   :  0.5.2 (OK)
pexpect >=4.4.0                :  4.8.0 (OK)
pickleshare >=0.4              :  0.7.5 (OK)
psutil >=5.3                   :  5.7.0 (OK)
pygments >=2.0                 :  2.6.1 (OK)
pylint >=0.25                  :  2.5.2 (OK)
pyls >=0.31.9;<0.32.0          :  0.31.10 (OK)
qdarkstyle >=2.8               :  2.8.1 (OK)
qtawesome >=0.5.7              :  0.7.0 (OK)
qtconsole >=4.6.0              :  4.7.4 (OK)
qtpy >=1.5.0                   :  1.9.0 (OK)
rtree >=0.8.3                  :  0.9.4 (OK)
sphinx >=0.6.6                 :  3.0.3 (OK)
spyder_kernels >=1.9.1;<1.10.0 :  1.9.1 (OK)
watchdog                       :  None (OK)
zmq >=17                       :  18.1.1 (OK)

# Optional:
cython >=0.21                  :  0.29.17 (OK)
matplotlib >=2.0.0             :  3.1.3 (OK)
numpy >=1.7                    :  1.18.1 (OK)
pandas >=0.13.1                :  1.0.3 (OK)
scipy >=0.17.0                 :  1.4.1 (OK)
sympy >=0.7.3                  :  1.5.1 (OK)
```



Discussion:
Hi @J-bytes,

I'm able to reproduce this issue, we will fix it for a future release of Spyder

Thanks for reporting! 
I had a look at this. As the traceback shows, the problem occurs in

https://github.com/spyder-ide/spyder/blob/436290ba71bb16c5928676467a358b70f4f38c10/spyder/plugins/variableexplorer/widgets/arrayeditor.py#L391-L399

It is caused by `model._data.dtype.name` being `"bool"` not only when `value` is a boolean, but also when it is a numpy array of booleans.

A workaround that prevents an error from being thrown is to add the clause `and type(value) != np.ndarray` to line 395. Something shorter like `if type(value) == bool:` doesn't quite work because there are multiple scalar boolean types.

The deeper problem is that the array editor doesn't fully handle generic objects as elements of numpy arrays. As an example, consider
```
a = [1, 'abc', [1,4,'cd'], np.arange(4)]
b = np.array(a)
```
Variable `a` can be edited in the explorers without issue, but for variable `b` nothing can be done. Though I guess this is intentional since the title of the window contains "(read only)" when I open `b`.

It should be possible to open a new ArrayEditor, or even a CollectionsEditor, from within the ArrayEditor. That would result in more intuitive behaviour. But that is more than a one-liner and I don't know exactly how to implement it.

> A workaround that prevents an error from being thrown is to add the clause and type(value) != np.ndarray to line 395.

Great! Could you open a pull request with that change? Doing it against the `4.x` branch is fine in this case (since this is a bug).

> Though I guess this is intentional since the title of the window contains "(read only)" when I open b.

Yes, it is intentional because we don't have a reliable way to allow users editing object arrays (which is what `b` is, i.e. a mix of several objects).

> It should be possible to open a new ArrayEditor, or even a CollectionsEditor, from within the ArrayEditor. That would result in more intuitive behaviour. But that is more than a one-liner and I don't know exactly how to implement it.

No problem, that could be done later.
Sure, I'll make a pull request tonight.

Resolving patch:
diff --git a/spyder/plugins/variableexplorer/widgets/arrayeditor.py b/spyder/plugins/variableexplorer/widgets/arrayeditor.py
--- a/spyder/plugins/variableexplorer/widgets/arrayeditor.py
+++ b/spyder/plugins/variableexplorer/widgets/arrayeditor.py
@@ -392,7 +392,10 @@ def createEditor(self, parent, option, index):
         """Create editor widget"""
         model = index.model()
         value = model.get_value(index)
-        if model._data.dtype.name == "bool":
+        if type(value) == np.ndarray or model.readonly:
+            # The editor currently cannot properly handle this case
+            return
+        elif model._data.dtype.name == "bool":
             value = not value
             model.setData(index, to_qvariant(value))
             return


Test patch: