diff --git a/spyder/plugins/projects/utils/watcher.py b/spyder/plugins/projects/utils/watcher.py
index b11ed519b16..f23a2a563cf 100644
--- a/spyder/plugins/projects/utils/watcher.py
+++ b/spyder/plugins/projects/utils/watcher.py
@@ -7,19 +7,17 @@
"""Watcher to detect filesystem changes in the project's directory."""
# Standard lib imports
+import os
import logging
# Third-party imports
from qtpy.QtCore import QObject, Signal
-from qtpy.QtWidgets import QMessageBox
from superqt.utils import qthrottled
import watchdog
-from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler, PatternMatchingEventHandler
+from watchdog.observers.polling import PollingObserverVFS
# Local imports
-from spyder.config.base import _
-from spyder.py3compat import to_text_string
from spyder.config.utils import get_edit_extensions
@@ -142,42 +140,26 @@ def connect_signals(self, project):
self.sig_file_modified.connect(project.file_modified)
def start(self, workspace_folder):
- # Needed to handle an error caused by the inotify limit reached.
- # See spyder-ide/spyder#10478
+ # We use a polling observer because:
+ # * It doesn't introduce long freezes on Linux when switching git
+ # branches that have many changes between them. That's because the
+ # OS-based observer (i.e. inotify) generates way too many events.
+ # * The OS-based observer on Windows has many shortcomings (see
+ # openmsi/openmsistream#56).
+ # * There doesn't seem to be issues on Mac, but it's simpler to use a
+ # single observer for all OSes.
+ self.observer = PollingObserverVFS(stat=os.stat, listdir=os.scandir)
+
+ self.observer.schedule(
+ self.event_handler, workspace_folder, recursive=True
+ )
+
try:
- self.observer = Observer()
- self.observer.schedule(
- self.event_handler, workspace_folder, recursive=True)
- try:
- self.observer.start()
- except OSError:
- # This error happens frequently on Linux
- logger.debug("Watcher could not be started.")
- except OSError as e:
- self.observer = None
- if u'inotify' in to_text_string(e):
- QMessageBox.warning(
- self.parent(),
- "Spyder",
- _("File system changes for this project can't be tracked "
- "because it contains too many files. To fix this you "
- "need to increase the inotify limit in your system, "
- "with the following command:"
- "
"
- ""
- "sudo sysctl -n -w fs.inotify.max_user_watches=524288"
- "
"
- "
For a permanent solution you need to add to"
- "/etc/sysctl.conf
"
- "the following line:
"
- ""
- "fs.inotify.max_user_watches=524288"
- "
"
- "
"
- "After doing that, you need to close and start Spyder "
- "again so those changes can take effect."))
- else:
- raise e
+ self.observer.start()
+ except Exception:
+ logger.debug(
+ f"Observer could not be started for: {workspace_folder}."
+ )
def stop(self):
if self.observer is not None: