src/eric7/CondaInterface/Conda.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9278
36448ca469c2
--- a/src/eric7/CondaInterface/Conda.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/CondaInterface/Conda.py	Wed Jul 13 14:55:47 2022 +0200
@@ -26,36 +26,37 @@
 class Conda(QObject):
     """
     Class implementing the conda GUI logic.
-    
+
     @signal condaEnvironmentCreated() emitted to indicate the creation of
         a new environment
     @signal condaEnvironmentRemoved() emitted to indicate the removal of
         an environment
     """
+
     condaEnvironmentCreated = pyqtSignal()
     condaEnvironmentRemoved = pyqtSignal()
-    
+
     RootName = QCoreApplication.translate("Conda", "<root>")
-    
+
     def __init__(self, parent=None):
         """
         Constructor
-        
+
         @param parent parent
         @type QObject
         """
         super().__init__(parent)
-        
+
         self.__ui = parent
-    
+
     #######################################################################
     ## environment related methods below
     #######################################################################
-    
+
     def createCondaEnvironment(self, arguments):
         """
         Public method to create a conda environment.
-        
+
         @param arguments list of command line arguments
         @type list of str
         @return tuple containing a flag indicating success, the directory of
@@ -64,15 +65,14 @@
         @rtype tuple of (bool, str, str)
         """
         args = ["create", "--json", "--yes"] + arguments
-        
+
         dlg = CondaExecDialog("create", self.__ui)
         dlg.start(args)
         dlg.exec()
         ok, resultDict = dlg.getResult()
-        
+
         if ok:
-            if ("actions" in resultDict and
-                    "PREFIX" in resultDict["actions"]):
+            if "actions" in resultDict and "PREFIX" in resultDict["actions"]:
                 prefix = resultDict["actions"]["PREFIX"]
             elif "prefix" in resultDict:
                 prefix = resultDict["prefix"]
@@ -80,37 +80,32 @@
                 prefix = resultDict["dst_prefix"]
             else:
                 prefix = ""
-            
+
             # determine Python executable
             if prefix:
-                pathPrefixes = [
-                    prefix,
-                    rootPrefix()
-                ]
+                pathPrefixes = [prefix, rootPrefix()]
             else:
-                pathPrefixes = [
-                    rootPrefix()
-                ]
+                pathPrefixes = [rootPrefix()]
             for pathPrefix in pathPrefixes:
                 python = (
                     os.path.join(pathPrefix, "python.exe")
-                    if Globals.isWindowsPlatform() else
-                    os.path.join(pathPrefix, "bin", "python")
+                    if Globals.isWindowsPlatform()
+                    else os.path.join(pathPrefix, "bin", "python")
                 )
                 if os.path.exists(python):
                     break
             else:
                 python = ""
-            
+
             self.condaEnvironmentCreated.emit()
             return True, prefix, python
         else:
             return False, "", ""
-    
+
     def removeCondaEnvironment(self, name="", prefix=""):
         """
         Public method to remove a conda environment.
-        
+
         @param name name of the environment
         @type str
         @param prefix prefix of the environment
@@ -118,15 +113,15 @@
         @return flag indicating success
         @rtype bool
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         if not name and not prefix:
             raise RuntimeError("One of 'name' or 'prefix' must be given.")
-        
+
         args = [
             "remove",
             "--json",
@@ -137,72 +132,80 @@
             args.extend(["--name", name])
         elif prefix:
             args.extend(["--prefix", prefix])
-        
+
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         proc = QProcess()
         proc.start(exe, args)
         if not proc.waitForStarted(15000):
             EricMessageBox.critical(
                 self.__ui,
                 self.tr("conda remove"),
-                self.tr("""The conda executable could not be started."""))
+                self.tr("""The conda executable could not be started."""),
+            )
             return False
         else:
             proc.waitForFinished(15000)
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
+            output = str(
+                proc.readAllStandardOutput(),
+                Preferences.getSystem("IOEncoding"),
+                "replace",
+            ).strip()
             try:
                 jsonDict = json.loads(output)
             except Exception:
                 EricMessageBox.critical(
                     self.__ui,
                     self.tr("conda remove"),
-                    self.tr("""The conda executable returned invalid data."""))
+                    self.tr("""The conda executable returned invalid data."""),
+                )
                 return False
-            
+
             if "error" in jsonDict:
                 EricMessageBox.critical(
                     self.__ui,
                     self.tr("conda remove"),
-                    self.tr("<p>The conda executable returned an error.</p>"
-                            "<p>{0}</p>").format(jsonDict["message"]))
+                    self.tr(
+                        "<p>The conda executable returned an error.</p>" "<p>{0}</p>"
+                    ).format(jsonDict["message"]),
+                )
                 return False
-            
+
             if jsonDict["success"]:
                 self.condaEnvironmentRemoved.emit()
-            
+
             return jsonDict["success"]
-        
+
         return False
-    
+
     def getCondaEnvironmentsList(self):
         """
         Public method to get a list of all Conda environments.
-        
+
         @return list of tuples containing the environment name and prefix
         @rtype list of tuples of (str, str)
         """
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         environmentsList = []
-        
+
         proc = QProcess()
         proc.start(exe, ["info", "--json"])
         if proc.waitForStarted(15000) and proc.waitForFinished(15000):
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
+            output = str(
+                proc.readAllStandardOutput(),
+                Preferences.getSystem("IOEncoding"),
+                "replace",
+            ).strip()
             try:
                 jsonDict = json.loads(output)
             except Exception:
                 jsonDict = {}
-            
+
             if "envs" in jsonDict:
                 for prefix in jsonDict["envs"][:]:
                     if prefix == jsonDict["root_prefix"]:
@@ -212,20 +215,20 @@
                         name = self.RootName
                     else:
                         name = os.path.basename(prefix)
-                    
+
                     environmentsList.append((name, prefix))
-        
+
         return environmentsList
-    
+
     #######################################################################
     ## package related methods below
     #######################################################################
-    
+
     def getInstalledPackages(self, name="", prefix=""):
         """
         Public method to get a list of installed packages of a conda
         environment.
-        
+
         @param name name of the environment
         @type str
         @param prefix prefix of the environment
@@ -234,15 +237,15 @@
             the package name, version and build.
         @rtype list of tuples of (str, str, str)
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         if not name and not prefix:
             raise RuntimeError("One of 'name' or 'prefix' must be given.")
-        
+
         args = [
             "list",
             "--json",
@@ -251,44 +254,44 @@
             args.extend(["--name", name])
         elif prefix:
             args.extend(["--prefix", prefix])
-        
+
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         packages = []
-        
+
         proc = QProcess()
         proc.start(exe, args)
         if proc.waitForStarted(15000) and proc.waitForFinished(30000):
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
+            output = str(
+                proc.readAllStandardOutput(),
+                Preferences.getSystem("IOEncoding"),
+                "replace",
+            ).strip()
             try:
                 jsonList = json.loads(output)
             except Exception:
                 jsonList = []
-            
+
             for package in jsonList:
                 if isinstance(package, dict):
-                    packages.append((
-                        package["name"],
-                        package["version"],
-                        package["build_string"]
-                    ))
+                    packages.append(
+                        (package["name"], package["version"], package["build_string"])
+                    )
                 else:
                     parts = package.rsplit("-", 2)
                     while len(parts) < 3:
                         parts.append("")
                     packages.append(tuple(parts))
-        
+
         return packages
-    
+
     def getUpdateablePackages(self, name="", prefix=""):
         """
         Public method to get a list of updateable packages of a conda
         environment.
-        
+
         @param name name of the environment
         @type str
         @param prefix prefix of the environment
@@ -297,15 +300,15 @@
             the package name, version and build.
         @rtype list of tuples of (str, str, str)
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         if not name and not prefix:
             raise RuntimeError("One of 'name' or 'prefix' must be given.")
-        
+
         args = [
             "update",
             "--json",
@@ -317,45 +320,49 @@
             args.extend(["--name", name])
         elif prefix:
             args.extend(["--prefix", prefix])
-        
+
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         packages = []
-        
+
         proc = QProcess()
         proc.start(exe, args)
         if proc.waitForStarted(15000) and proc.waitForFinished(30000):
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
+            output = str(
+                proc.readAllStandardOutput(),
+                Preferences.getSystem("IOEncoding"),
+                "replace",
+            ).strip()
             try:
                 jsonDict = json.loads(output)
             except Exception:
                 jsonDict = {}
-            
+
             if "actions" in jsonDict and "LINK" in jsonDict["actions"]:
                 for linkEntry in jsonDict["actions"]["LINK"]:
                     if isinstance(linkEntry, dict):
-                        packages.append((
-                            linkEntry["name"],
-                            linkEntry["version"],
-                            linkEntry["build_string"]
-                        ))
+                        packages.append(
+                            (
+                                linkEntry["name"],
+                                linkEntry["version"],
+                                linkEntry["build_string"],
+                            )
+                        )
                     else:
                         package = linkEntry.split()[0]
                         parts = package.rsplit("-", 2)
                         while len(parts) < 3:
                             parts.append("")
                         packages.append(tuple(parts))
-        
+
         return packages
-    
+
     def updatePackages(self, packages, name="", prefix=""):
         """
         Public method to update packages of a conda environment.
-        
+
         @param packages list of package names to be updated
         @type list of str
         @param name name of the environment
@@ -365,15 +372,15 @@
         @return flag indicating success
         @rtype bool
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         if not name and not prefix:
             raise RuntimeError("One of 'name' or 'prefix' must be given.")
-        
+
         if packages:
             args = [
                 "update",
@@ -385,20 +392,20 @@
             elif prefix:
                 args.extend(["--prefix", prefix])
             args.extend(packages)
-            
+
             dlg = CondaExecDialog("update", self.__ui)
             dlg.start(args)
             dlg.exec()
             ok, _ = dlg.getResult()
         else:
             ok = False
-        
+
         return ok
-    
+
     def updateAllPackages(self, name="", prefix=""):
         """
         Public method to update all packages of a conda environment.
-        
+
         @param name name of the environment
         @type str
         @param prefix prefix of the environment
@@ -406,37 +413,32 @@
         @return flag indicating success
         @rtype bool
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         if not name and not prefix:
             raise RuntimeError("One of 'name' or 'prefix' must be given.")
-        
-        args = [
-            "update",
-            "--json",
-            "--yes",
-            "--all"
-        ]
+
+        args = ["update", "--json", "--yes", "--all"]
         if name:
             args.extend(["--name", name])
         elif prefix:
             args.extend(["--prefix", prefix])
-        
+
         dlg = CondaExecDialog("update", self.__ui)
         dlg.start(args)
         dlg.exec()
         ok, _ = dlg.getResult()
-        
+
         return ok
-    
+
     def installPackages(self, packages, name="", prefix=""):
         """
         Public method to install packages into a conda environment.
-        
+
         @param packages list of package names to be installed
         @type list of str
         @param name name of the environment
@@ -446,15 +448,15 @@
         @return flag indicating success
         @rtype bool
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         if not name and not prefix:
             raise RuntimeError("One of 'name' or 'prefix' must be given.")
-        
+
         if packages:
             args = [
                 "install",
@@ -466,21 +468,21 @@
             elif prefix:
                 args.extend(["--prefix", prefix])
             args.extend(packages)
-            
+
             dlg = CondaExecDialog("install", self.__ui)
             dlg.start(args)
             dlg.exec()
             ok, _ = dlg.getResult()
         else:
             ok = False
-        
+
         return ok
-    
+
     def uninstallPackages(self, packages, name="", prefix=""):
         """
         Public method to uninstall packages of a conda environment (including
         all no longer needed dependencies).
-        
+
         @param packages list of package names to be uninstalled
         @type list of str
         @param name name of the environment
@@ -490,25 +492,27 @@
         @return flag indicating success
         @rtype bool
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         if not name and not prefix:
             raise RuntimeError("One of 'name' or 'prefix' must be given.")
-        
+
         if packages:
-            from UI.DeleteFilesConfirmationDialog import (
-                DeleteFilesConfirmationDialog)
+            from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
+
             dlg = DeleteFilesConfirmationDialog(
                 self.parent(),
                 self.tr("Uninstall Packages"),
                 self.tr(
                     "Do you really want to uninstall these packages and"
-                    " their dependencies?"),
-                packages)
+                    " their dependencies?"
+                ),
+                packages,
+            )
             if dlg.exec() == QDialog.DialogCode.Accepted:
                 args = [
                     "remove",
@@ -516,13 +520,15 @@
                     "--yes",
                 ]
                 if condaVersion() >= (4, 4, 0):
-                    args.append("--prune",)
+                    args.append(
+                        "--prune",
+                    )
                 if name:
                     args.extend(["--name", name])
                 elif prefix:
                     args.extend(["--prefix", prefix])
                 args.extend(packages)
-                
+
                 dlg = CondaExecDialog("remove", self.__ui)
                 dlg.start(args)
                 dlg.exec()
@@ -531,14 +537,21 @@
                 ok = False
         else:
             ok = False
-        
+
         return ok
-    
-    def searchPackages(self, pattern, fullNameOnly=False, packageSpec=False,
-                       platform="", name="", prefix=""):
+
+    def searchPackages(
+        self,
+        pattern,
+        fullNameOnly=False,
+        packageSpec=False,
+        platform="",
+        name="",
+        prefix="",
+    ):
         """
         Public method to search for a package pattern of a conda environment.
-        
+
         @param pattern package search pattern
         @type str
         @param fullNameOnly flag indicating to search for full names only
@@ -556,12 +569,12 @@
             packages as values
         @rtype tuple of (bool, dict of list of dict)
         @exception RuntimeError raised to indicate an error in parameters
-        
+
         Note: only one of name or prefix must be given.
         """
         if name and prefix:
             raise RuntimeError("Only one of 'name' or 'prefix' must be given.")
-        
+
         args = [
             "search",
             "--json",
@@ -577,103 +590,98 @@
         elif prefix:
             args.extend(["--prefix", prefix])
         args.append(pattern)
-        
+
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         packages = {}
         ok = False
-        
+
         proc = QProcess()
         proc.start(exe, args)
         if proc.waitForStarted(15000) and proc.waitForFinished(30000):
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
+            output = str(
+                proc.readAllStandardOutput(),
+                Preferences.getSystem("IOEncoding"),
+                "replace",
+            ).strip()
             with contextlib.suppress(Exception):
                 packages = json.loads(output)
                 ok = "error" not in packages
-        
+
         return ok, packages
-    
+
     #######################################################################
     ## special methods below
     #######################################################################
-    
+
     def updateConda(self):
         """
         Public method to update conda itself.
-        
+
         @return flag indicating success
         @rtype bool
         """
-        args = [
-            "update",
-            "--json",
-            "--yes",
-            "conda"
-        ]
-        
+        args = ["update", "--json", "--yes", "conda"]
+
         dlg = CondaExecDialog("update", self.__ui)
         dlg.start(args)
         dlg.exec()
         ok, _ = dlg.getResult()
-        
+
         return ok
-    
+
     def writeDefaultConfiguration(self):
         """
         Public method to create a conda configuration with default values.
         """
-        args = [
-            "config",
-            "--write-default",
-            "--quiet"
-        ]
-        
+        args = ["config", "--write-default", "--quiet"]
+
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         proc = QProcess()
         proc.start(exe, args)
         proc.waitForStarted(15000)
         proc.waitForFinished(30000)
-    
+
     def getCondaInformation(self):
         """
         Public method to get a dictionary containing information about conda.
-        
+
         @return dictionary containing information about conda
         @rtype dict
         """
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         infoDict = {}
-        
+
         proc = QProcess()
         proc.start(exe, ["info", "--json"])
         if proc.waitForStarted(15000) and proc.waitForFinished(30000):
-            output = str(proc.readAllStandardOutput(),
-                         Preferences.getSystem("IOEncoding"),
-                         'replace').strip()
+            output = str(
+                proc.readAllStandardOutput(),
+                Preferences.getSystem("IOEncoding"),
+                "replace",
+            ).strip()
             try:
                 infoDict = json.loads(output)
             except Exception:
                 infoDict = {}
-        
+
         return infoDict
-    
+
     def runProcess(self, args):
         """
         Public method to execute the conda with the given arguments.
-        
+
         The conda executable is called with the given arguments and
         waited for its end.
-        
+
         @param args list of command line arguments
         @type list of str
         @return tuple containing a flag indicating success and the output
@@ -683,7 +691,7 @@
         exe = Preferences.getConda("CondaExecutable")
         if not exe:
             exe = "conda"
-        
+
         process = QProcess()
         process.start(exe, args)
         procStarted = process.waitForStarted(15000)
@@ -691,28 +699,32 @@
             finished = process.waitForFinished(30000)
             if finished:
                 if process.exitCode() == 0:
-                    output = str(process.readAllStandardOutput(),
-                                 Preferences.getSystem("IOEncoding"),
-                                 'replace').strip()
+                    output = str(
+                        process.readAllStandardOutput(),
+                        Preferences.getSystem("IOEncoding"),
+                        "replace",
+                    ).strip()
                     return True, output
                 else:
-                    return (False,
-                            self.tr("conda exited with an error ({0}).")
-                            .format(process.exitCode()))
+                    return (
+                        False,
+                        self.tr("conda exited with an error ({0}).").format(
+                            process.exitCode()
+                        ),
+                    )
             else:
                 process.terminate()
                 process.waitForFinished(2000)
                 process.kill()
                 process.waitForFinished(3000)
-                return False, self.tr("conda did not finish within"
-                                      " 3 seconds.")
-        
+                return False, self.tr("conda did not finish within" " 3 seconds.")
+
         return False, self.tr("conda could not be started.")
-    
+
     def cleanConda(self, cleanAction):
         """
         Public method to update conda itself.
-        
+
         @param cleanAction cleaning action to be performed (must be one of
             the command line parameters without '--')
         @type str
@@ -722,7 +734,7 @@
             "--yes",
             "--{0}".format(cleanAction),
         ]
-        
+
         dlg = CondaExecDialog("clean", self.__ui)
         dlg.start(args)
         dlg.exec()

eric ide

mercurial