Repository: spyder-ide/spyder
Pull request: PR: Fix project workspace startup
<!--- Make sure to read the Contributing Guidelines:                   --->
<!--- https://github.com/spyder-ide/spyder/blob/master/CONTRIBUTING.md --->
<!--- and follow PEP 8, PEP 257 and Spyder's code style:               --->
<!--- https://github.com/spyder-ide/spyder/wiki/Dev:-Coding-Style      --->

## Description of Changes
Fix some race conditions and LSP call ordering to prevent project LSP malfunction. This is also required for testing https://github.com/palantir/python-language-server/pull/601

* [ ] Wrote at least one-line docstrings (for any new functions)
* [ ] Added unit test(s) covering the changes (if testable)
<!--- Remember that an image/animation is worth a thousand words! --->
* [ ] Included a screenshot or animation (if affecting the UI, see [Licecap](https://www.cockos.com/licecap/))


<!--- Explain what you've done and why --->




### Issue(s) Resolved

<!--- List the issue(s) below, in the form "Fixes #1234"; one per line --->

Fixes #9628


### Affirmation

By submitting this Pull Request or typing my (user)name below,
I affirm the [Developer Certificate of Origin](https://developercertificate.org)
with respect to all commits and content included in this PR,
and understand I am releasing the same under Spyder's MIT (Expat) license.

<!--- TYPE YOUR USER/NAME AFTER THE FOLLOWING: --->
I certify the above statement is true and correct:
@andfoy
<!--- Thanks for your help making Spyder better for everyone! --->


Problem statement:
Python LSP codeeditor configurations are being replaced each time a new LSP server is available
<!--- **PLEASE READ:** When submitting here, please ensure you've completed the following checklist and checked the boxes to confirm. Issue reports without it may be closed. Thanks! --->

## Problem Description

Sometimes when two or more LSP servers are launched after restoring the previous session files at startup, Python LSP settings get replaced by another language LSP settings. 

Additionally, sometimes, files do not start their introspection capabilities started, therefore, introspection services stop working completely, this may explain the project issues related to LSP.

Hints from issue discussion:

Commit message: Remove logging messages

Patch to review:
diff --git a/spyder/plugins/editor/plugin.py b/spyder/plugins/editor/plugin.py
index 4fd1086c4d4..384acc5c71f 100644
--- a/spyder/plugins/editor/plugin.py
+++ b/spyder/plugins/editor/plugin.py
@@ -287,27 +287,29 @@ def restore_scrollbar_position(self):
     def report_open_file(self, options):
         """Request to start a LSP server to attend a language."""
         filename = options['filename']
-        logger.debug('Call LSP for %s' % filename)
         language = options['language']
+        logger.debug('Call LSP for %s [%s]' % (filename, language))
         callback = options['codeeditor']
         stat = self.main.lspmanager.start_client(language.lower())
         self.main.lspmanager.register_file(
             language.lower(), filename, callback)
         if stat:
             if language.lower() in self.lsp_editor_settings:
+                logger.debug('{0} LSP is ready'.format(language))
                 self.lsp_server_ready(
                     language.lower(), self.lsp_editor_settings[
                         language.lower()])
             else:
-                editor = self.get_current_editor()
-                editor.lsp_ready = False
+                if callback.language == language.lower():
+                    logger.debug('Setting {0} LSP off'.filename)
+                    callback.lsp_ready = False
         if self.fallback_up:
             self.fallback_ready()
 
     @Slot(dict, str)
     def register_lsp_server_settings(self, settings, language):
         """Register LSP server settings."""
-        self.lsp_editor_settings[language] = settings
+        self.lsp_editor_settings[language] = dict(settings)
         logger.debug('LSP server settings for {!s} are: {!r}'.format(
             language, settings))
         self.lsp_server_ready(language, self.lsp_editor_settings[language])
@@ -323,7 +325,7 @@ def lsp_server_ready(self, language, configuration):
             editorstack.notify_server_ready(language, configuration)
 
     def send_lsp_request(self, language, request, params):
-        logger.debug("LSP request: %r" %request)
+        logger.debug("LSP request: %r" % request)
         self.main.lspmanager.send_request(language, request, params)
 
     def send_fallback_request(self, msg):
diff --git a/spyder/plugins/editor/widgets/codeeditor.py b/spyder/plugins/editor/widgets/codeeditor.py
index ac104260873..96405bcd8dd 100644
--- a/spyder/plugins/editor/widgets/codeeditor.py
+++ b/spyder/plugins/editor/widgets/codeeditor.py
@@ -865,7 +865,9 @@ def start_lsp_services(self, config):
             self.document_did_open()
 
     def stop_lsp_services(self):
+        logger.debug('Stopping LSP services for %s' % self.filename)
         self.lsp_ready = False
+        self.document_opened = False
 
     def parse_lsp_config(self, config):
         """Parse and load LSP server editor capabilities."""
diff --git a/spyder/plugins/projects/plugin.py b/spyder/plugins/projects/plugin.py
index 16a1c74e0b3..fac59b90015 100644
--- a/spyder/plugins/projects/plugin.py
+++ b/spyder/plugins/projects/plugin.py
@@ -285,6 +285,7 @@ def _create_project(self, path):
     def open_project(self, path=None, restart_consoles=True,
                      save_previous_files=True):
         """Open the project located in `path`"""
+        self.notify_project_open(path)
         self.switch_to_plugin()
         if path is None:
             basedir = get_home_dir()
@@ -325,7 +326,6 @@ def open_project(self, path=None, restart_consoles=True,
         self.sig_project_loaded.emit(path)
         self.sig_pythonpath_changed.emit()
         self.watcher.start(path)
-        self.notify_project_open(path)
 
         if restart_consoles:
             self.restart_consoles()


Code review comments:
diff_hunk: @@ -287,27 +287,29 @@ def restore_scrollbar_position(self):
     def report_open_file(self, options):
         """Request to start a LSP server to attend a language."""
         filename = options['filename']
-        logger.debug('Call LSP for %s' % filename)
         language = options['language']
+        logger.debug('Call LSP for %s [%s]' % (filename, language))
         callback = options['codeeditor']
path: spyder/plugins/editor/plugin.py
text: @user1:
Let's change the name of this variable to `codeeditor` because it's no longer a `callback`.

diff_hunk: @@ -287,27 +287,29 @@ def restore_scrollbar_position(self):
     def report_open_file(self, options):
         """Request to start a LSP server to attend a language."""
         filename = options['filename']
-        logger.debug('Call LSP for %s' % filename)
         language = options['language']
+        logger.debug('Call LSP for %s [%s]' % (filename, language))
         callback = options['codeeditor']
         stat = self.main.lspmanager.start_client(language.lower())
         self.main.lspmanager.register_file(
             language.lower(), filename, callback)
         if stat:
             if language.lower() in self.lsp_editor_settings:
+                logger.debug('{0} LSP is ready'.format(language))
                 self.lsp_server_ready(
                     language.lower(), self.lsp_editor_settings[
                         language.lower()])
             else:
-                editor = self.get_current_editor()
-                editor.lsp_ready = False
+                if callback.language == language.lower():
+                    logger.debug('Setting {0} LSP off'.filename)
path: spyder/plugins/editor/plugin.py
text: @user1:
This is wrong. It needs to be

    logger.debug('Setting {0} LSP off'.format(filename))