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