--- a/ProjectPyramid/Project.py Sat Mar 31 13:41:00 2018 +0200 +++ b/ProjectPyramid/Project.py Sat Jun 23 17:45:53 2018 +0200 @@ -108,6 +108,10 @@ self.__plugin = plugin self.__ui = parent self.__e5project = e5App().getObject("Project") + try: + self.__virtualEnvManager = e5App().getObject("VirtualEnvManager") + except KeyError: + self.__virtualEnvManager = None self.__hooksInstalled = False self.__menus = {} # dictionary with references to menus @@ -569,7 +573,7 @@ def __getExecutablePaths(self, file): """ - Private method to build all full path of an executable file from + Private method to build all full paths of an executable file from the environment. @param file filename of the executable (string) @@ -623,27 +627,50 @@ if fullCmd != cmd: variants.append(variant) else: - try: - fullCmds = Utilities.getExecutablePaths(cmd) - except AttributeError: - fullCmds = self.__getExecutablePaths(cmd) - for fullCmd in fullCmds: + if cmd: try: - f = open(fullCmd, 'r', encoding='utf-8') - l0 = f.readline() - f.close() - except (IOError, OSError): - l0 = "" - if variant.lower() in l0.lower() or \ - "{0}.".format(variant[-1]) in l0 or \ - (variant == "Python2" and - "python3" not in l0.lower() and - "python" in l0.lower()): - variants.append(variant) - break + fullCmds = Utilities.getExecutablePaths(cmd) + except AttributeError: + fullCmds = self.__getExecutablePaths(cmd) + for fullCmd in fullCmds: + try: + f = open(fullCmd, 'r', encoding='utf-8') + l0 = f.readline() + f.close() + except (IOError, OSError): + l0 = "" + if self.__isSuitableForVariant(variant, l0): + variants.append(variant) + break return variants + def __isSuitableForVariant(self, variant, line0): + """ + Private method to test, if a detected command file is suitable for the + given Python variant. + + @param variant Python variant to test for + @type str (one of Python2 or Python3) + @param line0 first line of the executable + @type str + @return flag indicating a suitable command + @rtype bool + """ + assert variant in ("Python2", "Python3") + + l0 = line0.lower() + ok = (variant.lower() in l0 or + "{0}.".format(variant[-1]) in l0) + if variant == "Python2": + ok |= "python3" not in l0 and "python" in l0 + ok |= "pypy2" in l0 + ok |= "pypy3" not in l0 and "pypy" in l0 + else: + ok |= "pypy3" in l0 + + return ok + def __getVirtualEnvironment(self, language=""): """ Private method to get the path of the virtual environment. @@ -654,12 +681,34 @@ """ if not language: language = self.__e5project.getProjectLanguage() - if language == "Python3": - virtEnv = self.__plugin.getPreferences("VirtualEnvironmentPy3") - elif language == "Python2": - virtEnv = self.__plugin.getPreferences("VirtualEnvironmentPy2") + if self.__virtualEnvManager: + if language == "Python3": + venvName = self.__plugin.getPreferences( + "VirtualEnvironmentNamePy3") + elif language == "Python2": + venvName = self.__plugin.getPreferences( + "VirtualEnvironmentNamePy2") + else: + venvName = "" + if venvName: + virtEnv = self.__virtualEnvManager.getVirtualenvDirectory( + venvName) + if not virtEnv: + virtEnv = os.path.dirname( + self.__virtualEnvManager.getVirtualenvInterpreter( + venvName)) + if virtEnv.endswith(("Scripts", "bin")): + virtEnv = os.path.dirname(virtEnv) + else: + virtEnv = "" else: - virtEnv = "" + # backward compatibility + if language == "Python3": + virtEnv = self.__plugin.getPreferences("VirtualEnvironmentPy3") + elif language == "Python2": + virtEnv = self.__plugin.getPreferences("VirtualEnvironmentPy2") + else: + virtEnv = "" if virtEnv and not os.path.exists(virtEnv): virtEnv = "" return virtEnv @@ -674,23 +723,40 @@ """ if not language: language = self.__e5project.getProjectLanguage() - if language == "Python3": - debugEnv = Preferences.getDebugger("Python3Interpreter") - if not debugEnv and sys.version_info[0] == 3: - debugEnv = sys.executable - elif language == "Python2": - debugEnv = Preferences.getDebugger("PythonInterpreter") - if not debugEnv and sys.version_info[0] == 2: - debugEnv = sys.executable + if self.__virtualEnvManager: + debugEnv = self.__getVirtualEnvironment(language) + if not debugEnv: + if language == "Python3": + venvName = Preferences.getDebugger("Python3VirtualEnv") + elif language == "Python2": + venvName = Preferences.getDebugger("Python2VirtualEnv") + else: + venvName = "" + + if venvName: + debugEnv = self.__virtualEnvManager.getVirtualenvDirectory( + venvName) + else: + debugEnv = "" else: - debugEnv = sys.executable - debugEnv = os.path.dirname(debugEnv) - if debugEnv and not os.path.exists(debugEnv): - if (language == "Python3" and sys.version_info[0] == 3) or \ - (language == "Python2" and sys.version_info[0] == 2): - debugEnv = sys.exec_prefix + # backward compatibility + if language == "Python3": + debugEnv = Preferences.getDebugger("Python3Interpreter") + if not debugEnv and sys.version_info[0] == 3: + debugEnv = sys.executable + elif language == "Python2": + debugEnv = Preferences.getDebugger("PythonInterpreter") + if not debugEnv and sys.version_info[0] == 2: + debugEnv = sys.executable else: - debugEnv = "" + debugEnv = sys.executable + debugEnv = os.path.dirname(debugEnv) + if debugEnv and not os.path.exists(debugEnv): + if (language == "Python3" and sys.version_info[0] == 3) or \ + (language == "Python2" and sys.version_info[0] == 2): + debugEnv = sys.exec_prefix + else: + debugEnv = "" return debugEnv def getPyramidCommand(self, cmd, language=""): @@ -702,6 +768,9 @@ for (string, one of '', 'Python2' or 'Python3') @return full pyramid command (string) """ + if not language: + language = self.__e5project.getProjectLanguage() + virtualEnv = self.__getVirtualEnvironment(language) if isWindowsPlatform() and not virtualEnv: virtualEnv = self.__getDebugEnvironment(language) @@ -733,52 +802,74 @@ @return python command (string) """ language = self.__e5project.getProjectLanguage() - virtualEnv = self.__getVirtualEnvironment() - if isWindowsPlatform(): - pythonExeList = ["python.exe", "pypy.exe"] - if not virtualEnv: - virtualEnv = self.__getDebugEnvironment(language) - for pythonExe in pythonExeList: - for python in [ - os.path.join(virtualEnv, "Scripts", pythonExe), - os.path.join(virtualEnv, "bin", pythonExe), - os.path.join(virtualEnv, pythonExe) - ]: - if os.path.exists(python): - break - else: - python = "" - - if python: - break + if self.__virtualEnvManager: + if language == "Python3": + venvName = self.__plugin.getPreferences( + "VirtualEnvironmentNamePy3") + if not venvName: + # if none configured, use the global one + venvName = Preferences.getDebugger("Python3VirtualEnv") + elif language == "Python2": + venvName = self.__plugin.getPreferences( + "VirtualEnvironmentNamePy2") + if not venvName: + # if none configured, use the global one + venvName = Preferences.getDebugger("Python2VirtualEnv") + else: + venvName = "" + if venvName: + python = self.__virtualEnvManager.getVirtualenvInterpreter( + venvName) else: python = "" else: - if language == "Python3": - pythonExeList = ["python3", "pypy3"] - elif language == "Python2": - pythonExeList = ["python2", "pypy2"] - if not virtualEnv: - virtualEnv = self.__getDebugEnvironment(language) - - for pythonExe in pythonExeList: - for python in [ - os.path.join(virtualEnv, "bin", pythonExe), - # omit the version character - os.path.join(virtualEnv, "bin", pythonExe)[:-1], - os.path.join(virtualEnv, pythonExe), - # omit the version character - os.path.join(virtualEnv, pythonExe)[:-1], - ]: - if os.path.exists(python): + # backward compatibility + virtualEnv = self.__getVirtualEnvironment() + if isWindowsPlatform(): + pythonExeList = ["python.exe", "pypy.exe"] + if not virtualEnv: + virtualEnv = self.__getDebugEnvironment(language) + for pythonExe in pythonExeList: + for python in [ + os.path.join(virtualEnv, "Scripts", pythonExe), + os.path.join(virtualEnv, "bin", pythonExe), + os.path.join(virtualEnv, pythonExe) + ]: + if os.path.exists(python): + break + else: + python = "" + + if python: break else: python = "" - - if python: - break else: - python = "" + if language == "Python3": + pythonExeList = ["python3", "pypy3"] + elif language == "Python2": + pythonExeList = ["python2", "pypy2"] + if not virtualEnv: + virtualEnv = self.__getDebugEnvironment(language) + + for pythonExe in pythonExeList: + for python in [ + os.path.join(virtualEnv, "bin", pythonExe), + # omit the version character + os.path.join(virtualEnv, "bin", pythonExe)[:-1], + os.path.join(virtualEnv, pythonExe), + # omit the version character + os.path.join(virtualEnv, pythonExe)[:-1], + ]: + if os.path.exists(python): + break + else: + python = "" + + if python: + break + else: + python = "" return python