Repository: spyder-ide/spyder

Issue:
Add a check_compatibility method to PluginMixin
On 3.x

https://github.com/spyder-ide/spyder/blob/master/spyder/api/plugins.py

Create a new method for `class SpyderPluginWidget(PluginWidget):`

```python
# For instance Qt4 can be checked here or other things...

    def check_compatibility(self):
        """
        This method can be implemented to check compatibility of plugin on a given os.

        `message` should give information in case of non compatibility:
        For example: 'This plugin does not work with Qt4'
        """
        message = ''
        valid = True
        return valid, message

```

On top of this we need to change the loading of plugins to load it only if compatible

@ccordoba12, @andfoy, @rlaverde  comments, ideas?


Discussion:
I was thinking that in some cases, this function might be not called at all, for example, on Spyder Terminal we don't even expose the Plugin at all if the current Qt backend if different from ``PyQt5`` ([spyder_terminal/__init__.py](https://github.com/spyder-ide/spyder-terminal/blob/master/spyder_terminal/__init__.py))
in that case maybe we dont need such method ?

Maybe, it should be defined on each plugin's ``__init__.py``
What I don't like here, is that we have an orphan PLUGIN_CLASS, I would make it `None` at least

```python
from qtpy import PYQT5

PLUGIN_CLASS = None
if PYQT5:
    from .terminalplugin import TerminalPlugin as PLUGIN_CLASS

```


>  What I don't like here, is that we have an orphan PLUGIN_CLASS, I would make it None at least

To be changed on 3.1.2! 
@andfoy, the idea is to make changes in `spyder-terminal` so that is a message is shown when people try to run it with PyQt4.

So its compatibility is to depend on PyQt5.
`PLUGIN_COMPATIBLE = (True, '')` then? and check that in spyder

In the case of spyder-terminal check for Qt4 and build a message accordingly
So should we remove that try... except block instead?
>So should we remove that try... except block instead?

Probably
Yes, that's the idea, and use `check_compatibility` instead.

But @goanpeca, then `check_compatibility` should be the first thing to run in `register_plugin`, right? That way, if compatibility is not satisfied, the plugin would not continue the registering process, and will show a (non-modal) QMessageBox instead.
Sorry, `check_compatibility` has to be called in the `__init__` method of SpyderPluginWidget:

https://github.com/spyder-ide/spyder/blob/3.x/spyder/plugins/__init__.py#L539

That way it will be run every time a plugin is created.

@dalthviz, please add the `check_compatibility` method to SpyderPluginWidget with @goanpeca suggestion, then call it in its `__init__` method.

Resolving patch:
diff --git a/spyder/plugins/__init__.py b/spyder/plugins/__init__.py
--- a/spyder/plugins/__init__.py
+++ b/spyder/plugins/__init__.py
@@ -27,7 +27,7 @@
 from qtpy.QtCore import QEvent, QObject, QPoint, Qt, Signal
 from qtpy.QtGui import QCursor, QKeySequence
 from qtpy.QtWidgets import (QApplication, QDockWidget, QMainWindow,
-                            QShortcut, QTabBar, QWidget)
+                            QShortcut, QTabBar, QWidget, QMessageBox)
 
 # Local imports
 from spyder.config.base import _
@@ -538,12 +538,18 @@ class SpyderPluginWidget(QWidget, SpyderPluginMixin):
 
     if PYQT5:
         def __init__(self, parent, **kwds):
+            check_compatibility, message = self.check_compatibility()
             super(SpyderPluginWidget, self).__init__(parent, **kwds)
+            if not check_compatibility:
+                self.show_compatibility_message(message)
     else:
         def __init__(self, parent):
+            check_compatibility, message = self.check_compatibility()
             QWidget.__init__(self, parent)
             SpyderPluginMixin.__init__(self, parent)
-        
+            if not check_compatibility:
+                self.show_compatibility_message(message)
+
     def get_plugin_title(self):
         """
         Return plugin title
@@ -591,3 +597,25 @@ def get_plugin_actions(self):
     def register_plugin(self):
         """Register plugin in Spyder's main window"""
         raise NotImplementedError
+
+    def check_compatibility(self):
+        """
+        This method can be implemented to check compatibility of a plugin
+        for a given condition.
+
+        `message` should give information in case of non compatibility:
+        For example: 'This plugin does not work with Qt4'
+        """
+        message = ''
+        valid = True
+        return valid, message
+
+    def show_compatibility_message(self, message):
+        """Show compatibility message."""
+        messageBox = QMessageBox(self)
+        messageBox.setWindowModality(Qt.NonModal)
+        messageBox.setAttribute(Qt.WA_DeleteOnClose)
+        messageBox.setWindowTitle('Compatibility Check')
+        messageBox.setText(message)
+        messageBox.setStandardButtons(QMessageBox.Ok)
+        messageBox.show()


Test patch: