Refactored the 'VirtualEnv' code for better maintainability. eric7

Wed, 06 Sep 2023 10:28:50 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 06 Sep 2023 10:28:50 +0200
branch
eric7
changeset 10194
2c26b4fe25db
parent 10193
0d7392e49c48
child 10195
d763674ac9a3

Refactored the 'VirtualEnv' code for better maintainability.

eric7.epj file | annotate | diff | comparison | revisions
src/eric7/APIs/Python3/eric7.api file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qch file | annotate | diff | comparison | revisions
src/eric7/Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvAddEditDialog.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvManager.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvManagerWidgets.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvMeta.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/index-eric7.VirtualEnv.html file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvAddEditDialog.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvManager.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvManagerWidgets.py file | annotate | diff | comparison | revisions
src/eric7/VirtualEnv/VirtualenvMeta.py file | annotate | diff | comparison | revisions
--- a/eric7.epj	Tue Sep 05 14:17:29 2023 +0200
+++ b/eric7.epj	Wed Sep 06 10:28:50 2023 +0200
@@ -2237,6 +2237,7 @@
       "src/eric7/VirtualEnv/VirtualenvInterpreterSelectionDialog.py",
       "src/eric7/VirtualEnv/VirtualenvManager.py",
       "src/eric7/VirtualEnv/VirtualenvManagerWidgets.py",
+      "src/eric7/VirtualEnv/VirtualenvMeta.py",
       "src/eric7/VirtualEnv/VirtualenvNameDialog.py",
       "src/eric7/VirtualEnv/VirtualenvUpgradeConfigurationDialog.py",
       "src/eric7/VirtualEnv/VirtualenvUpgradeExecDialog.py",
--- a/src/eric7/APIs/Python3/eric7.api	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/APIs/Python3/eric7.api	Wed Sep 06 10:28:50 2023 +0200
@@ -11149,14 +11149,14 @@
 eric7.ViewManager.ViewManager.ViewManager.zoomValueChanged?4(value, zoomingWidget)
 eric7.ViewManager.ViewManager.ViewManager?1()
 eric7.ViewManager.factory?4(ui, dbs, pluginManager)
-eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.getData?4()
+eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.getMetaData?4()
 eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.on_anacondaCheckBox_clicked?4(checked)
 eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.on_globalCheckBox_toggled?4(checked)
 eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.on_nameEdit_textChanged?4(txt)
 eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.on_pythonExecPicker_textChanged?4(txt)
 eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.on_remoteCheckBox_toggled?4(checked)
 eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog.on_targetDirectoryPicker_textChanged?4(txt)
-eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog?1(manager, venvName="", venvDirectory="", venvInterpreter="", isGlobal=False, isConda=False, isRemote=False, execPath="", description="", baseDir="", parent=None, )
+eric7.VirtualEnv.VirtualenvAddEditDialog.VirtualenvAddEditDialog?1(manager, metadata=None, baseDir="", parent=None, )
 eric7.VirtualEnv.VirtualenvConfigurationDialog.VirtualenvConfigurationDialog.getData?4()
 eric7.VirtualEnv.VirtualenvConfigurationDialog.VirtualenvConfigurationDialog.on_condaButton_toggled?4(checked)
 eric7.VirtualEnv.VirtualenvConfigurationDialog.VirtualenvConfigurationDialog.on_condaCloneButton_clicked?4()
@@ -11181,7 +11181,7 @@
 eric7.VirtualEnv.VirtualenvInterpreterSelectionDialog.VirtualenvInterpreterSelectionDialog?1(venvName, venvDirectory, parent=None)
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.DefaultKey?7
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.SystemKey?7
-eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.addVirtualEnv?4(venvName, venvDirectory, venvInterpreter="", isGlobal=False, isConda=False, isRemote=False, execPath="", description="", )
+eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.addVirtualEnv?4(metadata)
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.createVirtualEnv?4(baseDir="")
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.deleteVirtualEnvs?4(venvNames)
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.environmentForInterpreter?4(interpreter)
@@ -11198,8 +11198,8 @@
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.isUnique?4(venvName)
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.reloadSettings?4()
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.removeVirtualEnvs?4(venvNames)
-eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.renameVirtualEnv?4(oldVenvName, venvName, venvDirectory, venvInterpreter, isGlobal, isConda, isRemote, execPath, description, )
-eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.setVirtualEnv?4(venvName, venvDirectory, venvInterpreter, isGlobal, isConda, isRemote, execPath, description, )
+eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.renameVirtualEnv?4(oldVenvName, metadata, )
+eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.setVirtualEnv?4(metadata)
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.setVirtualEnvInterpreter?4(venvName, venvInterpreter)
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.setVirtualEnvironmentsBaseDir?4(baseDir)
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.showVirtualenvManagerDialog?4(modal=False)
@@ -11210,11 +11210,7 @@
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager.virtualEnvironmentsListChanged?7
 eric7.VirtualEnv.VirtualenvManager.VirtualenvManager?1(parent=None)
 eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerDialog?1(manager, parent=None)
-eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.DescriptionRole?7
-eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.ExecPathRole?7
-eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.IsCondaRole?7
-eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.IsGlobalRole?7
-eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.IsRemoteRole?7
+eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.MetadataRole?7
 eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.on_addButton_clicked?4()
 eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.on_deleteAllButton_clicked?4()
 eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.on_deleteButton_clicked?4()
@@ -11228,6 +11224,8 @@
 eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget.on_venvList_itemSelectionChanged?4()
 eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWidget?1(manager, parent=None)
 eric7.VirtualEnv.VirtualenvManagerWidgets.VirtualenvManagerWindow?1(parent=None)
+eric7.VirtualEnv.VirtualenvMeta.VirtualenvMetaData.as_dict?4()
+eric7.VirtualEnv.VirtualenvMeta.VirtualenvMetaData.from_dict?4(data)
 eric7.VirtualEnv.VirtualenvNameDialog.VirtualenvNameDialog.getName?4()
 eric7.VirtualEnv.VirtualenvNameDialog.VirtualenvNameDialog.on_nameEdit_textChanged?4(txt)
 eric7.VirtualEnv.VirtualenvNameDialog.VirtualenvNameDialog?1(environments, currentName, parent=None)
Binary file src/eric7/Documentation/Help/source.qch has changed
--- a/src/eric7/Documentation/Help/source.qhp	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/Documentation/Help/source.qhp	Wed Sep 06 10:28:50 2023 +0200
@@ -1282,6 +1282,7 @@
             <section title="eric7.VirtualEnv.VirtualenvInterpreterSelectionDialog" ref="eric7.VirtualEnv.VirtualenvInterpreterSelectionDialog.html" />
             <section title="eric7.VirtualEnv.VirtualenvManager" ref="eric7.VirtualEnv.VirtualenvManager.html" />
             <section title="eric7.VirtualEnv.VirtualenvManagerWidgets" ref="eric7.VirtualEnv.VirtualenvManagerWidgets.html" />
+            <section title="eric7.VirtualEnv.VirtualenvMeta" ref="eric7.VirtualEnv.VirtualenvMeta.html" />
             <section title="eric7.VirtualEnv.VirtualenvNameDialog" ref="eric7.VirtualEnv.VirtualenvNameDialog.html" />
             <section title="eric7.VirtualEnv.VirtualenvUpgradeConfigurationDialog" ref="eric7.VirtualEnv.VirtualenvUpgradeConfigurationDialog.html" />
             <section title="eric7.VirtualEnv.VirtualenvUpgradeExecDialog" ref="eric7.VirtualEnv.VirtualenvUpgradeExecDialog.html" />
