Repository: spyder-ide/spyder

Issue:
 TypeError in object explorer
## Problem Description
I used the statsmodels package for nominal logistic regression **in spyder IDE 4.0.0b4**, when I double click to return results, there is an error viewing the variables,the result like this:
![image](https://user-images.githubusercontent.com/1759365/62448960-9f2f4580-b79b-11e9-8889-c296a4d01f47.png)

When I double click the "rslt",an error occurs:
![image](https://user-images.githubusercontent.com/1759365/62449070-f6cdb100-b79b-11e9-8ad1-3fbac88248e0.png)

Details as follow:

<details>
```python-traceback
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\spyder\plugins\variableexplorer\widgets\objectexplorer\tree_model.py", line 267, in fetchMore
    parent_item.obj_path)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\spyder\plugins\variableexplorer\widgets\objectexplorer\tree_model.py", line 322, in _fetchObjectChildren
    for attr_name, attr_value in sorted(inspect.getmembers(obj)):
  File "d:\ProgramData\Anaconda3\envs\python37\lib\inspect.py", line 341, in getmembers
    value = getattr(object, key)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\statsmodels\base\wrapper.py", line 41, in __getattribute__
    obj = data.wrap_output(obj, how=how)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\statsmodels\base\data.py", line 413, in wrap_output
    return self.attach_rows(obj)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\statsmodels\base\data.py", line 552, in attach_rows
    columns=self.ynames)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\frame.py", line 424, in __init__
    copy=copy)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\internals\construction.py", line 158, in init_ndarray
    index, columns = _get_axes(*values.shape, index=index, columns=columns)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\internals\construction.py", line 375, in _get_axes
    columns = ensure_index(columns)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\indexes\base.py", line 5378, in ensure_index
    return Index(index_like)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\indexes\base.py", line 468, in __new__
    cls._scalar_data_error(data)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\indexes\base.py", line 3799, in _scalar_data_error
    repr(data)))
TypeError: Index(...) must be called with a collection of some kind, '科目' was passed
Traceback (most recent call last):
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\spyder\plugins\variableexplorer\widgets\objectexplorer\tree_model.py", line 267, in fetchMore
    parent_item.obj_path)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\spyder\plugins\variableexplorer\widgets\objectexplorer\tree_model.py", line 322, in _fetchObjectChildren
    for attr_name, attr_value in sorted(inspect.getmembers(obj)):
  File "d:\ProgramData\Anaconda3\envs\python37\lib\inspect.py", line 341, in getmembers
    value = getattr(object, key)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\statsmodels\base\wrapper.py", line 41, in __getattribute__
    obj = data.wrap_output(obj, how=how)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\statsmodels\base\data.py", line 413, in wrap_output
    return self.attach_rows(obj)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\statsmodels\base\data.py", line 552, in attach_rows
    columns=self.ynames)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\frame.py", line 424, in __init__
    copy=copy)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\internals\construction.py", line 158, in init_ndarray
    index, columns = _get_axes(*values.shape, index=index, columns=columns)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\internals\construction.py", line 375, in _get_axes
    columns = ensure_index(columns)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\indexes\base.py", line 5378, in ensure_index
    return Index(index_like)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\indexes\base.py", line 468, in __new__
    cls._scalar_data_error(data)
  File "d:\ProgramData\Anaconda3\envs\python37\lib\site-packages\pandas\core\indexes\base.py", line 3799, in _scalar_data_error
    repr(data)))
TypeError: Index(...) must be called with a collection of some kind, '科目' was passed
</details>

I also used **spyder IDE 3.3.6**,The 'rslt' variable shows ok:
![image](https://user-images.githubusercontent.com/1759365/62449369-9a1ec600-b79c-11e9-8635-370b5c40681f.png)

### Paste Traceback/Error Below (if applicable)
<!--- Copy from error dialog or View > Panes > Internal Console --->

```python-traceback

PASTE TRACEBACK HERE

```

## Versions
<!--- You can get this information from Help > About Spyder...
or (if Spyder won't launch) the "conda list" command
from the Anaconda Prompt/Terminal/command line. --->

* Spyder version: 4.0.0b4
* Python version: 
* Qt version: 
* PyQt version: 
* Operating System name/version:win7 

### Dependencies
<!--- Please go to the menu entry Help > Dependencies,
press the Copy to clipboard button and paste below --->

```
PASTE DEPENDENCIES HERE
```



Discussion:
Thanks for reporting. Please post a simple code that generates the `rslt` object you're trying to inspect in the Variable Explorer.
```python
import pandas as pd
import statsmodels.api as sm
subject = ['数学','自然科学','自然科学','数学','数学','自然科学','数学','数学',
           '艺术','自然科学','艺术','数学','自然科学','自然科学','艺术','自然科学',
           '自然科学','自然科学','艺术','数学','数学','艺术','艺术','数学','艺术',
           '艺术','数学','自然科学','数学','艺术']
age = [10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,
       13,13,13,13,13,13,13,13]
rsp = pd.Series(subject,name='sub')
pvar_con = pd.Series(age,name='age')
X = sm.add_constant(pvar_con)
model = sm.MNLogit(rsp,X)
rslt = model.fit()
```
Thanks for the quick response @leavor! We'll try to fix this for our next beta.

@dalthviz, please take a look at this one.

Resolving patch:
diff --git a/spyder/plugins/variableexplorer/widgets/objectexplorer/tree_model.py b/spyder/plugins/variableexplorer/widgets/objectexplorer/tree_model.py
--- a/spyder/plugins/variableexplorer/widgets/objectexplorer/tree_model.py
+++ b/spyder/plugins/variableexplorer/widgets/objectexplorer/tree_model.py
@@ -14,7 +14,6 @@
 
 # Standard library imports
 import logging
-import inspect
 from difflib import SequenceMatcher
 from collections import OrderedDict
 
@@ -317,19 +316,20 @@ def _fetchObjectChildren(self, obj, obj_path):
         assert len(obj_children) == len(path_strings), "sanity check"
         is_attr_list = [False] * len(obj_children)
 
-        try:
-            # Object attributes
-            for attr_name, attr_value in sorted(inspect.getmembers(obj)):
+        # Object attributes
+        # Needed to handle errors while getting object's attributes
+        # Related with spyder-ide/spyder#6728 and spyder-ide/spyder#9959
+        for attr_name in dir(obj):
+            try:
+                attr_value = getattr(obj, attr_name)
                 obj_children.append((attr_name, attr_value))
-                path_strings.append('{}.{}'.format(obj_path,
-                                    attr_name) if obj_path else attr_name)
+                path_strings.append('{}.{}'.format(obj_path, attr_name)
+                                    if obj_path else attr_name)
                 is_attr_list.append(True)
-
-            assert len(obj_children) == len(path_strings), "sanity check"
-        except ValueError:
-            # Needed to handle errors while getting object's attributes
-            # Related with spyder-ide/spyder#6728
-            pass
+            except Exception:
+                # Attribute could not be get
+                pass
+        assert len(obj_children) == len(path_strings), "sanity check"
         tree_items = []
         for item, path_str, is_attr in zip(obj_children, path_strings,
                                            is_attr_list):


Test patch:
diff --git a/spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py b/spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py
--- a/spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py
+++ b/spyder/plugins/variableexplorer/widgets/objectexplorer/tests/test_objectexplorer.py
@@ -47,6 +47,13 @@ def __init__(self):
 
         def get_text(self):
             return self.text
+
+        @property
+        def error_attribute(self):
+            # Attribute to test that the object explorer
+            # handles errors by getattr gracefully
+            raise AttributeError
+
     foobar = Foobar()
     editor = objectexplorer(foobar,
                             name='foobar',