Repository: spyder-ide/spyder

Issue:
AttributeError: no attribute 'refresh_formatter_name' when opening Spyder
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

OS: Ubuntu 16.04.7 LTS  

Package Manager: conda 4.9.2  

System (as reported by Help > About Spyder...): Python 3.7.10 64-bit | Qt 5.9.6 | PyQt5 5.9.2 | Linux 4.15.0-133-generic   

Steps to reproduce: Create a new conda env and start Spyder. "Issue reporter" pop-up window immediately appears with the error contained herein.  

```
conda create -n spyder-env python=3.7 spyder=4  
conda activate spyder-env  
spyder  
```

I have used various Spyder 3 and 4 installs on this same Ubuntu machine for 2 years. However, today I created a new conda environment with Spyder 4, and ran into this error for the first time. I tested python=3.6, 3.7, 3.8, 3.9, and also not specifying a python version. All produced the same error. Note that despite the error, the Spyder GUI starts up and seems to function normally.  

### Traceback
```python-traceback
  File "/home/hchyde/anaconda3/envs/spyder-env/lib/python3.7/site-packages/spyder/app/mainwindow.py", line 2198, in update_source_menu
    self.editor.refresh_formatter_name()
AttributeError: 'NoneType' object has no attribute 'refresh_formatter_name'
```

## Versions

* Spyder version: 4.2.1 
* Python version: 3.7.10
* Qt version: 5.9.6
* PyQt5 version: 5.9.2
* Operating System: Linux 4.15.0-136-generic

### Dependencies

```

# Mandatory:
atomicwrites >=1.2.0            :  1.4.0 (OK)
chardet >=2.0.0                 :  4.0.0 (OK)
cloudpickle >=0.5.0             :  1.6.0 (OK)
diff_match_patch >=20181111     :  20200713 (OK)
intervaltree >=3.0.2            :  3.1.0 (OK)
IPython >=7.6.0                 :  7.21.0 (OK)
jedi =0.17.2                    :  0.17.2 (OK)
jsonschema >=3.2.0              :  3.2.0 (OK)
keyring >=17.0.0                :  22.3.0 (OK)
nbconvert >=4.0                 :  6.0.7 (OK)
numpydoc >=0.6.0                :  1.1.0 (OK)
parso =0.7.0                    :  0.7.0 (OK)
pexpect >=4.4.0                 :  4.8.0 (OK)
pickleshare >=0.4               :  0.7.5 (OK)
psutil >=5.3                    :  5.8.0 (OK)
pygments >=2.0                  :  2.8.0 (OK)
pylint >=1.0                    :  2.7.2 (OK)
pyls >=0.36.2;<1.0.0            :  0.36.2 (OK)
pyls_black >=0.4.6              :  0.4.6 (OK)
pyls_spyder >=0.3.0             :  0.3.2 (OK)
qdarkstyle >=2.8                :  2.8.1 (OK)
qtawesome >=0.5.7               :  1.0.1 (OK)
qtconsole >=5.0.1               :  5.0.2 (OK)
qtpy >=1.5.0                    :  1.9.0 (OK)
rtree >=0.8.3                   :  0.9.4 (OK)
setuptools >=39.0.0             :  52.0.0.post20210125 (OK)
sphinx >=0.6.6                  :  3.5.1 (OK)
spyder_kernels >=1.10.1;<1.11.0 :  1.10.2 (OK)
textdistance >=4.2.0            :  4.2.1 (OK)
three_merge >=0.1.1             :  0.1.1 (OK)
watchdog >=0.10.3               :  1.0.2 (OK)
xdg >=0.26                      :  0.27 (OK)
zmq >=17                        :  20.0.0 (OK)

# Optional:
cython >=0.21                   :  None (NOK)
matplotlib >=2.0.0              :  None (NOK)
numpy >=1.7                     :  None (NOK)
pandas >=1.1.1                  :  None (NOK)
scipy >=0.17.0                  :  None (NOK)
sympy >=0.7.3                   :  None (NOK)
```



Discussion:
Hi @hchyde,

Can you please install the latest Spyder version in a new environment from conda forge channel? Please let me know if the error persists in this new env.
@steff456: Yes, the same problem persists when installed from the conda forge channel. My guess is that it's related to QT 5 and/or pyqt interaction with Spyder 4. Here is what I have found so far via troubleshooting, specifically import of the qtawesome Editor plugin and/or creation of a QApplication instance.
  
**Environment with startup error**  
Spyder 4.2.3 | Python 3.7.10 64-bit | Qt 5.12.9 | PyQt5 5.12.3 | Linux 4.15.0-136-generic  
Path: ~/anaconda3/envs/spyder4/lib/python3.7/site-packages/spyder/app/mainwindow.py  
```
from spyder.plugins.editor.plugin import Editor  # mainwindow.py:837
```
> Command executes with warning below