@@ -18287,7 +18288,7 @@
       <keyword name="VirtualenvAddEditDialog (Module)" id="VirtualenvAddEditDialog (Module)" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html" />
       <keyword name="VirtualenvAddEditDialog.__detectPythonInterpreter" id="VirtualenvAddEditDialog.__detectPythonInterpreter" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html#VirtualenvAddEditDialog.__detectPythonInterpreter" />
       <keyword name="VirtualenvAddEditDialog.__updateOk" id="VirtualenvAddEditDialog.__updateOk" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html#VirtualenvAddEditDialog.__updateOk" />
-      <keyword name="VirtualenvAddEditDialog.getData" id="VirtualenvAddEditDialog.getData" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html#VirtualenvAddEditDialog.getData" />
+      <keyword name="VirtualenvAddEditDialog.getMetaData" id="VirtualenvAddEditDialog.getMetaData" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html#VirtualenvAddEditDialog.getMetaData" />
       <keyword name="VirtualenvAddEditDialog.on_anacondaCheckBox_clicked" id="VirtualenvAddEditDialog.on_anacondaCheckBox_clicked" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html#VirtualenvAddEditDialog.on_anacondaCheckBox_clicked" />
       <keyword name="VirtualenvAddEditDialog.on_globalCheckBox_toggled" id="VirtualenvAddEditDialog.on_globalCheckBox_toggled" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html#VirtualenvAddEditDialog.on_globalCheckBox_toggled" />
       <keyword name="VirtualenvAddEditDialog.on_nameEdit_textChanged" id="VirtualenvAddEditDialog.on_nameEdit_textChanged" ref="eric7.VirtualEnv.VirtualenvAddEditDialog.html#VirtualenvAddEditDialog.on_nameEdit_textChanged" />
@@ -18389,6 +18390,10 @@
       <keyword name="VirtualenvManagerWidgets (Module)" id="VirtualenvManagerWidgets (Module)" ref="eric7.VirtualEnv.VirtualenvManagerWidgets.html" />
       <keyword name="VirtualenvManagerWindow" id="VirtualenvManagerWindow" ref="eric7.VirtualEnv.VirtualenvManagerWidgets.html#VirtualenvManagerWindow" />
       <keyword name="VirtualenvManagerWindow (Constructor)" id="VirtualenvManagerWindow (Constructor)" ref="eric7.VirtualEnv.VirtualenvManagerWidgets.html#VirtualenvManagerWindow.__init__" />
+      <keyword name="VirtualenvMeta (Module)" id="VirtualenvMeta (Module)" ref="eric7.VirtualEnv.VirtualenvMeta.html" />
+      <keyword name="VirtualenvMetaData" id="VirtualenvMetaData" ref="eric7.VirtualEnv.VirtualenvMeta.html#VirtualenvMetaData" />
+      <keyword name="VirtualenvMetaData.as_dict" id="VirtualenvMetaData.as_dict" ref="eric7.VirtualEnv.VirtualenvMeta.html#VirtualenvMetaData.as_dict" />
+      <keyword name="VirtualenvMetaData.from_dict" id="VirtualenvMetaData.from_dict" ref="eric7.VirtualEnv.VirtualenvMeta.html#VirtualenvMetaData.from_dict" />
       <keyword name="VirtualenvNameDialog" id="VirtualenvNameDialog" ref="eric7.VirtualEnv.VirtualenvNameDialog.html#VirtualenvNameDialog" />
       <keyword name="VirtualenvNameDialog (Constructor)" id="VirtualenvNameDialog (Constructor)" ref="eric7.VirtualEnv.VirtualenvNameDialog.html#VirtualenvNameDialog.__init__" />
       <keyword name="VirtualenvNameDialog (Module)" id="VirtualenvNameDialog (Module)" ref="eric7.VirtualEnv.VirtualenvNameDialog.html" />
@@ -21557,6 +21562,7 @@
       <file>eric7.VirtualEnv.VirtualenvInterpreterSelectionDialog.html</file>
       <file>eric7.VirtualEnv.VirtualenvManager.html</file>
       <file>eric7.VirtualEnv.VirtualenvManagerWidgets.html</file>
+      <file>eric7.VirtualEnv.VirtualenvMeta.html</file>
       <file>eric7.VirtualEnv.VirtualenvNameDialog.html</file>
       <file>eric7.VirtualEnv.VirtualenvUpgradeConfigurationDialog.html</file>
       <file>eric7.VirtualEnv.VirtualenvUpgradeExecDialog.html</file>
--- a/src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvAddEditDialog.html	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvAddEditDialog.html	Wed Sep 06 10:28:50 2023 +0200
@@ -67,8 +67,8 @@
 <td>Private slot to update the state of the OK button.</td>
 </tr>
 <tr>
-<td><a href="#VirtualenvAddEditDialog.getData">getData</a></td>
-<td>Public method to retrieve the entered data.</td>
+<td><a href="#VirtualenvAddEditDialog.getMetaData">getMetaData</a></td>
+<td>Public method to retrieve the entered metadata.</td>
 </tr>
 <tr>
 <td><a href="#VirtualenvAddEditDialog.on_anacondaCheckBox_clicked">on_anacondaCheckBox_clicked</a></td>
@@ -103,7 +103,7 @@
 
 <a NAME="VirtualenvAddEditDialog.__init__" ID="VirtualenvAddEditDialog.__init__"></a>
 <h4>VirtualenvAddEditDialog (Constructor)</h4>
-<b>VirtualenvAddEditDialog</b>(<i>manager, venvName="", venvDirectory="", venvInterpreter="", isGlobal=False, isConda=False, isRemote=False, execPath="", description="", baseDir="", parent=None, </i>)
+<b>VirtualenvAddEditDialog</b>(<i>manager, metadata=None, baseDir="", parent=None, </i>)
 
 <p>
         Constructor
@@ -114,46 +114,18 @@
 <dd>
 reference to the virtual environment manager
 </dd>
-<dt><i>venvName</i> (str)</dt>
-<dd>
-logical name of a virtual environment for editing
-</dd>
-<dt><i>venvDirectory</i> (str)</dt>
-<dd>
-directory of the virtual environment
-</dd>
-<dt><i>venvInterpreter</i> (str)</dt>
+<dt><i>metadata</i> (VirtualenvMetaData (optional))</dt>
 <dd>
-Python interpreter of the virtual environment
-</dd>
-<dt><i>isGlobal</i> (bool)</dt>
-<dd>
-flag indicating a global environment
-</dd>
-<dt><i>isConda</i> (bool)</dt>
-<dd>
-flag indicating an Anaconda virtual environment
+object containing the metadata of the virtual environment
+            (defaults to None)
 </dd>
-<dt><i>isRemote</i> (bool)</dt>
+<dt><i>baseDir</i> (str (optional))</dt>
 <dd>
-flag indicating a remotely accessed environment
-</dd>
-<dt><i>execPath</i> (str)</dt>
-<dd>
-search path string to be prepended to the PATH
-            environment variable
+base directory for the virtual environments (defaults to "")
 </dd>
-<dt><i>description</i> (str)</dt>
-<dd>
-descriptive text for the environment
-</dd>
-<dt><i>baseDir</i> (str)</dt>
+<dt><i>parent</i> (QWidget (optional))</dt>
 <dd>
