Plugins/PluginPipInterface.py

changeset 6342
c79ecba9cde7
parent 6076
b784925fb174
child 6645
ad476851d7e0
diff -r a00e63f6d766 -r c79ecba9cde7 Plugins/PluginPipInterface.py
--- a/Plugins/PluginPipInterface.py	Tue Jun 12 18:59:45 2018 +0200
+++ b/Plugins/PluginPipInterface.py	Tue Jun 12 19:01:06 2018 +0200
@@ -9,15 +9,12 @@
 
 from __future__ import unicode_literals
 
-import os
-import platform
 
-from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication, QProcess
+from PyQt5.QtCore import pyqtSignal, QObject, QCoreApplication
 
 from E5Gui.E5Application import e5App
 
 import Preferences
-import Utilities
 import UI.Info
 
 # Start-Of-Header
@@ -58,19 +55,17 @@
             "PipInterfacePlugin", "Package Management - pip"),
         "exe": "dummyExe",
         "versionCommand": "--version",
-        "versionStartsWith": "dummyExe",
+        "versionStartsWith": "pip",
         "versionPosition": 1,
         "version": "",
         "versionCleanup": None,
+        "exeModule": ["-m", "pip"],
     }
-    if pipPluginObject is not None:
-        executables = pipPluginObject.getPreferences("PipExecutables")
-        if not executables:
-            executables = ["pip3", "pip2", "pip"]
-        for exePath in executables:
-            data["exe"] = exePath
-            data["versionStartsWith"] = "pip"
-            dataList.append(data.copy())
+    virtualenvManager = e5App().getObject("VirtualEnvManager")
+    for venvName in virtualenvManager.getVirtualenvNames():
+        interpreter = virtualenvManager.getVirtualenvInterpreter(venvName)
+        data["exe"] = interpreter
+        dataList.append(data.copy())
     return dataList
 
 
@@ -111,142 +106,16 @@
     Preferences.Prefs.settings.remove(PipInterfacePlugin.PreferencesKey)
 
 
-def _findDefaultExecutables(majorVersion):
-    """
-    Restricted function to determine the name and path of the executables.
-    
-    @param majorVersion major python version of the executables (int)
-    @return path names of the executables (list of string)
-    """
-    # Determine Python Version
-    if majorVersion == 3:
-        minorVersions = range(10)
-    elif majorVersion == 2:
-        minorVersions = range(6, 8)
-    else:
-        return []
-    
-    executables = set()
-    if Utilities.isWindowsPlatform():
-        #
-        # Windows
-        #
-        try:
-            import winreg
-        except ImportError:
-            import _winreg as winreg    # __IGNORE_WARNING__
-        
-        def getExePath(branch, access, versionStr):
-            exes = []
-            try:
-                software = winreg.OpenKey(branch, 'Software', 0, access)
-                python = winreg.OpenKey(software, 'Python', 0, access)
-                pcore = winreg.OpenKey(python, 'PythonCore', 0, access)
-                version = winreg.OpenKey(pcore, versionStr, 0, access)
-                installpath = winreg.QueryValue(version, 'InstallPath')
-                exe = os.path.join(installpath, 'Scripts', 'pip.exe')
-                if os.access(exe, os.X_OK):
-                    exes.append(exe)
-            except (WindowsError, OSError):   # __IGNORE_WARNING__
-                pass
-            return exes
-        
-        versionSuffixes = ["", "-32", "-64"]
-        for minorVersion in minorVersions:
-            for versionSuffix in versionSuffixes:
-                versionStr = '{0}.{1}{2}'.format(majorVersion, minorVersion,
-                                                 versionSuffix)
-                exePaths = getExePath(
-                    winreg.HKEY_CURRENT_USER,
-                    winreg.KEY_WOW64_32KEY | winreg.KEY_READ, versionStr)
-                for exePath in exePaths:
-                    executables.add(exePath)
-                
-                exePaths = getExePath(
-                    winreg.HKEY_LOCAL_MACHINE,
-                    winreg.KEY_WOW64_32KEY | winreg.KEY_READ, versionStr)
-                for exePath in exePaths:
-                    executables.add(exePath)
-                
-                # Even on Intel 64-bit machines it's 'AMD64'
-                if platform.machine() == 'AMD64':
-                    exePaths = getExePath(
-                        winreg.HKEY_CURRENT_USER,
-                        winreg.KEY_WOW64_64KEY | winreg.KEY_READ, versionStr)
-                    for exePath in exePaths:
-                        executables.add(exePath)
-                    
-                    exePath = getExePath(
-                        winreg.HKEY_LOCAL_MACHINE,
-                        winreg.KEY_WOW64_64KEY | winreg.KEY_READ, versionStr)
-                    for exePath in exePaths:
-                        executables.add(exePath)
-    else:
-        #
-        # Linux, Unix ...
-        pipScript = 'pip'
-        scriptSuffixes = ["",
-                          "{0}".format(majorVersion),
-                          "-{0}".format(majorVersion),
-                          ]
-        for minorVersion in minorVersions:
-            scriptSuffixes.append(
-                "{0}.{1}".format(majorVersion, minorVersion))
-            scriptSuffixes.append(
-                "-{0}.{1}".format(majorVersion, minorVersion))
-        # There could be multiple pip executables in the path
-        # e.g. for different python variants
-        path = Utilities.getEnvironmentEntry('PATH')
-        # environment variable not defined
-        if path is None:
-            return []
-        
-        # step 1: determine possible candidates
-        exes = []
-        dirs = path.split(os.pathsep)
-        for directory in dirs:
-            for suffix in scriptSuffixes:
-                exe = os.path.join(directory, pipScript + suffix)
-                if os.access(exe, os.X_OK):
-                    exes.append(exe)
-        
-        # step 2: determine the Python variant
-        _exePy2 = set()
-        _exePy3 = set()
-        versionArgs = ["-c", "import sys; print(sys.version_info[0])"]
-        for exe in exes:
-            try:
-                f = open(exe, "r")
-                line0 = f.readline()
-                program = line0.replace("#!", "").strip()
-                process = QProcess()
-                process.start(program, versionArgs)
-                process.waitForFinished(5000)
-                # get a QByteArray of the output
-                versionBytes = process.readAllStandardOutput()
-                versionStr = str(versionBytes, encoding='utf-8').strip()
-                if versionStr == "3":
-                    _exePy3.add(exe)
-                elif versionStr == "2":
-                    _exePy2.add(exe)
-            finally:
-                f.close()
-        
-        executables = _exePy3 if majorVersion == 3 else _exePy2
-    
-    return list(executables)
-
-
 class PipInterfacePlugin(QObject):
     """
     Class implementing the pip interface plug-in.
     
-    @signal currentPipChanged(exe) emitted to signal a change of the current
-        pip executable
+    @signal currentEnvironmentChanged(str) emitted to signal a change of the
+        currently selected virtual environment
     """
     PreferencesKey = "PipPlugin"
     
-    currentPipChanged = pyqtSignal(str)
+    currentEnvironmentChanged = pyqtSignal(str)
     
     def __init__(self, ui):
         """
@@ -259,8 +128,7 @@
         self.__initialize()
         
         self.__defaults = {
-            "PipExecutables": [],
-            "CurrentPipExecutable": "",
+            "CurrentEnvironment": "",
             "PipSearchIndex": "",           # used by the search command
         }
     
@@ -277,7 +145,8 @@
         """
         Public method to activate this plugin.
         
-        @return tuple of None and activation status (boolean)
+        @return tuple of None and activation status
+        @rtype tuple of (None, bool)
         """
         global error
         error = ""     # clear previous error
@@ -294,23 +163,6 @@
         self.__mainMenu = self.__object.initMenu()
         self.__mainAct = menu.addMenu(self.__mainMenu)
         
-        if self.getPreferences("PipExecutables"):
-            # remove all executables, that don't exist anymore
-            executables = []
-            for executable in self.getPreferences("PipExecutables"):
-                if os.access(executable, os.X_OK):
-                    executables.append(executable)
-            self.setPreferences("PipExecutables", executables)
-            
-            current = self.getPreferences("CurrentPipExecutable")
-            if current not in executables:
-                current = ""
-                self.setPreferences("CurrentPipExecutable", current)
-        else:
-            # load the list with default executables
-            self.setPreferences("PipExecutables",
-                                self.getDefaultPipExecutables())
-        
         return None, True
     
     def deactivate(self):
@@ -327,38 +179,40 @@
     
     def getPreferences(self, key):
         """
-        Public method to retrieve the various refactoring settings.
+        Public method to retrieve the various pip related settings.
         
         @param key the key of the value to get
-        @return the requested refactoring setting
+        @type str
+        @return the requested setting
+        @rtype any
         """
-        if key in ["PipExecutables"]:
-            return Preferences.toList(Preferences.Prefs.settings.value(
-                self.PreferencesKey + "/" + key, self.__defaults[key]))
-        else:
-            return Preferences.Prefs.settings.value(
-                self.PreferencesKey + "/" + key, self.__defaults[key])
+        return Preferences.Prefs.settings.value(
+            self.PreferencesKey + "/" + key, self.__defaults[key])
     
     def setPreferences(self, key, value):
         """
-        Public method to store the various refactoring settings.
+        Public method to store the various pip related settings.
         
-        @param key the key of the setting to be set (string)
+        @param key the key of the setting to be set
+        @type str
         @param value the value to be set
+        @type any
         """
         Preferences.Prefs.settings.setValue(
             self.PreferencesKey + "/" + key, value)
         
-        if key == "CurrentPipExecutable":
-                self.currentPipChanged.emit(value)
+        if key == "CurrentEnvironment":
+                self.currentEnvironmentChanged.emit(value)
     
     def getMenu(self, name):
         """
         Public method to get a reference to the requested menu.
         
-        @param name name of the menu (string)
-        @return reference to the menu (QMenu) or None, if no
+        @param name name of the menu
+        @type str
+        @return reference to the menu or None, if no
             menu with the given name exists
+        @rtype  QMenu or None
         """
         if self.__object is not None:
             return self.__object.getMenu(name)
@@ -369,20 +223,13 @@
         """
         Public method to get the names of all menus.
         
-        @return menu names (list of string)
+        @return menu names
+        @rtype list of str
         """
         if self.__object is not None:
             return list(self.__menus.keys())
         else:
             return []
-    
-    def getDefaultPipExecutables(self):
-        """
-        Public method to get the default list of pip executables.
-        
-        @return list of pip executables (list of string)
-        """
-        return _findDefaultExecutables(2) + _findDefaultExecutables(3)
 
 #
 # eflag: noqa = M801

eric ide

mercurial