```
~/anaconda3/envs/spyder4/lib/python3.7/site-packages/qtawesome/iconic_font.py:313: UserWarning: You need to have a running QApplication to use QtAwesome!  
warnings.warn("You need to have a running " 
```

**Environment without startup error**
Spyder 3.3.6 | Python 3.7.9 64-bit | Qt 5.9.6 | PyQt5 5.9.2 | Linux 4.15.0-136-generic   
Path: ~/anaconda3/envs/spyder3/lib/python3.7/site-packages/spyder/app/mainwindow.py  
```
from spyder.plugins.editor.plugin import Editor  # mainwindow.py:844
```
> Command executes without warning
 
The Spyder 4 version produces the error regardless of preferences combinations I tested below:

_Preferences > Appearance >_   
**Main interface:**  
  Interface theme = {Automatic, Light, Dark}  
  Qt windows style = Fusion (cannot change)  
  Icon theme = {Spyder 3, Spyder 2}  
    
**Syntax highlighting theme:**  
  {Spyder Dark, IDLE, Emacs, ...}  

@steff456: I have now tested all my conda environments. The following Spyder 4.1.5 environment does **not** produce the startup error on my system, so the issue must have appeared sometime _after_ that release:

**Environment without startup error (Spyder 4.1.5)**
Spyder 4.1.5 | Python 3.7.7 64-bit | Qt 5.6.2 | PyQt5 5.6 | Linux 4.15.0-136-generic

Do you have any extra dependency in the rest of the environments were the error is happening?
There are no extra dependencies. For debugging here, I am starting with a fresh minimal conda environment. I sequentially created new environments with different Spyder release versions and found that Spyder 4.1.5 was the last version that does **not** produce an error upon startup. Starting with Spyder 4.2.0, I get the error upon startup.

Spyder 4.1.5 | Python 3.7.10 64-bit | Qt 5.9.6 | PyQt5 5.9.2 | Linux 4.15.0-136-generic
```
conda create -n spyder415 python=3.7 spyder=4.1.5
conda activate spyder415
spyder
```
> No problems

Spyder 4.2.0 | Python 3.7.10 64-bit | Qt 5.9.6 | PyQt5 5.9.2 | Linux 4.15.0-136-generic 
```
conda create -n spyder420 python=3.7 spyder=4.2.0
conda activate spyder420
spyder
```
> Starts up with error
```
"File /home/hchyde/anaconda3/envs/spyder420/lib/python3.7/site-packages/spyder/app/mainwindow.py", line 2271, in update_source_menu
self.editor.refresh_formatter_name()
AttributeError: 'NoneType' object has no attribute 'refresh_formatter_name'
```
The error occurs within a function named `update_source_menu` (which seems to be new in Spyder versions > 4.1.5). Here is the respective source code in app/mainwindow.py:2269
```
def update_source_menu(self):
        """Update source menu options that vary dynamically."""
        self.editor.refresh_formatter_name()
```
where `refresh_formatter_name` is defined in plugins/editor/plugin.py:1641
```
def refresh_formatter_name(self):
    formatter = CONF.get('lsp-server', 'formatting')
    self.formatting_action.setText(
        _('Format file or selection with {0}').format(
            formatter.capitalize()))
```
Line numbers above correspond to version 4.2.0. It seems a bit challenging to debug this error since it occurs before or during creation of the GUI. Is it possible to enable (or access) Spyder startup logs? Any other debugging tips?

