MicroPython mpy_network

Thu, 27 Apr 2023 17:59:09 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 27 Apr 2023 17:59:09 +0200
branch
mpy_network
changeset 9989
286c2a21f36f
parent 9988
1ba9d07ba9da
child 9990
54c614d91eff

MicroPython
- refactored the code to prepare for support of 'webrepl' interface

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.MicroPython.Devices.DeviceBase.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonDeviceInterface.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.Project.CreateDialogCodeDialog.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.Project.ProjectResourcesBrowser.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.Project.UicLoadUi5.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.Project.UicLoadUi6.html file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/CircuitPythonDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/DeviceBase.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/EspDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/GenericMicroPythonDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/MicrobitDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/PyBoardDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/RP2040Devices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/STLinkDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/TeensyDevices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonDeviceInterface.py file | annotate | diff | comparison | revisions
--- a/src/eric7/APIs/Python3/eric7.api	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/APIs/Python3/eric7.api	Thu Apr 27 17:59:09 2023 +0200
@@ -2692,6 +2692,7 @@
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.disconnectWifi?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.downloadFirmware?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.ensurePath?4(target)
+eric7.MicroPython.Devices.DeviceBase.BaseDevice.executeCommands?4(commands, *, mode="raw", timeout=0)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.exists?4(pathname)
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.fileSystemInfo?4()
 eric7.MicroPython.Devices.DeviceBase.BaseDevice.forceInterrupt?4()
@@ -2960,9 +2961,8 @@
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.dataReceived?7
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.disconnectFromDevice?4()
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.execute?4(commands, *, mode="raw", timeout=0)
-eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.executeAsync?4(commandsList)
+eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.executeAsync?4(commandsList, submitMode)
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.executeAsyncFinished?7
-eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.executeAsyncPaste?4(commandsList)
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.handlePreferencesChanged?4()
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.isConnected?4()
 eric7.MicroPython.MicroPythonDeviceInterface.MicroPythonDeviceInterface.probeDevice?4()
@@ -7975,7 +7975,6 @@
 eric7.Project.CreateDialogCodeDialog.pyqtSignatureRole?7
 eric7.Project.CreateDialogCodeDialog.pythonSignatureRole?7
 eric7.Project.CreateDialogCodeDialog.returnTypeRole?7
-eric7.Project.CreateDialogCodeDialog.rubySignatureRole?7
 eric7.Project.DebuggerPropertiesDialog.DebuggerPropertiesDialog.on_debugClientClearHistoryButton_clicked?4()
 eric7.Project.DebuggerPropertiesDialog.DebuggerPropertiesDialog.on_debugClientPicker_aboutToShowPathPickerDialog?4()
 eric7.Project.DebuggerPropertiesDialog.DebuggerPropertiesDialog.storeData?4()
@@ -8329,7 +8328,6 @@
 eric7.Project.ProjectOthersBrowser.ProjectOthersBrowser.showMenu?7
 eric7.Project.ProjectOthersBrowser.ProjectOthersBrowser?1(project, projectBrowser, parent=None)
 eric7.Project.ProjectResourcesBrowser.ProjectResourcesBrowser.RCFilenameFormatPython?7
-eric7.Project.ProjectResourcesBrowser.ProjectResourcesBrowser.RCFilenameFormatRuby?7
 eric7.Project.ProjectResourcesBrowser.ProjectResourcesBrowser._contextMenuRequested?5(coord)
 eric7.Project.ProjectResourcesBrowser.ProjectResourcesBrowser._createPopupMenus?5()
 eric7.Project.ProjectResourcesBrowser.ProjectResourcesBrowser._initHookMethods?5()
@@ -8404,10 +8402,12 @@
 eric7.Project.TranslationPropertiesDialog.TranslationPropertiesDialog?1(project, new, parent)
 eric7.Project.UicCompilerOptionsDialog.UicCompilerOptionsDialog.getData?4()
 eric7.Project.UicCompilerOptionsDialog.UicCompilerOptionsDialog?1(compilerOptions, compiler, parent=None)
+eric7.Project.UicLoadUi5._printerr?5(dataString)
 eric7.Project.UicLoadUi5._printout?5(dataString)
 eric7.Project.UicLoadUi5.className?4(formFile, projectPath)
 eric7.Project.UicLoadUi5.objectName?4(formFile, projectPath)
 eric7.Project.UicLoadUi5.signatures?4(formFile, projectPath)
+eric7.Project.UicLoadUi6._printerr?5(dataString)
 eric7.Project.UicLoadUi6._printout?5(dataString)
 eric7.Project.UicLoadUi6.className?4(formFile, projectPath)
 eric7.Project.UicLoadUi6.objectName?4(formFile, projectPath)
Binary file src/eric7/Documentation/Help/source.qch has changed
--- a/src/eric7/Documentation/Help/source.qhp	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/Documentation/Help/source.qhp	Thu Apr 27 17:59:09 2023 +0200
@@ -2097,6 +2097,7 @@
       <keyword name="BaseDevice.disconnectWifi" id="BaseDevice.disconnectWifi" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.disconnectWifi" />
       <keyword name="BaseDevice.downloadFirmware" id="BaseDevice.downloadFirmware" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.downloadFirmware" />
       <keyword name="BaseDevice.ensurePath" id="BaseDevice.ensurePath" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.ensurePath" />
+      <keyword name="BaseDevice.executeCommands" id="BaseDevice.executeCommands" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.executeCommands" />
       <keyword name="BaseDevice.exists" id="BaseDevice.exists" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.exists" />
       <keyword name="BaseDevice.fileSystemInfo" id="BaseDevice.fileSystemInfo" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.fileSystemInfo" />
       <keyword name="BaseDevice.forceInterrupt" id="BaseDevice.forceInterrupt" ref="eric7.MicroPython.Devices.DeviceBase.html#BaseDevice.forceInterrupt" />
@@ -3642,7 +3643,6 @@
       <keyword name="CreateDialogCodeDialog (Module)" id="CreateDialogCodeDialog (Module)" ref="eric7.Project.CreateDialogCodeDialog.html" />
       <keyword name="CreateDialogCodeDialog.__className" id="CreateDialogCodeDialog.__className" ref="eric7.Project.CreateDialogCodeDialog.html#CreateDialogCodeDialog.__className" />
       <keyword name="CreateDialogCodeDialog.__generateCode" id="CreateDialogCodeDialog.__generateCode" ref="eric7.Project.CreateDialogCodeDialog.html#CreateDialogCodeDialog.__generateCode" />
-      <keyword name="CreateDialogCodeDialog.__generatePythonCode" id="CreateDialogCodeDialog.__generatePythonCode" ref="eric7.Project.CreateDialogCodeDialog.html#CreateDialogCodeDialog.__generatePythonCode" />
       <keyword name="CreateDialogCodeDialog.__mapType" id="CreateDialogCodeDialog.__mapType" ref="eric7.Project.CreateDialogCodeDialog.html#CreateDialogCodeDialog.__mapType" />
       <keyword name="CreateDialogCodeDialog.__objectName" id="CreateDialogCodeDialog.__objectName" ref="eric7.Project.CreateDialogCodeDialog.html#CreateDialogCodeDialog.__objectName" />
       <keyword name="CreateDialogCodeDialog.__runUicLoadUi" id="CreateDialogCodeDialog.__runUicLoadUi" ref="eric7.Project.CreateDialogCodeDialog.html#CreateDialogCodeDialog.__runUicLoadUi" />
@@ -10793,6 +10793,8 @@
       <keyword name="MicroPythonDeviceInterface" id="MicroPythonDeviceInterface" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface" />
       <keyword name="MicroPythonDeviceInterface (Constructor)" id="MicroPythonDeviceInterface (Constructor)" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__init__" />
       <keyword name="MicroPythonDeviceInterface (Module)" id="MicroPythonDeviceInterface (Module)" ref="eric7.MicroPython.MicroPythonDeviceInterface.html" />
+      <keyword name="MicroPythonDeviceInterface.__executeAsyncPaste" id="MicroPythonDeviceInterface.__executeAsyncPaste" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__executeAsyncPaste" />
+      <keyword name="MicroPythonDeviceInterface.__executeAsyncRaw" id="MicroPythonDeviceInterface.__executeAsyncRaw" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__executeAsyncRaw" />
       <keyword name="MicroPythonDeviceInterface.__execute_paste" id="MicroPythonDeviceInterface.__execute_paste" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__execute_paste" />
       <keyword name="MicroPythonDeviceInterface.__execute_raw" id="MicroPythonDeviceInterface.__execute_raw" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__execute_raw" />
       <keyword name="MicroPythonDeviceInterface.__pasteOff" id="MicroPythonDeviceInterface.__pasteOff" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.__pasteOff" />
@@ -10804,7 +10806,6 @@
       <keyword name="MicroPythonDeviceInterface.disconnectFromDevice" id="MicroPythonDeviceInterface.disconnectFromDevice" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.disconnectFromDevice" />
       <keyword name="MicroPythonDeviceInterface.execute" id="MicroPythonDeviceInterface.execute" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.execute" />
       <keyword name="MicroPythonDeviceInterface.executeAsync" id="MicroPythonDeviceInterface.executeAsync" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.executeAsync" />
-      <keyword name="MicroPythonDeviceInterface.executeAsyncPaste" id="MicroPythonDeviceInterface.executeAsyncPaste" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.executeAsyncPaste" />
       <keyword name="MicroPythonDeviceInterface.handlePreferencesChanged" id="MicroPythonDeviceInterface.handlePreferencesChanged" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.handlePreferencesChanged" />
       <keyword name="MicroPythonDeviceInterface.isConnected" id="MicroPythonDeviceInterface.isConnected" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.isConnected" />
       <keyword name="MicroPythonDeviceInterface.probeDevice" id="MicroPythonDeviceInterface.probeDevice" ref="eric7.MicroPython.MicroPythonDeviceInterface.html#MicroPythonDeviceInterface.probeDevice" />
@@ -19188,6 +19189,8 @@
       <keyword name="_percentReplacementFunc" id="_percentReplacementFunc" ref="eric7.Utilities.__init__.html#_percentReplacementFunc" />
       <keyword name="_prettifyJSON" id="_prettifyJSON" ref="eric7.CycloneDXInterface.CycloneDXUtilities.html#_prettifyJSON" />
       <keyword name="_prettifyXML" id="_prettifyXML" ref="eric7.CycloneDXInterface.CycloneDXUtilities.html#_prettifyXML" />
+      <keyword name="_printerr" id="_printerr" ref="eric7.Project.UicLoadUi5.html#_printerr" />
+      <keyword name="_printerr" id="_printerr" ref="eric7.Project.UicLoadUi6.html#_printerr" />
       <keyword name="_printout" id="_printout" ref="eric7.Project.UicLoadUi5.html#_printout" />
       <keyword name="_printout" id="_printout" ref="eric7.Project.UicLoadUi6.html#_printout" />
       <keyword name="_shallPatch" id="_shallPatch" ref="eric7.DebugClients.Python.MultiProcessDebugExtension.html#_shallPatch" />
--- a/src/eric7/Documentation/Source/eric7.MicroPython.Devices.DeviceBase.html	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.Devices.DeviceBase.html	Thu Apr 27 17:59:09 2023 +0200
@@ -251,6 +251,10 @@
 <td>Public method to ensure, that the given target path exists.</td>
 </tr>
 <tr>
+<td><a href="#BaseDevice.executeCommands">executeCommands</a></td>
+<td>Public method to send commands to the connected device and return the result.</td>
+</tr>
+<tr>
 <td><a href="#BaseDevice.exists">exists</a></td>
 <td>Public method to check the existence of a file or directory.</td>
 </tr>
@@ -1070,6 +1074,46 @@
 target directory
 </dd>
 </dl>
+<a NAME="BaseDevice.executeCommands" ID="BaseDevice.executeCommands"></a>
+<h4>BaseDevice.executeCommands</h4>
+<b>executeCommands</b>(<i>commands, *, mode="raw", timeout=0</i>)
+
+<p>
+        Public method to send commands to the connected device and return the
+        result.
+</p>
+<p>
+        If no connected interface is available, empty results will be returned.
+</p>
+<dl>
+
+<dt><i>commands</i> (str or list of str)</dt>
+<dd>
+list of commands to be executed
+</dd>
+<dt><i>mode=</i> (str)</dt>
+<dd>
+submit mode to be used (one of 'raw' or 'paste') (defaults to
+            'raw')
+</dd>
+<dt><i>timeout=</i> (int (optional))</dt>
+<dd>
+per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing stdout and stderr output of the device
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (bytes, bytes)
+</dd>
+</dl>
 <a NAME="BaseDevice.exists" ID="BaseDevice.exists"></a>
 <h4>BaseDevice.exists</h4>
 <b>exists</b>(<i>pathname</i>)
--- a/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonDeviceInterface.html	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.MicroPython.MicroPythonDeviceInterface.html	Thu Apr 27 17:59:09 2023 +0200
@@ -73,6 +73,14 @@
 <td>Constructor</td>
 </tr>
 <tr>
+<td><a href="#MicroPythonDeviceInterface.__executeAsyncPaste">__executeAsyncPaste</a></td>
+<td>Private method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td>
+</tr>
+<tr>
+<td><a href="#MicroPythonDeviceInterface.__executeAsyncRaw">__executeAsyncRaw</a></td>
+<td>Private method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td>
+</tr>
+<tr>
 <td><a href="#MicroPythonDeviceInterface.__execute_paste">__execute_paste</a></td>
 <td>Private method to send commands to the connected device using 'paste' mode and return the result.</td>
 </tr>
@@ -117,10 +125,6 @@
 <td>Public method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td>
 </tr>
 <tr>
-<td><a href="#MicroPythonDeviceInterface.executeAsyncPaste">executeAsyncPaste</a></td>
-<td>Public method to execute a series of commands over a period of time without returning any result (asynchronous execution).</td>
-</tr>
-<tr>
 <td><a href="#MicroPythonDeviceInterface.handlePreferencesChanged">handlePreferencesChanged</a></td>
 <td>Public slot to handle a change of the preferences.</td>
 </tr>
@@ -157,6 +161,36 @@
 reference to the parent object
 </dd>
 </dl>
+<a NAME="MicroPythonDeviceInterface.__executeAsyncPaste" ID="MicroPythonDeviceInterface.__executeAsyncPaste"></a>
+<h4>MicroPythonDeviceInterface.__executeAsyncPaste</h4>
+<b>__executeAsyncPaste</b>(<i>commandsList</i>)
+
+<p>
+        Private method to execute a series of commands over a period of time
+        without returning any result (asynchronous execution).
+</p>
+<dl>
+
+<dt><i>commandsList</i> (list of str)</dt>
+<dd>
+list of commands to be execute on the device
+</dd>
+</dl>
+<a NAME="MicroPythonDeviceInterface.__executeAsyncRaw" ID="MicroPythonDeviceInterface.__executeAsyncRaw"></a>
+<h4>MicroPythonDeviceInterface.__executeAsyncRaw</h4>
+<b>__executeAsyncRaw</b>(<i>commandsList</i>)
+
+<p>
+        Private method to execute a series of commands over a period of time
+        without returning any result (asynchronous execution).
+</p>
+<dl>
+
+<dt><i>commandsList</i> (list of bytes)</dt>
+<dd>
+list of commands to be execute on the device
+</dd>
+</dl>
 <a NAME="MicroPythonDeviceInterface.__execute_paste" ID="MicroPythonDeviceInterface.__execute_paste"></a>
 <h4>MicroPythonDeviceInterface.__execute_paste</h4>
 <b>__execute_paste</b>(<i>commands, timeout=0</i>)
@@ -375,7 +409,7 @@
 </dl>
 <a NAME="MicroPythonDeviceInterface.executeAsync" ID="MicroPythonDeviceInterface.executeAsync"></a>
 <h4>MicroPythonDeviceInterface.executeAsync</h4>
-<b>executeAsync</b>(<i>commandsList</i>)
+<b>executeAsync</b>(<i>commandsList, submitMode</i>)
 
 <p>
         Public method to execute a series of commands over a period of time
@@ -383,24 +417,20 @@
 </p>
 <dl>
 
-<dt><i>commandsList</i> (list of bytes)</dt>
+<dt><i>commandsList</i> (list of str)</dt>
 <dd>
 list of commands to be execute on the device
 </dd>
+<dt><i>submitMode</i> (str (one of 'raw' or 'paste'))</dt>
+<dd>
+mode to be used to submit the commands
+</dd>
 </dl>
-<a NAME="MicroPythonDeviceInterface.executeAsyncPaste" ID="MicroPythonDeviceInterface.executeAsyncPaste"></a>
-<h4>MicroPythonDeviceInterface.executeAsyncPaste</h4>
-<b>executeAsyncPaste</b>(<i>commandsList</i>)
-
-<p>
-        Public method to execute a series of commands over a period of time
-        without returning any result (asynchronous execution).
-</p>
 <dl>
 
-<dt><i>commandsList</i> (list of bytes)</dt>
+<dt>Raises <b>ValueError</b>:</dt>
 <dd>
-list of commands to be execute on the device
+raised to indicate an unknown submit mode
 </dd>
 </dl>
 <a NAME="MicroPythonDeviceInterface.handlePreferencesChanged" ID="MicroPythonDeviceInterface.handlePreferencesChanged"></a>
--- a/src/eric7/Documentation/Source/eric7.Project.CreateDialogCodeDialog.html	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.Project.CreateDialogCodeDialog.html	Thu Apr 27 17:59:09 2023 +0200
@@ -14,7 +14,7 @@
 <h3>Global Attributes</h3>
 
 <table>
-<tr><td>parameterNamesListRole</td></tr><tr><td>parameterTypesListRole</td></tr><tr><td>pyqtSignatureRole</td></tr><tr><td>pythonSignatureRole</td></tr><tr><td>returnTypeRole</td></tr><tr><td>rubySignatureRole</td></tr>
+<tr><td>parameterNamesListRole</td></tr><tr><td>parameterTypesListRole</td></tr><tr><td>pyqtSignatureRole</td></tr><tr><td>pythonSignatureRole</td></tr><tr><td>returnTypeRole</td></tr>
 </table>
 <h3>Classes</h3>
 
@@ -64,10 +64,6 @@
 </tr>
 <tr>
 <td><a href="#CreateDialogCodeDialog.__generateCode">__generateCode</a></td>
-<td>Private slot to generate the code as requested by the user.</td>
-</tr>
-<tr>
-<td><a href="#CreateDialogCodeDialog.__generatePythonCode">__generatePythonCode</a></td>
 <td>Private slot to generate Python code as requested by the user.</td>
 </tr>
 <tr>
@@ -163,13 +159,6 @@
 <b>__generateCode</b>(<i></i>)
 
 <p>
-        Private slot to generate the code as requested by the user.
-</p>
-<a NAME="CreateDialogCodeDialog.__generatePythonCode" ID="CreateDialogCodeDialog.__generatePythonCode"></a>
-<h4>CreateDialogCodeDialog.__generatePythonCode</h4>
-<b>__generatePythonCode</b>(<i></i>)
-
-<p>
         Private slot to generate Python code as requested by the user.
 </p>
 <a NAME="CreateDialogCodeDialog.__mapType" ID="CreateDialogCodeDialog.__mapType"></a>
--- a/src/eric7/Documentation/Source/eric7.Project.ProjectResourcesBrowser.html	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.Project.ProjectResourcesBrowser.html	Thu Apr 27 17:59:09 2023 +0200
@@ -57,7 +57,7 @@
 <h3>Class Attributes</h3>
 
 <table>
-<tr><td>RCFilenameFormatPython</td></tr><tr><td>RCFilenameFormatRuby</td></tr>
+<tr><td>RCFilenameFormatPython</td></tr>
 </table>
 <h3>Class Methods</h3>
 
--- a/src/eric7/Documentation/Source/eric7.Project.UicLoadUi5.html	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.Project.UicLoadUi5.html	Thu Apr 27 17:59:09 2023 +0200
@@ -30,8 +30,12 @@
 <td>Private function to map a type as reported by Qt's meta object to the correct Python type.</td>
 </tr>
 <tr>
+<td><a href="#_printerr">_printerr</a></td>
+<td>Function to print the given string as error to sys.stdoerr with a guard string.</td>
+</tr>
+<tr>
 <td><a href="#_printout">_printout</a></td>
-<td>Function to print the given string to sys.stdout with a guard string.</td>
+<td>Function to print the given string as output to sys.stderr with a guard string.</td>
 </tr>
 <tr>
 <td><a href="#className">className</a></td>
@@ -78,12 +82,29 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
+<a NAME="_printerr" ID="_printerr"></a>
+<h2>_printerr</h2>
+<b>_printerr</b>(<i>dataString</i>)
+
+<p>
+    Function to print the given string as error to sys.stdoerr with a guard string.
+</p>
+<dl>
+
+<dt><i>dataString</i> (str)</dt>
+<dd>
+string to be printed
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
 <a NAME="_printout" ID="_printout"></a>
 <h2>_printout</h2>
 <b>_printout</b>(<i>dataString</i>)
 
 <p>
-    Function to print the given string to sys.stdout with a guard string.
+    Function to print the given string as output to sys.stderr with a guard string.
 </p>
 <dl>
 
--- a/src/eric7/Documentation/Source/eric7.Project.UicLoadUi6.html	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/Documentation/Source/eric7.Project.UicLoadUi6.html	Thu Apr 27 17:59:09 2023 +0200
@@ -30,8 +30,12 @@
 <td>Private function to map a type as reported by Qt's meta object to the correct Python type.</td>
 </tr>
 <tr>
+<td><a href="#_printerr">_printerr</a></td>
+<td>Function to print the given string as error to sys.stdoerr with a guard string.</td>
+</tr>
+<tr>
 <td><a href="#_printout">_printout</a></td>
-<td>Function to print the given string to sys.stdout with a guard string.</td>
+<td>Function to print the given string as output to sys.stderr with a guard string.</td>
 </tr>
 <tr>
 <td><a href="#className">className</a></td>
@@ -78,12 +82,29 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
+<a NAME="_printerr" ID="_printerr"></a>
+<h2>_printerr</h2>
+<b>_printerr</b>(<i>dataString</i>)
+
+<p>
+    Function to print the given string as error to sys.stdoerr with a guard string.
+</p>
+<dl>
+
+<dt><i>dataString</i> (str)</dt>
+<dd>
+string to be printed
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
 <a NAME="_printout" ID="_printout"></a>
 <h2>_printout</h2>
 <b>_printout</b>(<i>dataString</i>)
 
 <p>
-    Function to print the given string to sys.stdout with a guard string.
+    Function to print the given string as output to sys.stderr with a guard string.
 </p>
 <dl>
 
--- a/src/eric7/MicroPython/Devices/CircuitPythonDevices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/CircuitPythonDevices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -469,7 +469,7 @@
         Private slot to reset the connected device.
         """
         if self.microPython.isConnected():
-            self.microPython.deviceInterface().execute(
+            self.executeCommands(
                 "import microcontroller as mc\n"
                 "mc.on_next_reset(mc.RunMode.NORMAL)"
                 "mc.reset()\n",
@@ -501,7 +501,7 @@
         Private slot to switch the board into 'bootloader' mode.
         """
         if self.microPython.isConnected():
-            self.microPython.deviceInterface().execute(
+            self.executeCommands(
                 "import microcontroller as mc\n"
                 "mc.on_next_reset(mc.RunMode.BOOTLOADER)\n"
                 "mc.reset()\n",
@@ -514,7 +514,7 @@
         Private slot to switch the board into 'UF2 Boot' mode.
         """
         if self.microPython.isConnected():
-            self.microPython.deviceInterface().execute(
+            self.executeCommands(
                 "import microcontroller as mc\n"
                 "mc.on_next_reset(mc.RunMode.UF2)\n"
                 "mc.reset()\n",
@@ -764,7 +764,7 @@
 print(has_wifi())
 del has_wifi
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return ast.literal_eval(out.decode("utf-8"))
@@ -848,7 +848,7 @@
 del wifi_status
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -902,7 +902,7 @@
         )
 
         with EricOverrideCursor():
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=15000
             )
         if err:
@@ -938,7 +938,7 @@
 del disconnect_wifi
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
 
@@ -1070,7 +1070,7 @@
 del check_internet
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
 
@@ -1107,9 +1107,7 @@
 del scan_networks
 """
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=15000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
             return [], err
 
@@ -1162,7 +1160,7 @@
 del deactivate
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
         else:
@@ -1214,9 +1212,7 @@
             repr(ssid), repr(password), authmode
         )
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=15000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
             return False, err
         elif out and out.startswith(b"Error:"):
@@ -1245,7 +1241,7 @@
 del stop_ap
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
         elif out and out.startswith(b"Error:"):
@@ -1294,9 +1290,7 @@
 del has_eth
 """
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1339,9 +1333,7 @@
             WiznetUtilities.cpyWiznetInit()
         )
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1396,7 +1388,7 @@
         )
 
         with EricOverrideCursor():
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=15000
             )
         if err:
@@ -1428,7 +1420,7 @@
         )
 
         with EricOverrideCursor():
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=15000
             )
         if err:
@@ -1465,9 +1457,7 @@
             WiznetUtilities.cpyWiznetInit(),
         )
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=15000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
             return False, err
 
@@ -1621,9 +1611,7 @@
 print(has_bt())
 del has_bt
 """
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             raise OSError(self._shortError(err))
         return out.strip() == b"True"
@@ -1666,7 +1654,7 @@
 ble_status()
 del ble_status
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1703,7 +1691,7 @@
 activate_ble()
 del activate_ble
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1729,7 +1717,7 @@
 deactivate_ble()
 del deactivate_ble
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1790,7 +1778,7 @@
 """.format(
             timeout
         )
-        out, err = self._interface.execute(
+        out, err = self.executeCommands(
             command, mode=self._submitMode, timeout=(timeout + 5) * 1000
         )
         if err:
@@ -1845,7 +1833,7 @@
 print(has_ntp())
 del has_ntp
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return out.strip() == b"True"
@@ -1937,7 +1925,7 @@
                 repr(server), tzOffset, timeout
             )
 
-        out, err = self._interface.execute(
+        out, err = self.executeCommands(
             command, mode=self._submitMode, timeout=(timeout + 2) * 1000
         )
         if err:
--- a/src/eric7/MicroPython/Devices/DeviceBase.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/DeviceBase.py	Thu Apr 27 17:59:09 2023 +0200
@@ -118,7 +118,7 @@
         super().__init__(parent)
 
         self._deviceType = deviceType
-        self._interface = microPythonWidget.deviceInterface()
+        self._interface = None
         self.microPython = microPythonWidget
         self._deviceData = {}  # dictionary with essential device data
 
@@ -137,6 +137,7 @@
         self._deviceData = {}
 
         if connected:
+            self._interface = self.microPython.deviceInterface()
             with contextlib.suppress(OSError):
                 self._deviceData = self.__getDeviceData()
                 self._deviceData["local_mip"] = (
@@ -149,6 +150,8 @@
                     self._deviceData["ethernet_type"],
                 ) = self.hasEthernet()
                 self._deviceData["ntp"] = self.hasNetworkTime()
+        else:
+            self._interface = None
 
     def getDeviceType(self):
         """
@@ -381,6 +384,29 @@
             # user cancelled
             return ""
 
+    def executeCommands(self, commands, *, mode="raw", timeout=0):
+        """
+        Public method to send commands to the connected device and return the
+        result.
+
+        If no connected interface is available, empty results will be returned.
+
+        @param commands list of commands to be executed
+        @type str or list of str
+        @keyparam mode submit mode to be used (one of 'raw' or 'paste') (defaults to
+            'raw')
+        @type str
+        @keyparam timeout per command timeout in milliseconds (0 for configured default)
+            (defaults to 0)
+        @type int (optional)
+        @return tuple containing stdout and stderr output of the device
+        @rtype tuple of (bytes, bytes)
+        """
+        if self._interface is None:
+            return b"", b""
+
+        return self._interface.execute(commands, mode=mode, timeout=timeout)
+
     def sendCommands(self, commandsList):
         """
         Public method to send a list of commands to the device.
@@ -388,25 +414,8 @@
         @param commandsList list of commands to be sent to the device
         @type list of str
         """
-        if self._submitMode == "raw":
-            rawOn = [  # sequence of commands to enter raw mode
-                b"\x02",  # Ctrl-B: exit raw repl (just in case)
-                b"\r\x03\x03\x03",  # Ctrl-C three times: interrupt any running program
-                b"\r\x01",  # Ctrl-A: enter raw REPL
-            ]
-            newLine = [
-                b'print("\\n")\r',
-            ]
-            commands = [c.encode("utf-8)") + b"\r" for c in commandsList]
-            commands.append(b"\r")
-            commands.append(b"\x04")
-            rawOff = [b"\x02", b"\x02"]
-            commandSequence = rawOn + newLine + commands + rawOff
-            self._interface.executeAsync(commandSequence)
-        elif self._submitMode == "paste":
-            commands = b"\n".join([c.encode("utf-8)") for c in commandsList])
-            commandSequence = ["@PasteOn@", commands]
-            self._interface.executeAsyncPaste(commandSequence)
+        if self._interface is not None:
+            self._interface.executeAsync(commandsList, self._submitMode)
 
     @pyqtSlot()
     def handleDataFlood(self):
@@ -543,7 +552,7 @@
 """.format(
             repr(pathname)
         )
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return out.strip() == b"True"
@@ -565,7 +574,7 @@
 """.format(
             dirname
         )
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return ast.literal_eval(out.decode("utf-8"))
@@ -617,7 +626,7 @@
 """.format(
             dirname, showHidden
         )
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         fileslist = ast.literal_eval(out.decode("utf-8"))
@@ -645,7 +654,7 @@
 """.format(
                 dirname
             )
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -662,7 +671,7 @@
 print(__os_.getcwd())
 del __os_
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return out.decode("utf-8").strip()
@@ -687,7 +696,7 @@
 """.format(
                 filename
             )
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -734,7 +743,7 @@
 """.format(
                 name, recursive, force
             )
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=20000
             )
             if err:
@@ -759,7 +768,7 @@
 """.format(
                 dirname
             )
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -786,7 +795,7 @@
 """.format(
                 dirname
             )
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -848,7 +857,7 @@
         )
         command = "\n".join(commands)
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return True
@@ -917,7 +926,7 @@
 """.format(
             deviceFileName
         )
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -962,7 +971,7 @@
 print(fsinfo())
 del __os_, fsinfo
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         infodict = ast.literal_eval(out.decode("utf-8"))
@@ -1084,7 +1093,7 @@
 print(get_device_data())
 del get_device_data
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return ast.literal_eval(out.decode("utf-8"))
@@ -1198,7 +1207,7 @@
 print(get_board_info())
 del get_board_info
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return ast.literal_eval(out.decode("utf-8"))
@@ -1212,7 +1221,7 @@
         @exception OSError raised to indicate an issue with the device
         """
         commands = ["help('modules')"]
-        out, err = self._interface.execute(commands, mode=self._submitMode)
+        out, err = self.executeCommands(commands, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1255,7 +1264,7 @@
 get_time()
 del get_time
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             if b"NotImplementedError" in err:
                 return "&lt;unsupported&gt; &lt;unsupported&gt;"
@@ -1327,7 +1336,7 @@
                     now.tm_isdst,
                 ),
             )
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 raise OSError(self._shortError(err))
 
@@ -1354,7 +1363,7 @@
 """.format(
             repr(packages)
         )
-        return self._interface.execute(command, mode=self._submitMode, timeout=60000)
+        return self.executeCommands(command, mode=self._submitMode, timeout=60000)
 
     def mipInstall(self, package, index=None, target=None, version=None, mpy=True):
         """
@@ -1393,7 +1402,7 @@
 """.format(
             parameterStr
         )
-        return self._interface.execute(command, mode=self._submitMode, timeout=60000)
+        return self.executeCommands(command, mode=self._submitMode, timeout=60000)
 
     def getLibPaths(self):
         """
@@ -1411,7 +1420,7 @@
 lib_paths()
 del lib_paths
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
--- a/src/eric7/MicroPython/Devices/EspDevices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/EspDevices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -508,7 +508,7 @@
         Private slot to reset the connected device.
         """
         if self.microPython.isConnected() and not self.hasCircuitPython():
-            self.microPython.deviceInterface().execute(
+            self.executeCommands(
                 "import machine\nmachine.reset()\n", mode=self._submitMode
             )
         else:
@@ -688,7 +688,7 @@
 del wifi_status
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -745,7 +745,7 @@
         )
 
         with EricOverrideCursor():
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=15000
             )
         if err:
@@ -787,7 +787,7 @@
 del disconnect_wifi
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
 
@@ -842,7 +842,7 @@
 del modify_boot
 """
 
-        out, err = self._interface.execute(nvsCommand, mode=self._submitMode)
+        out, err = self.executeCommands(nvsCommand, mode=self._submitMode)
         if err:
             return False, self.tr("Error saving credentials: {0}").format(err)
 
@@ -857,7 +857,7 @@
         except OSError as err:
             return False, self.tr("Error saving auto-connect script: {0}").format(err)
 
-        out, err = self._interface.execute(bootCommand, mode=self._submitMode)
+        out, err = self.executeCommands(bootCommand, mode=self._submitMode)
         if err:
             return False, self.tr("Error modifying 'boot.py': {0}").format(err)
 
@@ -889,7 +889,7 @@
 del delete_wifi_creds
 """
 
-        out, err = self._interface.execute(nvsCommand, mode=self._submitMode)
+        out, err = self.executeCommands(nvsCommand, mode=self._submitMode)
         if err:
             return False, self.tr("Error deleting credentials: {0}").format(err)
 
@@ -926,7 +926,7 @@
 del check_internet
 """
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
 
@@ -960,9 +960,7 @@
 del scan_networks
 """
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=15000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
             return [], err
 
@@ -1017,7 +1015,7 @@
             interface
         )
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
         else:
@@ -1070,9 +1068,7 @@
             repr(ssid), security, repr(password), ifconfig
         )
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=15000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
             return False, err
         else:
@@ -1113,9 +1109,7 @@
 del get_stations
 """
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             return [], err
 
@@ -1152,9 +1146,7 @@
 print(has_bt())
 del has_bt
 """
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             raise OSError(self._shortError(err))
         return out.strip() == b"True"
@@ -1200,7 +1192,7 @@
 ble_status()
 del ble_status
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1245,7 +1237,7 @@
 activate_ble()
 del activate_ble
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1274,7 +1266,7 @@
 deactivate_ble()
 del deactivate_ble
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1334,7 +1326,7 @@
 """.format(
             timeout
         )
-        out, err = self._interface.execute(
+        out, err = self.executeCommands(
             command, mode=self._submitMode, timeout=(timeout + 5) * 1000
         )
         if err:
@@ -1379,7 +1371,7 @@
 print(has_ntp())
 del has_ntp
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return out.strip() == b"True"
@@ -1439,7 +1431,7 @@
 """.format(
             repr(server), tzOffset, timeout
         )
-        out, err = self._interface.execute(
+        out, err = self.executeCommands(
             command, mode=self._submitMode, timeout=(timeout + 2) * 1000
         )
         if err:
--- a/src/eric7/MicroPython/Devices/GenericMicroPythonDevices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/GenericMicroPythonDevices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -249,7 +249,7 @@
         Private slot to switch the board into 'bootloader' mode.
         """
         if self.microPython.isConnected():
-            self.microPython.deviceInterface().execute(
+            self.executeCommands(
                 "import machine\nmachine.bootloader()\n", mode=self._submitMode
             )
             # simulate pressing the disconnect button
@@ -334,11 +334,12 @@
         """
         Private slot to reset the connected device.
         """
-        self.microPython.deviceInterface().execute(
-            "import machine\nmachine.reset()\n", mode=self._submitMode
-        )
-        # simulate pressing the disconnect button
-        self.microPython.on_connectButton_clicked()
+        if self.microPython.isConnected():
+            self.executeCommands(
+                "import machine\nmachine.reset()\n", mode=self._submitMode
+            )
+            # simulate pressing the disconnect button
+            self.microPython.on_connectButton_clicked()
 
     def getDocumentationUrl(self):
         """
--- a/src/eric7/MicroPython/Devices/MicrobitDevices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/MicrobitDevices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -526,16 +526,18 @@
         """
         Private slot to reset the connected device.
         """
-        if self.getDeviceType() == "bbc_microbit":
-            # BBC micro:bit
-            self.microPython.deviceInterface().execute(
-                "import microbit\nmicrobit.reset()\n", mode=self._submitMode
-            )
-        else:
-            # Calliope mini
-            self.microPython.deviceInterface().execute(
-                "import calliope_mini\ncalliope_mini.reset()\n", mode=self._submitMode
-            )
+        if self.microPython.isConnected():
+            if self.getDeviceType() == "bbc_microbit":
+                # BBC micro:bit
+                self.executeCommands(
+                    "import microbit\nmicrobit.reset()\n", mode=self._submitMode
+                )
+            else:
+                # Calliope mini
+                self.executeCommands(
+                    "import calliope_mini\ncalliope_mini.reset()\n",
+                    mode=self._submitMode,
+                )
 
     def getDocumentationUrl(self):
         """
@@ -626,7 +628,7 @@
 print(__os_.listdir())
 del __os_
 """
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 raise OSError(self._shortError(err))
             return ast.literal_eval(out.decode("utf-8"))
@@ -674,7 +676,7 @@
 """.format(
                 showHidden
             )
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 raise OSError(self._shortError(err))
             fileslist = ast.literal_eval(out.decode("utf-8"))
@@ -765,9 +767,7 @@
 print(has_bt())
 del has_bt
 """
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             raise OSError(self._shortError(err))
         return out.strip() == b"True"
@@ -811,7 +811,7 @@
 ble_status()
 del ble_status
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -848,7 +848,7 @@
 activate_ble()
 del activate_ble
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -874,7 +874,7 @@
 deactivate_ble()
 del deactivate_ble
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -935,7 +935,7 @@
 """.format(
             timeout
         )
-        out, err = self._interface.execute(
+        out, err = self.executeCommands(
             command, mode=self._submitMode, timeout=(timeout + 5) * 1000
         )
         if err:
--- a/src/eric7/MicroPython/Devices/PyBoardDevices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/PyBoardDevices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -500,7 +500,7 @@
         Private slot to activate the bootloader and disconnect.
         """
         if self.microPython.isConnected():
-            self.microPython.deviceInterface().execute(
+            self.executeCommands(
                 [
                     "import pyb",
                     "pyb.bootloader()",
@@ -515,9 +515,10 @@
         """
         Private slot to reset the connected device.
         """
-        self.microPython.deviceInterface().execute(
-            "import machine\nmachine.reset()\n", mode=self._submitMode
-        )
+        if self.microPython.isConnected():
+            self.executeCommands(
+                "import machine\nmachine.reset()\n", mode=self._submitMode
+            )
 
     ##################################################################
     ## time related methods below
--- a/src/eric7/MicroPython/Devices/RP2040Devices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/RP2040Devices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -239,7 +239,7 @@
         Private slot to switch the board into 'bootloader' mode.
         """
         if self.microPython.isConnected():
-            self.microPython.deviceInterface().execute(
+            self.executeCommands(
                 [
                     "import machine",
                     "machine.bootloader()",
@@ -338,9 +338,10 @@
         """
         Private slot to reset the connected device.
         """
-        self.microPython.deviceInterface().execute(
-            "import machine\nmachine.reset()\n", mode=self._submitMode
-        )
+        if self.microPython.isConnected():
+            self.executeCommands(
+                "import machine\nmachine.reset()\n", mode=self._submitMode
+            )
 
     def getDocumentationUrl(self):
         """
@@ -463,9 +464,7 @@
 print(has_wifi())
 del has_wifi
 """
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             if not err.startswith(b"Timeout "):
                 raise OSError(self._shortError(err))
@@ -584,7 +583,7 @@
         else:
             return super().getWifiData()
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -698,7 +697,7 @@
             return super().connectWifi(ssid, password)
 
         with EricOverrideCursor():
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=15000
             )
         if err:
@@ -756,7 +755,7 @@
         else:
             return super().disconnectWifi()
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
 
@@ -823,7 +822,7 @@
             return False, str(err)
 
         # modify boot.py
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
 
@@ -888,9 +887,7 @@
         else:
             return super().checkInternet()
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             return False, err
 
@@ -953,9 +950,7 @@
         else:
             return super().scanNetworks()
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=15000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
             return [], err
 
@@ -1031,7 +1026,7 @@
         else:
             return super().deactivateInterface(interface)
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
         else:
@@ -1122,9 +1117,7 @@
         else:
             return super().startAccessPoint(ssid, security=security, password=password)
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=15000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=15000)
         if err:
             return False, err
         else:
@@ -1172,9 +1165,7 @@
         else:
             return super().checkInternet()
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             return [], err
 
@@ -1209,9 +1200,7 @@
 del has_eth
 """
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1250,7 +1239,7 @@
             WiznetUtilities.mpyWiznetInit()
         )
 
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
 
@@ -1307,7 +1296,7 @@
         )
 
         with EricOverrideCursor():
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=15000
             )
         if err:
@@ -1339,7 +1328,7 @@
         )
 
         with EricOverrideCursor():
-            out, err = self._interface.execute(
+            out, err = self.executeCommands(
                 command, mode=self._submitMode, timeout=15000
             )
         if err:
@@ -1378,9 +1367,7 @@
             WiznetUtilities.mpyWiznetInit(),
         )
 
-        out, err = self._interface.execute(
-            command, mode=self._submitMode, timeout=10000
-        )
+        out, err = self.executeCommands(command, mode=self._submitMode, timeout=10000)
         if err:
             return False, err
 
@@ -1445,7 +1432,7 @@
             return False, str(err)
 
         # modify boot.py
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             return False, err
 
@@ -1490,7 +1477,7 @@
 print(has_ntp())
 del has_ntp
 """
-        out, err = self._interface.execute(command, mode=self._submitMode)
+        out, err = self.executeCommands(command, mode=self._submitMode)
         if err:
             raise OSError(self._shortError(err))
         return out.strip() == b"True"
@@ -1551,7 +1538,7 @@
 """.format(
             repr(server), tzOffset, timeout
         )
-        out, err = self._interface.execute(
+        out, err = self.executeCommands(
             command, mode=self._submitMode, timeout=(timeout + 2) * 1000
         )
         if err:
@@ -1586,7 +1573,7 @@
                 repr(country)
             )
 
-            out, err = self._interface.execute(command, mode=self._submitMode)
+            out, err = self.executeCommands(command, mode=self._submitMode)
             if err:
                 self.microPython.showError("rp2.country()", err)
 
--- a/src/eric7/MicroPython/Devices/STLinkDevices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/STLinkDevices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -468,9 +468,10 @@
         """
         Private slot to reset the connected device.
         """
-        self.microPython.deviceInterface().execute(
-            "import machine\nmachine.reset()\n", mode=self._submitMode
-        )
+        if self.microPython.isConnected():
+            self.executeCommands(
+                "import machine\nmachine.reset()\n", mode=self._submitMode
+            )
 
 
 def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber):
--- a/src/eric7/MicroPython/Devices/TeensyDevices.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/Devices/TeensyDevices.py	Thu Apr 27 17:59:09 2023 +0200
@@ -243,9 +243,10 @@
         """
         Private slot to reset the connected device.
         """
-        self.microPython.deviceInterface().execute(
-            "import machine\nmachine.reset()\n", mode=self._submitMode
-        )
+        if self.microPython.isConnected():
+            self.executeCommands(
+                "import machine\nmachine.reset()\n", mode=self._submitMode
+            )
 
     ##################################################################
     ## time related methods below
--- a/src/eric7/MicroPython/MicroPythonDeviceInterface.py	Mon Apr 24 17:51:11 2023 +0200
+++ b/src/eric7/MicroPython/MicroPythonDeviceInterface.py	Thu Apr 27 17:59:09 2023 +0200
@@ -427,39 +427,68 @@
         self.__blockReadyRead = False
         return out, err
 
-    def executeAsync(self, commandsList):
+    def executeAsync(self, commandsList, submitMode):
         """
         Public method to execute a series of commands over a period of time
         without returning any result (asynchronous execution).
 
         @param commandsList list of commands to be execute on the device
+        @type list of str
+        @param submitMode mode to be used to submit the commands
+        @type str (one of 'raw' or 'paste')
+        @exception ValueError raised to indicate an unknown submit mode
+        """
+        if submitMode not in ("raw", "paste"):
+            raise ValueError("Illegal submit mode given ({0})".format(submitMode))
+
+        if submitMode == "raw":
+            startSequence = [  # sequence of commands to enter raw mode
+                b"\x02",  # Ctrl-B: exit raw repl (just in case)
+                b"\r\x03\x03\x03",  # Ctrl-C three times: interrupt any running program
+                b"\r\x01",  # Ctrl-A: enter raw REPL
+                b'print("\\n")\r',
+            ]
+            endSequence = [
+                b"\r",
+                b"\x04",
+            ]
+            self.__executeAsyncRaw(
+                startSequence
+                + [c.encode("utf-8") + b"\r" for c in commandsList]
+                + endSequence
+            )
+        elif submitMode == "paste":
+            self.__executeAsyncPaste(commandsList)
+
+    def __executeAsyncRaw(self, commandsList):
+        """
+        Private method to execute a series of commands over a period of time
+        without returning any result (asynchronous execution).
+
+        @param commandsList list of commands to be execute on the device
         @type list of bytes
         """
         if commandsList:
             command = commandsList.pop(0)
             self.__serial.write(command)
-            QTimer.singleShot(2, lambda: self.executeAsync(commandsList))
+            QTimer.singleShot(2, lambda: self.__executeAsyncRaw(commandsList))
         else:
+            self.__rawOff()
             self.executeAsyncFinished.emit()
 
-    def executeAsyncPaste(self, commandsList):
+    def __executeAsyncPaste(self, commandsList):
         """
-        Public method to execute a series of commands over a period of time
+        Private method to execute a series of commands over a period of time
         without returning any result (asynchronous execution).
 
         @param commandsList list of commands to be execute on the device
-        @type list of bytes
+        @type list of str
         """
-        if commandsList:
-            self.__blockReadyRead = True
-            command = commandsList.pop(0)
-            if command == "@PasteOn@":
-                self.__pasteOn()
-            else:
-                self.__serial.write(command)
-                self.__serial.readUntil(command)
-            QTimer.singleShot(2, lambda: self.executeAsyncPaste(commandsList))
-        else:
-            self.__blockReadyRead = False
-            self.__pasteOff()
-            self.executeAsyncFinished.emit()
+        self.__blockReadyRead = True
+        self.__pasteOn()
+        command = b"\n".join(c.encode("utf-8)") for c in commandsList)
+        self.__serial.write(command)
+        self.__serial.readUntil(command)
+        self.__blockReadyRead = False
+        self.__pasteOff()
+        self.executeAsyncFinished.emit

eric ide

mercurial