-base directory for the virtual environments
-</dd>
-<dt><i>parent</i> (QWidget)</dt>
-<dd>
-reference to the parent widget
+reference to the parent widget (defaults to None)
 </dd>
 </dl>
 <a NAME="VirtualenvAddEditDialog.__detectPythonInterpreter" ID="VirtualenvAddEditDialog.__detectPythonInterpreter"></a>
@@ -190,27 +162,23 @@
 <p>
         Private slot to update the state of the OK button.
 </p>
-<a NAME="VirtualenvAddEditDialog.getData" ID="VirtualenvAddEditDialog.getData"></a>
-<h4>VirtualenvAddEditDialog.getData</h4>
-<b>getData</b>(<i></i>)
+<a NAME="VirtualenvAddEditDialog.getMetaData" ID="VirtualenvAddEditDialog.getMetaData"></a>
+<h4>VirtualenvAddEditDialog.getMetaData</h4>
+<b>getMetaData</b>(<i></i>)
 
 <p>
-        Public method to retrieve the entered data.
+        Public method to retrieve the entered metadata.
 </p>
 <dl>
 <dt>Return:</dt>
 <dd>
-tuple containing the logical name, the directory, the interpreter of the
-            virtual environment, a flag indicating a global environment, a flag
-            indicating an Anaconda environment, a flag indicating a remotely accessed
-            environment, a string to be prepended to the PATH environment variable and
-            a descriptive text
+metadata for the virtual environment
 </dd>
 </dl>
 <dl>
 <dt>Return Type:</dt>
 <dd>
-tuple of (str, str, str, bool, bool, bool, str, str)
+VirtualenvMetaData
 </dd>
 </dl>
 <a NAME="VirtualenvAddEditDialog.on_anacondaCheckBox_clicked" ID="VirtualenvAddEditDialog.on_anacondaCheckBox_clicked"></a>
--- a/src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvManager.html	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvManager.html	Wed Sep 06 10:28:50 2023 +0200
@@ -116,7 +116,7 @@
 </tr>
 <tr>
 <td><a href="#VirtualenvManager.getEnvironmentEntries">getEnvironmentEntries</a></td>
-<td>Public method to get a dictionary containing the defined virtual environment entries.</td>
+<td>Public method to get a list of the defined virtual environment entries.</td>
 </tr>
 <tr>
 <td><a href="#VirtualenvManager.getVirtualEnvironmentsBaseDir">getVirtualEnvironmentsBaseDir</a></td>
@@ -250,45 +250,16 @@
 </p>
 <a NAME="VirtualenvManager.addVirtualEnv" ID="VirtualenvManager.addVirtualEnv"></a>
 <h4>VirtualenvManager.addVirtualEnv</h4>
-<b>addVirtualEnv</b>(<i>venvName, venvDirectory, venvInterpreter="", isGlobal=False, isConda=False, isRemote=False, execPath="", description="", </i>)
+<b>addVirtualEnv</b>(<i>metadata</i>)
 
 <p>
         Public method to add a virtual environment.
 </p>
 <dl>
 
-<dt><i>venvName</i> (str)</dt>
-<dd>
-logical name for the virtual environment
-</dd>
-<dt><i>venvDirectory</i> (str)</dt>
-<dd>
-directory of the virtual environment
-</dd>
-<dt><i>venvInterpreter</i> (str)</dt>
-<dd>
-interpreter of the virtual environment
-</dd>
-<dt><i>isGlobal</i> (bool)</dt>
+<dt><i>metadata</i> (VirtualenvMetaData)</dt>
 <dd>
-flag indicating a global environment
-</dd>
-<dt><i>isConda</i> (bool)</dt>
-<dd>
-flag indicating an Anaconda virtual environment
-</dd>
-<dt><i>isRemote</i> (bool)</dt>
-<dd>
-flag indicating a remotely accessed environment
-</dd>
-<dt><i>execPath</i> (str)</dt>
-<dd>
-search path string to be prepended to the PATH
-            environment variable
-</dd>
-<dt><i>description</i> (str)</dt>
-<dd>
-descriptive text for the environment
+object containing the metadata of the virtual environment
 </dd>
 </dl>
 <a NAME="VirtualenvManager.createVirtualEnv" ID="VirtualenvManager.createVirtualEnv"></a>
@@ -336,14 +307,14 @@
 <dl>
 <dt>Return:</dt>
 <dd>
-tuple containing the environment name and a dictionary
-            containing a copy of the default virtual environment
+tuple containing the environment name and a copy of the metadata
+            of the virtual environment the interpreter belongs to
 </dd>
 </dl>
 <dl>
 <dt>Return Type:</dt>
 <dd>
-tuple of (str, dict)
+tuple of (str, VirtualenvMetaData)
 </dd>
 </dl>
 <a NAME="VirtualenvManager.getDefaultEnvironment" ID="VirtualenvManager.getDefaultEnvironment"></a>
@@ -361,14 +332,14 @@
 <dl>
 <dt>Return:</dt>
 <dd>
-tuple containing the environment name and a dictionary
-            containing a copy of the default virtual environment
+tuple containing the environment name and a copy of the metadata
+            of the default virtual environment
 </dd>
 </dl>
 <dl>
 <dt>Return Type:</dt>
 <dd>
-tuple of (str, dict)
+tuple of (str, VirtualenvMetaData)
 </dd>
 </dl>
 <a NAME="VirtualenvManager.getEnvironmentEntries" ID="VirtualenvManager.getEnvironmentEntries"></a>
@@ -376,20 +347,18 @@
 <b>getEnvironmentEntries</b>(<i></i>)
 
 <p>
-        Public method to get a dictionary containing the defined virtual
-        environment entries.
+        Public method to get a list of the defined virtual environment entries.
 </p>
 <dl>
 <dt>Return:</dt>
 <dd>
-dictionary containing a copy of the defined virtual
-            environments
+list containing a copy of the defined virtual environments
 </dd>
 </dl>
 <dl>
 <dt>Return Type:</dt>
 <dd>
-dict
+list
 </dd>
 </dl>
 <a NAME="VirtualenvManager.getVirtualEnvironmentsBaseDir" ID="VirtualenvManager.getVirtualEnvironmentsBaseDir"></a>
@@ -649,7 +618,7 @@
 </dl>
 <a NAME="VirtualenvManager.renameVirtualEnv" ID="VirtualenvManager.renameVirtualEnv"></a>
 <h4>VirtualenvManager.renameVirtualEnv</h4>
-<b>renameVirtualEnv</b>(<i>oldVenvName, venvName, venvDirectory, venvInterpreter, isGlobal, isConda, isRemote, execPath, description, </i>)
+<b>renameVirtualEnv</b>(<i>oldVenvName, metadata, </i>)
 
 <p>
         Public method to substitute a virtual environment entry with a new
@@ -661,81 +630,23 @@
 <dd>
 old name of the virtual environment
 </dd>
-<dt><i>venvName</i> (str)</dt>
-<dd>
-logical name for the virtual environment
-</dd>
-<dt><i>venvDirectory</i> (str)</dt>
-<dd>
-directory of the virtual environment
-</dd>
-<dt><i>venvInterpreter</i> (str)</dt>
-<dd>
-interpreter of the virtual environment
-</dd>
-<dt><i>isGlobal</i> (bool)</dt>
+<dt><i>metadata</i> (VirtualenvMetaData)</dt>
 <dd>
-flag indicating a global environment
-</dd>
-<dt><i>isConda</i> (bool)</dt>
-<dd>
-flag indicating an Anaconda virtual environment
-</dd>
-<dt><i>isRemote</i> (bool)</dt>
-<dd>
-flag indicating a remotely accessed environment
-</dd>
-<dt><i>execPath</i> (str)</dt>
-<dd>
-search path string to be prepended to the PATH
-            environment variable
-</dd>
-<dt><i>description</i> (str)</dt>
-<dd>
-descriptive text for the environment
+object containing the metadata of the virtual environment
 </dd>
 </dl>
 <a NAME="VirtualenvManager.setVirtualEnv" ID="VirtualenvManager.setVirtualEnv"></a>
 <h4>VirtualenvManager.setVirtualEnv</h4>
-<b>setVirtualEnv</b>(<i>venvName, venvDirectory, venvInterpreter, isGlobal, isConda, isRemote, execPath, description, </i>)
+<b>setVirtualEnv</b>(<i>metadata</i>)
 
 <p>
         Public method to change a virtual environment.
 </p>
 <dl>
 
-<dt><i>venvName</i> (str)</dt>
-<dd>
-logical name of the virtual environment
-</dd>
-<dt><i>venvDirectory</i> (str)</dt>
-<dd>
-directory of the virtual environment
-</dd>
-<dt><i>venvInterpreter</i> (str)</dt>
-<dd>
-interpreter of the virtual environment
-</dd>
-<dt><i>isGlobal</i> (bool)</dt>
+<dt><i>metadata</i> (VirtualenvMetaData)</dt>
 <dd>
-flag indicating a global environment
-</dd>
-<dt><i>isConda</i> (bool)</dt>
-<dd>
-flag indicating an Anaconda virtual environment
-</dd>
-<dt><i>isRemote</i> (bool)</dt>
-<dd>
-flag indicating a remotely accessed environment
-</dd>
-<dt><i>execPath</i> (str)</dt>
-<dd>
-search path string to be prepended to the PATH
-            environment variable
-</dd>
-<dt><i>description</i> (str)</dt>
-<dd>
-descriptive text for the environment
+object containing the metadata of the virtual environment
 </dd>
 </dl>
 <a NAME="VirtualenvManager.setVirtualEnvInterpreter" ID="VirtualenvManager.setVirtualEnvInterpreter"></a>
--- a/src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvManagerWidgets.html	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvManagerWidgets.html	Wed Sep 06 10:28:50 2023 +0200
@@ -107,7 +107,7 @@
 <h3>Class Attributes</h3>
 
 <table>
-<tr><td>DescriptionRole</td></tr><tr><td>ExecPathRole</td></tr><tr><td>IsCondaRole</td></tr><tr><td>IsGlobalRole</td></tr><tr><td>IsRemoteRole</td></tr>
+<tr><td>MetadataRole</td></tr>
 </table>
 <h3>Class Methods</h3>
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Documentation/Source/eric7.VirtualEnv.VirtualenvMeta.html	Wed Sep 06 10:28:50 2023 +0200
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html><head>
+<title>eric7.VirtualEnv.VirtualenvMeta</title>
+<meta charset="UTF-8">
+<link rel="stylesheet" href="styles.css">
+</head>
+<body>
+<a NAME="top" ID="top"></a>
+<h1>eric7.VirtualEnv.VirtualenvMeta</h1>
+
+<p>
+Module implementing a dataclass containing the metadata of a virtual environment.
+</p>
+<h3>Global Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+
+<table>
+
+<tr>
+<td><a href="#VirtualenvMetaData">VirtualenvMetaData</a></td>
+<td>Class implementing a container for the metadata of a virtual environment.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr />
+<hr />
+<a NAME="VirtualenvMetaData" ID="VirtualenvMetaData"></a>
+<h2>VirtualenvMetaData</h2>
+
+<p>
+    Class implementing a container for the metadata of a virtual environment.
+</p>
+<h3>Derived from</h3>
+None
+<h3>Class Attributes</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Class Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#VirtualenvMetaData.from_dict">from_dict</a></td>
+<td>Class method to create a metadata object from the given dictionary.</td>
+</tr>
+</table>
+<h3>Methods</h3>
+
+<table>
+
+<tr>
+<td><a href="#VirtualenvMetaData.as_dict">as_dict</a></td>
+<td>Public method to convert the metadata into a dictionary.</td>
+</tr>
+</table>
+<h3>Static Methods</h3>
+
+<table>
+<tr><td>None</td></tr>
+</table>
+
+<a NAME="VirtualenvMetaData.from_dict" ID="VirtualenvMetaData.from_dict"></a>
+<h4>VirtualenvMetaData.from_dict (class method)</h4>
+<b>from_dict</b>(<i>data</i>)
+
+<p>
+        Class method to create a metadata object from the given dictionary.
+</p>
+<dl>
+
+<dt><i>data</i> (dict)</dt>
+<dd>
+dictionary containing the metadata
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+created metadata object
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+VirtualenvMetaData
+</dd>
+</dl>
+<a NAME="VirtualenvMetaData.as_dict" ID="VirtualenvMetaData.as_dict"></a>
+<h4>VirtualenvMetaData.as_dict</h4>
+<b>as_dict</b>(<i></i>)
+
+<p>
+        Public method to convert the metadata into a dictionary.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+dictionary containing the metadata
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+dict
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/src/eric7/Documentation/Source/index-eric7.VirtualEnv.html	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/Documentation/Source/index-eric7.VirtualEnv.html	Wed Sep 06 10:28:50 2023 +0200
@@ -40,6 +40,10 @@
 <td>Module implementing a dialog to manage the list of defined virtual environments.</td>
 </tr>
 <tr>
+<td><a href="eric7.VirtualEnv.VirtualenvMeta.html">VirtualenvMeta</a></td>
+<td>Module implementing a dataclass containing the metadata of a virtual environment.</td>
+</tr>
+<tr>
 <td><a href="eric7.VirtualEnv.VirtualenvNameDialog.html">VirtualenvNameDialog</a></td>
 <td>Module implementing a dialog to enter the logical name for a new virtual environment.</td>
 </tr>
--- a/src/eric7/VirtualEnv/VirtualenvAddEditDialog.py	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/VirtualEnv/VirtualenvAddEditDialog.py	Wed Sep 06 10:28:50 2023 +0200
@@ -16,6 +16,7 @@
 from eric7.SystemUtilities import OSUtilities, PythonUtilities
 
 from .Ui_VirtualenvAddEditDialog import Ui_VirtualenvAddEditDialog
+from .VirtualenvMeta import VirtualenvMetaData
 
 
 class VirtualenvAddEditDialog(QDialog, Ui_VirtualenvAddEditDialog):
@@ -26,14 +27,7 @@
     def __init__(
         self,
         manager,
-        venvName="",
-        venvDirectory="",
-        venvInterpreter="",
-        isGlobal=False,
-        isConda=False,
-        isRemote=False,
-        execPath="",
-        description="",
+        metadata=None,
         baseDir="",
         parent=None,
     ):
@@ -42,34 +36,20 @@
 
         @param manager reference to the virtual environment manager
         @type VirtualenvManager
-        @param venvName logical name of a virtual environment for editing
-        @type str
-        @param venvDirectory directory of the virtual environment
-        @type str
-        @param venvInterpreter Python interpreter of the virtual environment
-        @type str
-        @param isGlobal flag indicating a global environment
-        @type bool
-        @param isConda flag indicating an Anaconda virtual environment
-        @type bool
-        @param isRemote flag indicating a remotely accessed environment
-        @type bool
-        @param execPath search path string to be prepended to the PATH
-            environment variable
-        @type str
-        @param description descriptive text for the environment
-        @type str
-        @param baseDir base directory for the virtual environments
-        @type str
-        @param parent reference to the parent widget
-        @type QWidget
+        @param metadata object containing the metadata of the virtual environment
+            (defaults to None)
+        @type VirtualenvMetaData (optional)
+        @param baseDir base directory for the virtual environments (defaults to "")
+        @type str (optional)
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
         """
         super().__init__(parent)
         self.setupUi(self)
 
-        self.__venvName = venvName
+        self.__venvName = "" if metadata is None else metadata.name
         self.__manager = manager
-        self.__editMode = bool(venvName)
+        self.__editMode = bool(self.__venvName)
 
         if self.__editMode:
             self.setWindowTitle(self.tr("Edit Virtual Environment"))
@@ -97,22 +77,31 @@
             ).format(os.pathsep)
         )
 
-        self.nameEdit.setText(venvName)
-        if venvDirectory:
-            self.targetDirectoryPicker.setText(venvDirectory, toNative=not isRemote)
+        self.nameEdit.setText(self.__venvName)
+        if metadata:
+            if metadata.path:
+                self.targetDirectoryPicker.setText(
+                    metadata.path, toNative=not metadata.is_remote
+                )
+            else:
+                self.targetDirectoryPicker.setText(
+                    self.__envBaseDir, toNative=not metadata.is_remote
+                )
+            if not metadata.interpreter and metadata.path and not metadata.is_remote:
+                py = self.__detectPythonInterpreter(metadata.path)
+                self.pythonExecPicker.setText(py)
+            else:
+                self.pythonExecPicker.setText(
+                    metadata.interpreter, toNative=not metadata.is_remote
+                )
         else:
-            self.targetDirectoryPicker.setText(self.__envBaseDir, toNative=not isRemote)
-        if not venvInterpreter and venvDirectory and not isRemote:
-            py = self.__detectPythonInterpreter(venvDirectory)
-            self.pythonExecPicker.setText(py)
-        else:
-            self.pythonExecPicker.setText(venvInterpreter, toNative=not isRemote)
+            self.targetDirectoryPicker.setText(self.__envBaseDir, toNative=True)
 
-        self.globalCheckBox.setChecked(isGlobal)
-        self.anacondaCheckBox.setChecked(isConda)
-        self.remoteCheckBox.setChecked(isRemote)
-        self.execPathEdit.setText(execPath)
-        self.descriptionEdit.setPlainText(description)
+        self.globalCheckBox.setChecked(metadata.is_global if metadata else False)
+        self.anacondaCheckBox.setChecked(metadata.is_conda if metadata else False)
+        self.remoteCheckBox.setChecked(metadata.is_remote if metadata else False)
+        self.execPathEdit.setText(metadata.exec_path if metadata else "")
+        self.descriptionEdit.setPlainText(metadata.description if metadata else "")
 
         self.__updateOk()
 
@@ -267,25 +256,21 @@
                     os.path.join(self.targetDirectoryPicker.text(), "bin"),
                 )
 
-    def getData(self):
+    def getMetaData(self):
         """
-        Public method to retrieve the entered data.
+        Public method to retrieve the entered metadata.
 
-        @return tuple containing the logical name, the directory, the interpreter of the
-            virtual environment, a flag indicating a global environment, a flag
-            indicating an Anaconda environment, a flag indicating a remotely accessed
-            environment, a string to be prepended to the PATH environment variable and
-            a descriptive text
-        @rtype tuple of (str, str, str, bool, bool, bool, str, str)
+        @return metadata for the virtual environment
+        @rtype VirtualenvMetaData
         """
         nativePaths = not self.remoteCheckBox.isChecked()
-        return (
-            self.nameEdit.text(),
-            self.targetDirectoryPicker.text(toNative=nativePaths),
-            self.pythonExecPicker.text(toNative=nativePaths),
-            self.globalCheckBox.isChecked(),
-            self.anacondaCheckBox.isChecked(),
-            self.remoteCheckBox.isChecked(),
-            self.execPathEdit.text(),
-            self.descriptionEdit.toPlainText(),
+        return VirtualenvMetaData(
+            name=self.nameEdit.text(),
+            path=self.targetDirectoryPicker.text(toNative=nativePaths),
+            interpreter=self.pythonExecPicker.text(toNative=nativePaths),
+            is_global=self.globalCheckBox.isChecked(),
+            is_conda=self.anacondaCheckBox.isChecked(),
+            is_remote=self.remoteCheckBox.isChecked(),
+            exec_path=self.execPathEdit.text(),
+            description=self.descriptionEdit.toPlainText(),
         )
--- a/src/eric7/VirtualEnv/VirtualenvManager.py	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/VirtualEnv/VirtualenvManager.py	Wed Sep 06 10:28:50 2023 +0200
@@ -22,6 +22,8 @@
 from eric7.SystemUtilities import FileSystemUtilities, PythonUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 
+from .VirtualenvMeta import VirtualenvMetaData
+
 
 class VirtualenvManager(QObject):
     """
@@ -85,27 +87,17 @@
         #                   setting
         #   description     a description of the environment
         #
-        envsToDelete = []
         for venvName in environments:
             environment = environments[venvName]
+            environment["name"] = venvName
             if ("is_remote" in environment and environment["is_remote"]) or os.access(
                 environment["interpreter"], os.X_OK
             ):
                 if "is_global" not in environment:
                     environment["is_global"] = environment["path"] == ""
-                if "is_conda" not in environment:
-                    environment["is_conda"] = False
-                if "is_remote" not in environment:
-                    environment["is_remote"] = False
-                if "exec_path" not in environment:
-                    environment["exec_path"] = ""
-                if "description" not in environment:
-                    environment["description"] = ""
-                self.__virtualEnvironments[venvName] = environment
-
-        # now remove unsupported environments
-        for venvName in envsToDelete:
-            del environments[venvName]
+                self.__virtualEnvironments[venvName] = VirtualenvMetaData.from_dict(
+                    environment
+                )
 
         # check, if the interpreter used to run eric is in the environments
         defaultPy = PythonUtilities.getPythonExecutable()
@@ -120,16 +112,13 @@
                     break
             if not found:
                 # add an environment entry for the default interpreter
-                self.__virtualEnvironments[VirtualenvManager.DefaultKey] = {
-                    "path": "",
-                    "interpreter": defaultPy,
-                    "variant": 3,
-                    "is_global": True,
-                    "is_conda": False,
-                    "is_remote": False,
-                    "exec_path": "",
-                    "description": "",
-                }
+                self.__virtualEnvironments[
+                    VirtualenvManager.DefaultKey
+                ] = VirtualenvMetaData(
+                    name=VirtualenvManager.DefaultKey,
+                    interpreter=defaultPy,
+                    is_globa=True,
+                )
 
         self.__saveSettings()
 
@@ -142,7 +131,10 @@
         )
 
         Preferences.getSettings().setValue(
-            "PyVenv/VirtualEnvironments", json.dumps(self.__virtualEnvironments)
+            "PyVenv/VirtualEnvironments",
+            json.dumps(
+                {env.name: env.as_dict() for env in self.__virtualEnvironments.values()}
+            ),
         )
         Preferences.syncPreferences()
 
@@ -162,9 +154,9 @@
         having an interpreter matching sys.executable (i.e. the one used to
         execute eric with)
 
-        @return tuple containing the environment name and a dictionary
-            containing a copy of the default virtual environment
-        @rtype tuple of (str, dict)
+        @return tuple containing the environment name and a copy of the metadata
+            of the default virtual environment
+        @rtype tuple of (str, VirtualenvMetaData)
         """
         if VirtualenvManager.DefaultKey in self.__virtualEnvironments:
             return (
@@ -181,14 +173,14 @@
 
         @param interpreter path of the interpreter
         @type str
-        @return tuple containing the environment name and a dictionary
-            containing a copy of the default virtual environment
-        @rtype tuple of (str, dict)
+        @return tuple containing the environment name and a copy of the metadata
+            of the virtual environment the interpreter belongs to
+        @rtype tuple of (str, VirtualenvMetaData)
         """
         py = FileSystemUtilities.normcaseabspath(interpreter.replace("w.exe", ".exe"))
         for venvName in self.__virtualEnvironments:
             if py == FileSystemUtilities.normcaseabspath(
-                self.__virtualEnvironments[venvName]["interpreter"]
+                self.__virtualEnvironments[venvName].interpreter
             ):
                 return (venvName, copy.copy(self.__virtualEnvironments[venvName]))
 
@@ -223,10 +215,12 @@
                 )
                 if ok and "--dry-run" not in resultDict["arguments"]:
                     self.addVirtualEnv(
-                        resultDict["logicalName"],
-                        prefix,
-                        venvInterpreter=interpreter,
-                        isConda=True,
+                        VirtualenvMetaData(
+                            name=resultDict["logicalName"],
+                            path=prefix,
+                            interpreter=interpreter,
+                            is_conda=True,
+                        )
                     )
             else:
                 # now do the call
@@ -262,155 +256,78 @@
             dia.start(args)
             dia.exec()
 
-    def addVirtualEnv(
-        self,
-        venvName,
-        venvDirectory,
-        venvInterpreter="",
-        isGlobal=False,
-        isConda=False,
-        isRemote=False,
-        execPath="",
-        description="",
-    ):
+    def addVirtualEnv(self, metadata):
         """
         Public method to add a virtual environment.
 
-        @param venvName logical name for the virtual environment
-        @type str
-        @param venvDirectory directory of the virtual environment
-        @type str
-        @param venvInterpreter interpreter of the virtual environment
-        @type str
-        @param isGlobal flag indicating a global environment
-        @type bool
-        @param isConda flag indicating an Anaconda virtual environment
-        @type bool
-        @param isRemote flag indicating a remotely accessed environment
-        @type bool
-        @param execPath search path string to be prepended to the PATH
-            environment variable
-        @type str
-        @param description descriptive text for the environment
-        @type str
+        @param metadata object containing the metadata of the virtual environment
+        @type VirtualenvMetaData
         """
         from .VirtualenvInterpreterSelectionDialog import (
             VirtualenvInterpreterSelectionDialog,
         )
         from .VirtualenvNameDialog import VirtualenvNameDialog
 
-        if venvName in self.__virtualEnvironments:
+        if metadata.name in self.__virtualEnvironments:
             ok = EricMessageBox.yesNo(
                 None,
                 self.tr("Add Virtual Environment"),
                 self.tr(
                     """A virtual environment named <b>{0}</b> exists"""
                     """ already. Shall it be replaced?"""
-                ).format(venvName),
+                ).format(metadata.name),
                 icon=EricMessageBox.Warning,
             )
             if not ok:
                 dlg = VirtualenvNameDialog(
-                    list(self.__virtualEnvironments.keys()), venvName
+                    list(self.__virtualEnvironments.keys()), metadata.name
                 )
                 if dlg.exec() != QDialog.DialogCode.Accepted:
                     return
 
-                venvName = dlg.getName()
-
-        if not venvInterpreter:
-            dlg = VirtualenvInterpreterSelectionDialog(venvName, venvDirectory)
-            if dlg.exec() == QDialog.DialogCode.Accepted:
-                venvInterpreter = dlg.getData()
+                metadata.name = dlg.getName()
 
-        if venvInterpreter:
-            self.__virtualEnvironments[venvName] = {
-                "path": venvDirectory,
-                "interpreter": venvInterpreter,
-                "variant": 3,  # always 3
-                "is_global": isGlobal,
-                "is_conda": isConda,
-                "is_remote": isRemote,
-                "exec_path": execPath,
-                "description": description,
-            }
+        if not metadata.interpreter:
+            dlg = VirtualenvInterpreterSelectionDialog(metadata.name, metadata.path)
+            if dlg.exec() == QDialog.DialogCode.Accepted:
+                metadata.interpreter = dlg.getData()
 
+        if metadata.interpreter:
+            self.__virtualEnvironments[metadata.name] = metadata
             self.__saveSettings()
 
             self.virtualEnvironmentAdded.emit()
             self.virtualEnvironmentsListChanged.emit()
 
-    def setVirtualEnv(
-        self,
-        venvName,
-        venvDirectory,
-        venvInterpreter,
-        isGlobal,
-        isConda,
-        isRemote,
-        execPath,
-        description,
-    ):
+    def setVirtualEnv(self, metadata):
         """
         Public method to change a virtual environment.
 
-        @param venvName logical name of the virtual environment
-        @type str
-        @param venvDirectory directory of the virtual environment
-        @type str
-        @param venvInterpreter interpreter of the virtual environment
-        @type str
-        @param isGlobal flag indicating a global environment
-        @type bool
-        @param isConda flag indicating an Anaconda virtual environment
-        @type bool
-        @param isRemote flag indicating a remotely accessed environment
-        @type bool
-        @param execPath search path string to be prepended to the PATH
-            environment variable
-        @type str
-        @param description descriptive text for the environment
-        @type str
+        @param metadata object containing the metadata of the virtual environment
+        @type VirtualenvMetaData
         """
-        if venvName not in self.__virtualEnvironments:
+        if metadata.name not in self.__virtualEnvironments:
             EricMessageBox.yesNo(
                 None,
                 self.tr("Change Virtual Environment"),
                 self.tr(
                     """A virtual environment named <b>{0}</b> does not"""
                     """ exist. Aborting!"""
-                ).format(venvName),
+                ).format(metadata.name),
                 icon=EricMessageBox.Warning,
             )
             return
 
-        self.__virtualEnvironments[venvName] = {
-            "path": venvDirectory,
-            "interpreter": venvInterpreter,
-            "variant": 3,  # always 3
-            "is_global": isGlobal,
-            "is_conda": isConda,
-            "is_remote": isRemote,
-            "exec_path": execPath,
-            "description": description,
-        }
-
+        self.__virtualEnvironments[metadata.name] = metadata
         self.__saveSettings()
 
-        self.virtualEnvironmentChanged.emit(venvName)
+        self.virtualEnvironmentChanged.emit(metadata.name)
         self.virtualEnvironmentsListChanged.emit()
 
     def renameVirtualEnv(
         self,
         oldVenvName,
-        venvName,
-        venvDirectory,
-        venvInterpreter,
-        isGlobal,
-        isConda,
-        isRemote,
-        execPath,
-        description,
+        metadata,
     ):
         """
         Public method to substitute a virtual environment entry with a new
@@ -418,23 +335,8 @@
 
         @param oldVenvName old name of the virtual environment
         @type str
-        @param venvName logical name for the virtual environment
-        @type str
-        @param venvDirectory directory of the virtual environment
-        @type str
-        @param venvInterpreter interpreter of the virtual environment
-        @type str
-        @param isGlobal flag indicating a global environment
-        @type bool
-        @param isConda flag indicating an Anaconda virtual environment
-        @type bool
-        @param isRemote flag indicating a remotely accessed environment
-        @type bool
-        @param execPath search path string to be prepended to the PATH
-            environment variable
-        @type str
-        @param description descriptive text for the environment
-        @type str
+        @param metadata object containing the metadata of the virtual environment
+        @type VirtualenvMetaData
         """
         if oldVenvName not in self.__virtualEnvironments:
             EricMessageBox.yesNo(
@@ -449,16 +351,7 @@
             return
 
         del self.__virtualEnvironments[oldVenvName]
-        self.addVirtualEnv(
-            venvName,
-            venvDirectory,
-            venvInterpreter=venvInterpreter,
-            isGlobal=isGlobal,
-            isConda=isConda,
-            isRemote=isRemote,
-            execPath=execPath,
-            description=description,
-        )
+        self.addVirtualEnv(metadata)
 
     def deleteVirtualEnvs(self, venvNames):
         """
@@ -470,11 +363,11 @@
         venvMessages = []
         for venvName in venvNames:
             if venvName in self.__virtualEnvironments and bool(
-                self.__virtualEnvironments[venvName]["path"]
+                self.__virtualEnvironments[venvName].path
             ):
                 venvMessages.append(
                     self.tr("{0} - {1}").format(
-                        venvName, self.__virtualEnvironments[venvName]["path"]
+                        venvName, self.__virtualEnvironments[venvName].path
                     )
                 )
         if venvMessages:
@@ -492,13 +385,13 @@
                     if self.__isEnvironmentDeleteable(venvName):
                         if self.isCondaEnvironment(venvName):
                             conda = ericApp().getObject("Conda")
-                            path = self.__virtualEnvironments[venvName]["path"]
+                            path = self.__virtualEnvironments[venvName].path
                             res = conda.removeCondaEnvironment(prefix=path)
                             if res:
                                 del self.__virtualEnvironments[venvName]
                         else:
                             shutil.rmtree(
-                                self.__virtualEnvironments[venvName]["path"], True
+                                self.__virtualEnvironments[venvName].path, True
                             )
                             del self.__virtualEnvironments[venvName]
 
@@ -520,10 +413,10 @@
         ok = False
         if venvName in self.__virtualEnvironments:
             ok = True
-            ok &= bool(self.__virtualEnvironments[venvName]["path"])
-            ok &= not self.__virtualEnvironments[venvName]["is_global"]
-            ok &= not self.__virtualEnvironments[venvName]["is_remote"]
-            ok &= os.access(self.__virtualEnvironments[venvName]["path"], os.W_OK)
+            ok &= bool(self.__virtualEnvironments[venvName].path)
+            ok &= not self.__virtualEnvironments[venvName].is_global
+            ok &= not self.__virtualEnvironments[venvName].is_remote
+            ok &= os.access(self.__virtualEnvironments[venvName].path, os.W_OK)
 
         return ok
 
@@ -539,7 +432,7 @@
             if venvName in self.__virtualEnvironments:
                 venvMessages.append(
                     self.tr("{0} - {1}").format(
-                        venvName, self.__virtualEnvironments[venvName]["path"]
+                        venvName, self.__virtualEnvironments[venvName].path
                     )
                 )
         if venvMessages:
@@ -564,14 +457,12 @@
 
     def getEnvironmentEntries(self):
         """
-        Public method to get a dictionary containing the defined virtual
-        environment entries.
+        Public method to get a list of the defined virtual environment entries.
 
-        @return dictionary containing a copy of the defined virtual
-            environments
-        @rtype dict
+        @return list containing a copy of the defined virtual environments
+        @rtype list
         """
-        return copy.deepcopy(self.__virtualEnvironments)
+        return [copy.copy(env) for env in self.__virtualEnvironments.values()]
 
     @pyqtSlot()
     def showVirtualenvManagerDialog(self, modal=False):
@@ -611,7 +502,7 @@
         @rtype str
         """
         if venvName in self.__virtualEnvironments:
-            return self.__virtualEnvironments[venvName]["interpreter"].replace(
+            return self.__virtualEnvironments[venvName].interpreter.replace(
                 "w.exe", ".exe"
             )
         elif venvName == VirtualenvManager.SystemKey:
@@ -629,7 +520,7 @@
         @type str
         """
         if venvName in self.__virtualEnvironments:
-            self.__virtualEnvironments[venvName]["interpreter"] = venvInterpreter
+            self.__virtualEnvironments[venvName].interpreter = venvInterpreter
             self.__saveSettings()
 
             self.virtualEnvironmentChanged.emit(venvName)
@@ -645,7 +536,7 @@
         @rtype str
         """
         if venvName in self.__virtualEnvironments:
-            return self.__virtualEnvironments[venvName]["path"]
+            return self.__virtualEnvironments[venvName].path
         else:
             return ""
 
@@ -683,7 +574,7 @@
         @rtype bool
         """
         if venvName in self.__virtualEnvironments:
-            return self.__virtualEnvironments[venvName]["is_global"]
+            return self.__virtualEnvironments[venvName].is_global
         else:
             return False
 
@@ -698,7 +589,7 @@
         @rtype bool
         """
         if venvName in self.__virtualEnvironments:
-            return self.__virtualEnvironments[venvName]["is_conda"]
+            return self.__virtualEnvironments[venvName].is_conda
         else:
             return False
 
@@ -713,7 +604,7 @@
         @rtype bool
         """
         if venvName in self.__virtualEnvironments:
-            return self.__virtualEnvironments[venvName]["is_remote"]
+            return self.__virtualEnvironments[venvName].is_remote
         else:
             return False
 
@@ -727,7 +618,7 @@
         @rtype str
         """
         if venvName in self.__virtualEnvironments:
-            return self.__virtualEnvironments[venvName]["exec_path"]
+            return self.__virtualEnvironments[venvName].exec_path
         else:
             return ""
 
--- a/src/eric7/VirtualEnv/VirtualenvManagerWidgets.py	Tue Sep 05 14:17:29 2023 +0200
+++ b/src/eric7/VirtualEnv/VirtualenvManagerWidgets.py	Wed Sep 06 10:28:50 2023 +0200
@@ -34,11 +34,7 @@
     environments.
     """
 
-    IsGlobalRole = Qt.ItemDataRole.UserRole + 1
-    IsCondaRole = Qt.ItemDataRole.UserRole + 2
-    IsRemoteRole = Qt.ItemDataRole.UserRole + 3
-    ExecPathRole = Qt.ItemDataRole.UserRole + 4
-    DescriptionRole = Qt.ItemDataRole.UserRole + 5
+    MetadataRole = Qt.ItemDataRole.UserRole + 1
 
     def __init__(self, manager, parent=None):
         """
@@ -94,8 +90,8 @@
             if (
                 itm.text(0) != "<default>"
                 and bool(itm.text(1))
-                and not itm.data(0, VirtualenvManagerWidget.IsGlobalRole)
-                and not itm.data(0, VirtualenvManagerWidget.IsRemoteRole)
+                and not itm.data(0, VirtualenvManagerWidget.MetadataRole).is_global
+                and not itm.data(0, VirtualenvManagerWidget.MetadataRole).is_remote
             ):
                 deletableSelectedItemCount += 1
 
@@ -105,7 +101,7 @@
             if (
                 itm.text(0) != "<default>"
                 and bool(itm.text(1))
-                and not itm.data(0, VirtualenvManagerWidget.IsRemoteRole)
+                and not itm.data(0, VirtualenvManagerWidget.MetadataRole).is_remote
             ):
                 deletableItemCount += 1
 
@@ -151,30 +147,11 @@
         from .VirtualenvAddEditDialog import VirtualenvAddEditDialog
 
         dlg = VirtualenvAddEditDialog(
-            self.__manager, baseDir=self.envBaseDirectoryPicker.text()
+            self.__manager, baseDir=self.envBaseDirectoryPicker.text(), parent=self
         )
         if dlg.exec() == QDialog.DialogCode.Accepted:
-            (
-                venvName,
-                venvDirectory,
-                venvInterpreter,
-                isGlobal,
-                isConda,
-                isRemote,
-                execPath,
-                description,
-            ) = dlg.getData()
-
-            self.__manager.addVirtualEnv(
-                venvName,
-                venvDirectory,
-                venvInterpreter,
-                isGlobal,
-                isConda,
-                isRemote,
-                execPath,
-                description,
-            )
+            metadata = dlg.getMetaData()
+            self.__manager.addVirtualEnv(metadata)
 
     @pyqtSlot()
     def on_newButton_clicked(self):
@@ -195,50 +172,16 @@
 
         dlg = VirtualenvAddEditDialog(
             self.__manager,
-            selectedItem.text(0),
-            selectedItem.text(1),
-            selectedItem.text(2),
-            selectedItem.data(0, VirtualenvManagerWidget.IsGlobalRole),
-            selectedItem.data(0, VirtualenvManagerWidget.IsCondaRole),
-            selectedItem.data(0, VirtualenvManagerWidget.IsRemoteRole),
-            selectedItem.data(0, VirtualenvManagerWidget.ExecPathRole),
-            selectedItem.data(0, VirtualenvManagerWidget.DescriptionRole),
+            selectedItem.data(0, VirtualenvManagerWidget.MetadataRole),
             baseDir=self.envBaseDirectoryPicker.text(),
+            parent=self,
         )
         if dlg.exec() == QDialog.DialogCode.Accepted:
-            (
-                venvName,
-                venvDirectory,
-                venvInterpreter,
-                isGlobal,
-                isConda,
-                isRemote,
-                execPath,
-                description,
-            ) = dlg.getData()
-            if venvName != oldVenvName:
-                self.__manager.renameVirtualEnv(
-                    oldVenvName,
-                    venvName,
-                    venvDirectory,
-                    venvInterpreter,
-                    isGlobal,
-                    isConda,
-                    isRemote,
-                    execPath,
-                    description,
-                )
+            metadata = dlg.getMetaData()
+            if metadata.name != oldVenvName:
+                self.__manager.renameVirtualEnv(oldVenvName, metadata)
             else:
-                self.__manager.setVirtualEnv(
-                    venvName,
-                    venvDirectory,
-                    venvInterpreter,
-                    isGlobal,
-                    isConda,
-                    isRemote,
-                    execPath,
-                    description,
-                )
+                self.__manager.setVirtualEnv(metadata)
 
     @pyqtSlot()
     def on_upgradeButton_clicked(self):
@@ -309,7 +252,9 @@
         selectedItems = self.venvList.selectedItems()
         if len(selectedItems) == 1:
             self.descriptionEdit.setPlainText(
-                selectedItems[0].data(0, VirtualenvManagerWidget.DescriptionRole)
+                selectedItems[0]
+                .data(0, VirtualenvManagerWidget.MetadataRole)
+                .description
             )
         else:
             self.descriptionEdit.clear()
@@ -340,44 +285,19 @@
         """
         Private method to populate the list of virtual environments.
         """
-        environments = self.__manager.getEnvironmentEntries()
-        for venvName in environments:
+        for environment in self.__manager.getEnvironmentEntries():
             itm = QTreeWidgetItem(
                 self.venvList,
                 [
-                    venvName,
-                    environments[venvName]["path"],
-                    environments[venvName]["interpreter"],
+                    environment.name,
+                    environment.path,
+                    environment.interpreter,
                 ],
             )
-            itm.setData(
-                0,
-                VirtualenvManagerWidget.IsGlobalRole,
-                environments[venvName]["is_global"],
-            )
-            itm.setData(
-                0,
-                VirtualenvManagerWidget.IsCondaRole,
-                environments[venvName]["is_conda"],
-            )
-            itm.setData(
-                0,
-                VirtualenvManagerWidget.IsRemoteRole,
-                environments[venvName]["is_remote"],
-            )
-            itm.setData(
-                0,
-                VirtualenvManagerWidget.ExecPathRole,
-                environments[venvName]["exec_path"],
-            )
-            itm.setData(
-                0,
-                VirtualenvManagerWidget.DescriptionRole,
-                environments[venvName]["description"],
-            )
+            itm.setData(0, VirtualenvManagerWidget.MetadataRole, environment)
 
             # show remote environments with underlined font
-            if environments[venvName]["is_remote"]:
+            if environment.is_remote:
                 font = itm.font(0)
                 font.setUnderline(True)
                 for column in range(itm.columnCount()):
@@ -386,14 +306,14 @@
                 # local environments
 
                 # show global environments with bold font
-                if environments[venvName]["is_global"]:
+                if environment.is_global:
                     font = itm.font(0)
                     font.setBold(True)
                     for column in range(itm.columnCount()):
                         itm.setFont(column, font)
 
                 # show Anaconda environments with italic font
-                if environments[venvName]["is_conda"]:
+                if environment.is_conda:
                     font = itm.font(0)
                     font.setItalic(True)
                     for column in range(itm.columnCount()):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/VirtualEnv/VirtualenvMeta.py	Wed Sep 06 10:28:50 2023 +0200
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dataclass containing the metadata of a virtual environment.
+"""
+
+from dataclasses import asdict, dataclass
+
+
+@dataclass
+class VirtualenvMetaData:
+    """
+    Class implementing a container for the metadata of a virtual environment.
+    """
+
+    name: str  # name of the virtual environment
+    path: str = ""  # directory of the virtual environment (empty for a global one)
+    interpreter: str = ""  # path of the Python interpreter
+    is_global: bool = False  # flag indicating a global environment
+    is_conda: bool = False  # flag indicating an Anaconda environment
+    is_remote: bool = False  # flag indicating a remotely accessed environment
+    exec_path: str = ""  # string to be prefixed to the PATH environment setting
+    description: str = ""  # description of the environment
+
+    def as_dict(self):
+        """
+        Public method to convert the metadata into a dictionary.
+
+        @return dictionary containing the metadata
+        @rtype dict
+        """
+        return asdict(self)
+
+    @classmethod
+    def from_dict(cls, data):
+        """
+        Class method to create a metadata object from the given dictionary.
+
+        @param data dictionary containing the metadata
+        @type dict
+        @return created metadata object
+        @rtype VirtualenvMetaData
+        """
+        return cls(
+            name=data["name"],
+            path=data.get("path", ""),
+            interpreter=data.get("interpreter", ""),
+            is_global=data.get("is_global", False),
+            is_conda=data.get("is_conda", False),
+            is_remote=data.get("is_remote", False),
+            exec_path=data.get("exec_path", ""),
+            description=data.get("description", ""),
+        )

eric ide

mercurial