Repository: spyder-ide/spyder

Issue:
Open project error
Hello!
When I use "Project > Open project" to open an existing project, I have this error:

```python-traceback
  File "/usr/lib/python3.6/site-packages/spyder/plugins/projects.py", line 145, in <lambda>
    lambda v: self.editor.setup_open_files())
  File "/usr/lib/python3.6/site-packages/spyder/plugins/editor.py", line 2707, in setup_open_files
    filenames = self.reorder_filenames(filenames)
  File "/usr/lib/python3.6/site-packages/spyder/plugins/editor.py", line 2733, in reorder_filenames
    splitsettings = layout.get('splitsettings')
AttributeError: 'NoneType' object has no attribute 'get'
```

* Spyder Version: 4dev (master)
* Python Version: 3.6
* Qt Version: 5.9
* PyQt Version: 5.9
* Operating system: Arch Linux


Discussion:
@rlaverde, I think this is related to the reordering of files in Projects you introduced in PR #4880.

Resolving patch:
diff --git a/spyder/plugins/editor.py b/spyder/plugins/editor.py
--- a/spyder/plugins/editor.py
+++ b/spyder/plugins/editor.py
@@ -2730,6 +2730,8 @@ def reorder_filenames(self, filenames):
         layout settings.
         """
         layout = self.get_option('layout_settings', None)
+        if layout is None:
+            return filenames
         splitsettings = layout.get('splitsettings')
         index_first_file = 0
         reordered_splitsettings = []


Test patch:
diff --git a/spyder/plugins/tests/test_editor.py b/spyder/plugins/tests/test_editor.py
new file mode 100644
--- /dev/null
+++ b/spyder/plugins/tests/test_editor.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright © Spyder Project Contributors
+# Licensed under the terms of the MIT License
+#
+"""Tests for the Editor plugin."""
+
+# Third party imports
+import pytest
+
+try:
+    from unittest.mock import Mock
+except ImportError:
+    from mock import Mock  # Python 2
+
+from qtpy.QtWidgets import QWidget
+
+
+@pytest.fixture
+def setup_editor(qtbot, monkeypatch):
+    """Set up the Editor plugin."""
+    monkeypatch.setattr('spyder.dependencies', Mock())
+    from spyder.plugins.editor import Editor
+
+    monkeypatch.setattr('spyder.plugins.editor.IntrospectionManager', Mock())
+    monkeypatch.setattr('spyder.plugins.editor.add_actions', Mock())
+
+    class MainMock(QWidget):
+        def __getattr__(self, attr):
+            if attr.endswith('actions'):
+                return []
+            else:
+                return Mock()
+
+    editor = Editor(MainMock())
+    qtbot.addWidget(editor)
+    editor.show()
+
+    return editor, qtbot
+
+
+def test_basic_initialization(setup_editor):
+    """Test Editor plugin initialization."""
+    editor, qtbot = setup_editor
+
+    # Assert that editor exists
+    assert editor is not None
+
+
+@pytest.mark.parametrize(
+    'filenames, expected_filenames, splitsettings, expected_splitsettings', [
+        (['/file1.py', '/file2.py', '/file3.py', '/file4.py'],
+         ['/file1.py', '/file2.py', '/file3.py', '/file4.py'],
+         [(False, '/other_file.py', [2, 4, 8, 12])],
+         [(False, '/file1.py', [2, 4, 8, 12])]),
+        (['/file1.py', '/file2.py', '/file3.py', '/file4.py'],
+         ['/file2.py', '/file1.py', '/file3.py', '/file4.py'],
+         [(False, '/file2.py', [2, 4, 8, 12])],
+         [(False, '/file2.py', [2, 2, 8, 12])]),
+        (['/file1.py', '/file2.py', '/file3.py', '/file4.py'],
+         ['/file1.py', '/file2.py', '/file3.py', '/file4.py'],
+         None,
+         None, )
+    ])
+def test_reorder_filenames(setup_editor, expected_filenames, filenames,
+                           splitsettings, expected_splitsettings):
+    editor, qtbot = setup_editor
+
+    def get_option(*args):
+        if splitsettings is None:
+            return None
+        return {'splitsettings': splitsettings}
+
+    def set_option(name, layout_settings):
+        assert layout_settings['splitsettings'] == expected_splitsettings
+
+    editor.get_option = get_option
+    editor.set_option = set_option
+
+    assert expected_filenames == editor.reorder_filenames(filenames)