src/eric7/VirtualEnv/VirtualenvManager.py

branch
eric7
changeset 11286
f0a76bd2a9d3
parent 11230
8a15b05eeee3
--- a/src/eric7/VirtualEnv/VirtualenvManager.py	Tue May 13 16:46:34 2025 +0200
+++ b/src/eric7/VirtualEnv/VirtualenvManager.py	Wed May 14 18:18:06 2025 +0200
@@ -137,6 +137,7 @@
                 )
 
         self.__cleanEnvironments()
+        self.__checkEnvironmentInterpretersExist()
 
         self.__saveSettings()
 
@@ -194,11 +195,51 @@
                         if not os.path.exists(venvPath):
                             del self.__virtualEnvironments[venvName]
                             removed = True
+
         if removed:
-            self.__saveSettings()
             self.virtualEnvironmentRemoved.emit()
             self.virtualEnvironmentsListChanged.emit()
 
+    def __checkEnvironmentInterpretersExist(self):
+        """
+        Private method to set all environments with non-existent interpreters to
+        the disabled state.
+        """
+        changed = False
+
+        for venvName in self.__virtualEnvironments:
+            venvItem = self.__virtualEnvironments[venvName]
+            if venvItem.environment_type != "remote":
+                venvInterpreter = venvItem.interpreter
+                if venvInterpreter:
+                    if venvItem.environment_type == "eric_server":
+                        with contextlib.suppress(KeyError):
+                            # It is an eric-ide server environment; check it has
+                            # an existing interpreter.
+                            ericServer = ericApp().getObject("EricServer")
+                            if (
+                                ericServer.isServerConnected()
+                                and ericServer.getHost() == venvItem.eric_server
+                                and not ericServer.getServiceInterface(
+                                    "FileSystem"
+                                ).exists(venvInterpreter)
+                            ):
+                                venvItem.available = False
+                                changed = True
+                    else:
+                        # It is a local environment; check it has an existing
+                        # interpreter.
+                        if not os.path.exists(venvInterpreter):
+                            venvItem.available = False
+                            changed = True
+                else:
+                    # no interpreter defined
+                    venvItem.available = False
+                    changed = True
+
+        if changed:
+            self.virtualEnvironmentsListChanged.emit()
+
     def getDefaultEnvironment(self):
         """
         Public method to get the default virtual environment.
@@ -232,8 +273,12 @@
         """
         py = FileSystemUtilities.normcaseabspath(interpreter.replace("w.exe", ".exe"))
         for venvName in self.__virtualEnvironments:
-            if py == FileSystemUtilities.normcaseabspath(
-                self.__virtualEnvironments[venvName].interpreter
+            if (
+                py
+                == FileSystemUtilities.normcaseabspath(
+                    self.__virtualEnvironments[venvName].interpreter
+                )
+                and self.__virtualEnvironments[venvName].available
             ):
                 return (venvName, copy.copy(self.__virtualEnvironments[venvName]))
 
@@ -606,7 +651,10 @@
         @return interpreter path
         @rtype str
         """
-        if venvName in self.__virtualEnvironments:
+        if (
+            venvName in self.__virtualEnvironments
+            and self.__virtualEnvironments[venvName].available
+        ):
             return self.__virtualEnvironments[venvName].interpreter.replace(
                 "w.exe", ".exe"
             )
@@ -626,6 +674,9 @@
         """
         if venvName in self.__virtualEnvironments:
             self.__virtualEnvironments[venvName].interpreter = venvInterpreter
+            self.__virtualEnvironments[venvName].available = os.path.exists(
+                venvInterpreter
+            )
             self.__saveSettings()
 
             self.virtualEnvironmentChanged.emit(venvName)
@@ -659,7 +710,11 @@
         @return list of defined virtual environments
         @rtype list of str
         """
-        environments = list(self.__virtualEnvironments)
+        environments = [
+            name
+            for name in self.__virtualEnvironments
+            if self.isAvailableEnvironment(name)
+        ]
         if noGlobals:
             environments = [
                 name for name in environments if not self.isGlobalEnvironment(name)
@@ -684,6 +739,20 @@
 
         return environments
 
+    def isAvailableEnvironment(self, venvName):
+        """
+        Public method to test, if a given environment is available.
+
+        @param venvName logical name of the virtual environment
+        @type str
+        @return flag indicating an available environment
+        @rtype bool
+        """
+        try:
+            return self.__virtualEnvironments[venvName].available
+        except KeyError:
+            return False
+
     def isGlobalEnvironment(self, venvName):
         """
         Public method to test, if a given environment is a global one.

eric ide

mercurial