FYI: I am using Kite in my Spyder environments.
I found the `--debug-info` launch option. Below is the output when starting Spyder 4.2.3 in debug mode, which shows the traceback for the error in question (which occurs for all versions >= 4.2.0 on this machine). FYI: The error also persists if the `--safe-mode` option is additionally used. 
```
(base) ~$ conda activate spyder423
(spyder423) ~$ spyder
(spyder423) ~$ spyder --debug-info minimal
2021-03-10 23:19:58,310 [INFO] [spyder.app.mainwindow] -> Start of MainWindow constructor
2021-03-10 23:19:58,715 [INFO] [spyder.app.mainwindow] -> End of MainWindow constructor
2021-03-10 23:19:58,807 [INFO] [spyder.app.mainwindow] -> *** Start of MainWindow setup ***
2021-03-10 23:19:58,807 [INFO] [spyder.app.mainwindow] -> Updating PYTHONPATH
2021-03-10 23:19:58,807 [INFO] [spyder.app.mainwindow] -> Applying theme configuration...
2021-03-10 23:19:58,809 [INFO] [qdarkstyle] -> QSS file sucessfuly loaded.
2021-03-10 23:19:58,809 [INFO] [qdarkstyle] -> Found application patches to be applied.
2021-03-10 23:19:58,817 [INFO] [spyder.app.mainwindow] -> Creating core actions...
2021-03-10 23:19:58,818 [INFO] [spyder.app.mainwindow] -> Creating toolbars...
2021-03-10 23:19:58,836 [INFO] [spyder.app.mainwindow] -> Creating Tools menu...
2021-03-10 23:19:58,840 [INFO] [spyder.app.mainwindow] -> Creating guidata and sift entries...
2021-03-10 23:19:58,842 [INFO] [spyder.app.mainwindow] -> Loading switcher...
2021-03-10 23:19:58,852 [INFO] [spyder.app.mainwindow] -> Loading internal console...
2021-03-10 23:19:58,870 [INFO] [spyder.plugins.console.plugin] -> Initializing...
2021-03-10 23:19:58,940 [INFO] [spyder.app.mainwindow] -> Starting code completion manager...
2021-03-10 23:19:59,084 [INFO] [spyder.app.mainwindow] -> Loading working directory...
2021-03-10 23:19:59,124 [INFO] [spyder.app.mainwindow] -> Loading help...
2021-03-10 23:19:59,249 [INFO] [spyder.app.mainwindow] -> Loading outline explorer...
Traceback (most recent call last):
  File "/home/hchyde/anaconda3/envs/spyder423/lib/python3.7/site-packages/spyder/app/mainwindow.py", line 2190, in update_source_menu
    self.editor.refresh_formatter_name()
AttributeError: 'NoneType' object has no attribute 'refresh_formatter_name'
2021-03-10 23:19:59,270 [INFO] [spyder.app.mainwindow] -> Loading editor...
2021-03-10 23:19:59,368 [INFO] [spyder.app.mainwindow] -> Loading namespace browser...
2021-03-10 23:19:59,385 [INFO] [spyder.app.mainwindow] -> Loading figure browser...
2021-03-10 23:19:59,398 [INFO] [spyder.app.mainwindow] -> Loading history plugin...
2021-03-10 23:19:59,450 [INFO] [spyder.app.mainwindow] -> Loading IPython console...
2021-03-10 23:19:59,524 [INFO] [spyder.app.mainwindow] -> Loading file explorer...
2021-03-10 23:19:59,569 [INFO] [spyder.app.mainwindow] -> Loading online help...
2021-03-10 23:19:59,632 [INFO] [spyder.app.mainwindow] -> Loading project explorer...
2021-03-10 23:20:00,055 [INFO] [spyder.app.mainwindow] -> Loading third-party plugins...
2021-03-10 23:20:00,068 [INFO] [spyder.app.mainwindow] -> Setting up main window...
2021-03-10 23:20:00,148 [INFO] [spyder.app.mainwindow] -> Setting up window...
2021-03-10 23:20:00,209 [INFO] [spyder.app.mainwindow] -> *** End of MainWindow setup ***
2021-03-10 23:20:00,315 [INFO] [spyder.app.mainwindow] -> Deleting previous Spyder instance LSP logs...
2021-03-10 23:20:00,559 [INFO] [spyder.plugins.ipythonconsole.utils.kernelspec] -> Kernel command: ['/home/hchyde/anaconda3/envs/spyder423/bin/python', '-m', 'spyder_kernels.console', '-f', '{connection_file}']
2021-03-10 23:20:01,714 [INFO] [spyder.plugins.completion.languageserver.plugin] -> Starting LSP client for python...
2021-03-10 23:20:01,715 [INFO] [spyder.plugins.completion.languageserver.client] -> Starting server: /home/hchyde/anaconda3/envs/spyder423/bin/python -m pyls --host 127.0.0.1 --port 2087 --tcp --check-parent-process --log-file /home/hchyde/.config/spyder-py3/lsp_logs/server_python_6963.log -v
2021-03-10 23:20:01,720 [INFO] [spyder.plugins.completion.languageserver.client] -> Starting transport for python: /home/hchyde/anaconda3/envs/spyder423/bin/python -u /home/hchyde/anaconda3/envs/spyder423/lib/python3.7/site-packages/spyder/plugins/completion/languageserver/transport/main.py --folder /home/hchyde/.config/spyder-py3/lsp_paths/root_path --transport-debug 2 --server-host 127.0.0.1 --server-port 2087  --zmq-in-port 33767 --zmq-out-port 40007 --external-server
```

Resolving patch:
diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py
--- a/spyder/app/mainwindow.py
+++ b/spyder/app/mainwindow.py
@@ -2187,7 +2187,12 @@ def valid_project(self):
 
     def update_source_menu(self):
         """Update source menu options that vary dynamically."""
-        self.editor.refresh_formatter_name()
+        # This is necessary to avoid an error at startup.
+        # Fixes spyder-ide/spyder#14901
+        try:
+            self.editor.refresh_formatter_name()
+        except AttributeError:
+            pass
 
     def free_memory(self):
         """Free memory after event."""


Test patch: