diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 000000000..91e1a30fa --- /dev/null +++ b/mypy.ini @@ -0,0 +1,11 @@ +# Global options: + +[mypy] +strict_optional = False + +[mypy-asttokens.*] +ignore_missing_imports = True + +[mypy-jedi.*] +ignore_missing_imports = True + diff --git a/thonny/misc_utils.py b/thonny/misc_utils.py index b7c80c048..8d0c0e076 100644 --- a/thonny/misc_utils.py +++ b/thonny/misc_utils.py @@ -49,14 +49,7 @@ def running_on_rpi() -> bool: def list_volumes(skip_letters=set()) -> Sequence[str]: "Adapted from https://github.com/ntoll/uflash/blob/master/uflash.py" - if os.name == "posix": - # 'posix' means we're on Linux or OSX (Mac). - # Call the unix "mount" command to list the mounted volumes. - mount_output = subprocess.check_output("mount").splitlines() - return [x.split()[2].decode("utf-8") for x in mount_output] - - elif os.name == "nt": - # 'nt' means we're on Windows. + if sys.platform == "win32": import ctypes # @@ -79,8 +72,10 @@ def list_volumes(skip_letters=set()) -> Sequence[str]: finally: ctypes.windll.kernel32.SetErrorMode(old_mode) # @UndefinedVariable else: - # No support for unknown operating systems. - raise NotImplementedError('OS "{}" not supported.'.format(os.name)) + # 'posix' means we're on Linux or OSX (Mac). + # Call the unix "mount" command to list the mounted volumes. + mount_output = subprocess.check_output("mount").splitlines() + return [x.split()[2].decode("utf-8") for x in mount_output] def get_win_volume_name(path: str) -> str: @@ -90,14 +85,24 @@ def get_win_volume_name(path: str) -> str: the given disk/device. Code from http://stackoverflow.com/a/12056414 """ - import ctypes + if sys.platform == "win32": + import ctypes - vol_name_buf = ctypes.create_unicode_buffer(1024) - ctypes.windll.kernel32.GetVolumeInformationW( # @UndefinedVariable - ctypes.c_wchar_p(path), vol_name_buf, ctypes.sizeof(vol_name_buf), None, None, None, None, 0 - ) - assert isinstance(vol_name_buf.value, str) - return vol_name_buf.value + vol_name_buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.kernel32.GetVolumeInformationW( # @UndefinedVariable + ctypes.c_wchar_p(path), + vol_name_buf, + ctypes.sizeof(vol_name_buf), + None, + None, + None, + None, + 0, + ) + assert isinstance(vol_name_buf.value, str) + return vol_name_buf.value + else: + raise RuntimeError("Only meant for Windows") def find_volumes_by_name(volume_name: str, skip_letters={"A"}) -> Sequence[str]: diff --git a/thonny/plugins/micropython/bare_metal_backend.py b/thonny/plugins/micropython/bare_metal_backend.py index f00fa3c1b..227d2d8e4 100644 --- a/thonny/plugins/micropython/bare_metal_backend.py +++ b/thonny/plugins/micropython/bare_metal_backend.py @@ -25,7 +25,7 @@ ends_overlap, linux_dirname_basename, ) -from thonny.plugins.micropython.connection import ConnectionFailedException +from thonny.plugins.micropython.connection import ConnectionFailedException, MicroPythonConnection # See https://github.com/dhylands/rshell/blob/master/rshell/main.py # for UART_BUFFER_SIZE vs USB_BUFFER_SIZE @@ -274,7 +274,7 @@ def _submit_input(self, cdata: str) -> None: if echo != bdata: # because of autoreload? timing problems? interruption? # Leave it. - logging.warning("Unexpected echo. Expected %s, got %s" % (bdata, echo)) + logging.warning("Unexpected echo. Expected %r, got %r" % (bdata, echo)) self._connection.unread(echo) def _submit_code(self, script): @@ -319,7 +319,7 @@ def _submit_code(self, script): def _execute_with_consumer(self, script, output_consumer): """Expected output after submitting the command and reading the confirmation is following: - + stdout EOT stderr @@ -349,7 +349,7 @@ def _execute_with_consumer(self, script, output_consumer): self._forward_output_until_active_prompt(output_consumer, "stdout") def _forward_output_until_active_prompt(self, output_consumer, stream_name="stdout"): - """Used for finding initial prompt or forwarding problematic output + """Used for finding initial prompt or forwarding problematic output in case of parse errors""" while True: terminator = self._forward_output_until_eot_or_active_propmt( @@ -362,24 +362,24 @@ def _forward_output_until_active_prompt(self, output_consumer, stream_name="stdo output_consumer(terminator, "stdout") def _forward_output_until_eot_or_active_propmt(self, output_consumer, stream_name="stdout"): - """Meant for incrementally forwarding stdout from user statements, - scripts and soft-reboots. Also used for forwarding side-effect output from + """Meant for incrementally forwarding stdout from user statements, + scripts and soft-reboots. Also used for forwarding side-effect output from expression evaluations and for capturing help("modules") output. In these cases it is expected to arrive to an EOT. - + Also used for initial prompt searching or for recovering from a protocol error. In this case it must work until active normal prompt or first raw prompt. - + The code may have been submitted in any of the REPL modes or automatically via (soft-)reset. - - NB! The processing may end in normal mode even if the command was started + + NB! The processing may end in normal mode even if the command was started in raw mode (eg. when user presses reset during processing in some devices)! - - The processing may also end in FIRST_RAW_REPL, when it was started in - normal REPL and Ctrl+A was issued during processing (ie. before Ctrl+C in + + The processing may also end in FIRST_RAW_REPL, when it was started in + normal REPL and Ctrl+A was issued during processing (ie. before Ctrl+C in this example): - + 6 7 8 @@ -393,27 +393,27 @@ def _forward_output_until_eot_or_active_propmt(self, output_consumer, stream_nam >>> raw REPL; CTRL-B to exit > - + (Preceding output does not contain EOT) Note that this Ctrl+A may have been issued even before Thonny connected to the device. Note that interrupt does not affect the structure of the output -- it is presented just like any other exception. - + The method returns pair of captured output (or b"" if not requested) and EOT, RAW_PROMPT or NORMAL_PROMPT, depending on which terminator ended the processing. - + The terminating EOT may be either the first EOT from normal raw-REPL output or the starting EOT from Thonny expression (or, in principle, even - the second raw-REPL EOT or terminating Thonny expression EOT) + the second raw-REPL EOT or terminating Thonny expression EOT) -- the caller will do the interpretation. - + Because ot the special role of EOT and NORMAL_PROMT, we assume user code will not output these. If it does, processing will break. TODO: Experiment with this! - - Output produced by background threads (eg. in WiPy ESP32) cause even more difficulties, + + Output produced by background threads (eg. in WiPy ESP32) cause even more difficulties, because it becomes impossible to say whether we are at prompt and output is from another thread or the main thread is still running. For now I'm ignoring these problems and assume all output comes from the main thread. @@ -997,6 +997,7 @@ def _is_connected(self): port = None if args.port == "None" else args.port try: + connection: MicroPythonConnection if port is None: # remain busy while True: