From 99d9eae8596ab90063f5366b060ce935fcd97090 Mon Sep 17 00:00:00 2001 From: Jos Verlinde Date: Fri, 19 Jan 2024 15:46:33 +0100 Subject: [PATCH] test: update qa test Signed-off-by: Jos Verlinde --- .../micropython-stdlib-stubs/pyproject.toml | 2 +- .../reduce_stdlib.ipynb | 155 ++++++++++++++++++ .../stdlib/sys/__init__.pyi | 54 +++--- .../check_esp32/check_onewire.py | 6 +- .../check_esp32/check_webrepl.py | 19 +-- .../check_examples/ble_uart_repl.py | 2 +- .../check_aioespnow.py | 2 +- .../feat_micropython/check_functions.py | 2 +- .../check_machine/check_reset.py | 2 +- .../check_examples/http_client.py | 4 +- .../check_examples/http_client_ssl.py | 5 +- .../check_examples/http_server_ssl.py | 8 +- .../feat_networking/check_ssl.py | 4 +- tests/quality_tests/feat_stdlib/check_io.py | 6 +- .../check_sys/check_implementation.py | 22 +-- .../feat_uasyncio/check_demo/aiorepl.py | 18 +- .../feat_uasyncio/check_demo/auart_hd.py | 8 +- tests/quality_tests/typecheck.py | 7 +- tests/quality_tests/typecheck_mypy.py | 7 +- 19 files changed, 242 insertions(+), 91 deletions(-) create mode 100644 publish/micropython-stdlib-stubs/reduce_stdlib.ipynb rename tests/quality_tests/{check_esp32 => feat_espnow}/check_aioespnow.py (96%) diff --git a/publish/micropython-stdlib-stubs/pyproject.toml b/publish/micropython-stdlib-stubs/pyproject.toml index 116a08a2b..d783b2e51 100644 --- a/publish/micropython-stdlib-stubs/pyproject.toml +++ b/publish/micropython-stdlib-stubs/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "micropython-stdlib-stubs" -version = "1.1.1a3" +version = "1.1.2a0" description = "Micropython stdlib is a reduced and augmented copy of typeshed's stdlib for use by MicroPython stub packages" authors = ["josverl "] license = "MIT" diff --git a/publish/micropython-stdlib-stubs/reduce_stdlib.ipynb b/publish/micropython-stdlib-stubs/reduce_stdlib.ipynb new file mode 100644 index 000000000..4e3929018 --- /dev/null +++ b/publish/micropython-stdlib-stubs/reduce_stdlib.ipynb @@ -0,0 +1,155 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Remove top level module variables from the stdlib sys module.\n", + "This is based of the types detected on the sys module in a fimrware stub for esp32 micropython\n", + "\n", + "the approach is very simple, we just comment the top level variables from the sys module\n", + "this assumes that all defenitions are on a single line, which may or may not be true\n", + "\n", + "A more mature approach would use cstlib to parse the module and remove the variables\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from typing import Set\n", + "import re\n", + "from pathlib import Path\n", + "\n", + "RE_VAR_TYPE = r\"[a-zA-Z0-9_]*\\s*: \"\n", + "RE_VAR_ASSIGN = r\"[a-zA-Z0-9_]*\\s*= \"\n", + "\n", + "\n", + "def read_stubfile_toplevel(stubfile: Path) -> Set[str]:\n", + " # read the stubfile into a list of lines\n", + " with open(stubfile, \"r\") as f:\n", + " lines = f.readlines()\n", + " # remove the newlines\n", + " lines = [line.rstrip(\"\\n\") for line in lines]\n", + "\n", + " # # find all lines that start with the regex \"def [a-zA-Z0-9_]*\\(\"\n", + " # deflines = []\n", + " # for line in lines:\n", + " # if re.match(r\"def [a-zA-Z0-9_]*\\s*\\(\", line):\n", + " # deflines.append(line)\n", + "\n", + " # # find all lines that start with the regex \"class [a-zA-Z0-9_]*\\(\"\n", + " # classlines = []\n", + " # for line in lines:\n", + " # if re.match(r\"class [a-zA-Z0-9_]*\\s*\\(\", line):\n", + " # classlines.append(line)\n", + "\n", + " # find all lines that start with the regex \"[a-zA-Z0-9_]*: \"\n", + " typelines = []\n", + " for line in lines:\n", + " if re.match(RE_VAR_TYPE, line):\n", + " typelines.append(line)\n", + "\n", + " # find all lines that start with the regex \"[a-zA-Z0-9_]* = \"\n", + " varlines = []\n", + " for line in lines:\n", + " if re.match(RE_VAR_ASSIGN, line):\n", + " varlines.append(line)\n", + "\n", + " toplevel_vars = set()\n", + " toplevel_vars = toplevel_vars.union([v.split(\":\")[0].strip() for v in typelines])\n", + " toplevel_vars = toplevel_vars.union([v.split(\"=\")[0].strip() for v in varlines])\n", + " return toplevel_vars" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def patch_stdlib_toplevel(stubfile: Path, toplevel_vars: Set[str]) -> int:\n", + " # read the stubfile into a list of lines\n", + " with open(stubfile, \"r\") as f:\n", + " lines = f.readlines()\n", + " # remove the newlines\n", + " updated = 0\n", + " for i, line in enumerate(lines):\n", + " # comment out the lines that are not toplevel vars\n", + " if re.match(RE_VAR_TYPE, line):\n", + " varname = line.split(\":\")[0].strip()\n", + " if not varname in toplevel_vars and varname[0] != \"_\":\n", + " lines[i] = \"# \" + line\n", + " updated += 1\n", + " elif re.match(RE_VAR_ASSIGN, line):\n", + " varname = line.split(\"=\")[0].strip()\n", + " if not varname in toplevel_vars and varname[0] != \"_\":\n", + " lines[i] = \"# \" + line\n", + " updated += 1\n", + "\n", + " # write the stubfile back\n", + " with open(stubfile, \"w\") as f:\n", + " f.writelines(lines)\n", + "\n", + " return updated" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'stderr', 'argv', 'implementation', 'ps2', 'stdin', 'stdout', 'platform', 'maxsize', 'byteorder', 'ps1', 'modules', 'version', 'version_info', 'path'}\n" + ] + }, + { + "data": { + "text/plain": [ + "27" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stubfile = \"C:\\\\develop\\\\MyPython\\\\micropython-stubs\\\\publish\\\\micropython-latest-esp32-stubs\\\\sys.pyi\"\n", + "stdlib_stub = Path(\n", + " \"C:\\\\develop\\\\MyPython\\\\micropython-stubs\\\\publish\\\\micropython-stdlib-stubs\\\\stdlib\\\\sys\\\\__init__.pyi\"\n", + ")\n", + "toplevel_vars = read_stubfile_toplevel(stubfile)\n", + "print(toplevel_vars)\n", + "\n", + "patch_stdlib_toplevel(stdlib_stub, toplevel_vars)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/publish/micropython-stdlib-stubs/stdlib/sys/__init__.pyi b/publish/micropython-stdlib-stubs/stdlib/sys/__init__.pyi index a362cb0e8..3286107b8 100644 --- a/publish/micropython-stdlib-stubs/stdlib/sys/__init__.pyi +++ b/publish/micropython-stdlib-stubs/stdlib/sys/__init__.pyi @@ -30,36 +30,36 @@ class _MetaPathFinder(Protocol): if sys.platform != "win32": abiflags: str argv: list[str] -base_exec_prefix: str -base_prefix: str +# base_exec_prefix: str +# base_prefix: str byteorder: Literal["little", "big"] -builtin_module_names: Sequence[str] # actually a tuple of strings -copyright: str +# builtin_module_names: Sequence[str] # actually a tuple of strings +# copyright: str if sys.platform == "win32": dllhandle: int -dont_write_bytecode: bool -displayhook: Callable[[object], Any] -excepthook: Callable[[type[BaseException], BaseException, TracebackType | None], Any] -exec_prefix: str -executable: str -float_repr_style: Literal["short", "legacy"] -hexversion: int -last_type: type[BaseException] | None -last_value: BaseException | None -last_traceback: TracebackType | None +# dont_write_bytecode: bool +# displayhook: Callable[[object], Any] +# excepthook: Callable[[type[BaseException], BaseException, TracebackType | None], Any] +# exec_prefix: str +# executable: str +# float_repr_style: Literal["short", "legacy"] +# hexversion: int +# last_type: type[BaseException] | None +# last_value: BaseException | None +# last_traceback: TracebackType | None maxsize: int -maxunicode: int -meta_path: list[_MetaPathFinder] +# maxunicode: int +# meta_path: list[_MetaPathFinder] modules: dict[str, ModuleType] if sys.version_info >= (3, 10): orig_argv: list[str] path: list[str] -path_hooks: list[Callable[[str], PathEntryFinder]] -path_importer_cache: dict[str, PathEntryFinder | None] +# path_hooks: list[Callable[[str], PathEntryFinder]] +# path_importer_cache: dict[str, PathEntryFinder | None] platform: str if sys.version_info >= (3, 9): platlibdir: str -prefix: str +# prefix: str if sys.version_info >= (3, 8): pycache_prefix: str | None ps1: object @@ -84,10 +84,10 @@ if sys.version_info >= (3, 10): __stdin__: Final[TextIOWrapper] # Contains the original value of stdin __stdout__: Final[TextIOWrapper] # Contains the original value of stdout __stderr__: Final[TextIOWrapper] # Contains the original value of stderr -tracebacklimit: int +# tracebacklimit: int version: str -api_version: int -warnoptions: Any +# api_version: int +# warnoptions: Any # Each entry is a tuple of the form (action, message, category, module, # lineno) if sys.platform == "win32": @@ -98,7 +98,7 @@ _xoptions: dict[Any, Any] # This can't be represented in the type system, so we just use `structseq[Any]` _UninstantiableStructseq: TypeAlias = structseq[Any] -flags: _flags +# flags: _flags if sys.version_info >= (3, 10): _FlagTuple: TypeAlias = tuple[int, int, int, int, int, int, int, int, int, int, int, int, int, bool, int, int] @@ -144,7 +144,7 @@ class _flags(_UninstantiableStructseq, _FlagTuple): @property def safe_path(self) -> bool: ... -float_info: _float_info +# float_info: _float_info @final class _float_info(structseq[float], tuple[float, int, int, float, int, int, int, int, float, int, int]): @@ -171,7 +171,7 @@ class _float_info(structseq[float], tuple[float, int, int, float, int, int, int, @property def rounds(self) -> int: ... # FLT_ROUNDS -hash_info: _hash_info +# hash_info: _hash_info @final class _hash_info(structseq[Any | int], tuple[int, int, int, int, int, str, int, int, int]): @@ -206,7 +206,7 @@ class _implementation: # > These non-standard attributes must start with an underscore, and are not described here. def __getattr__(self, name: str) -> Any: ... -int_info: _int_info +# int_info: _int_info @final class _int_info(structseq[int], tuple[int, int, int, int]): @@ -231,7 +231,7 @@ class _thread_info(_UninstantiableStructseq, tuple[_ThreadInfoName, _ThreadInfoL @property def version(self) -> str | None: ... -thread_info: _thread_info +# thread_info: _thread_info _ReleaseLevel: TypeAlias = Literal["alpha", "beta", "candidate", "final"] @final diff --git a/tests/quality_tests/check_esp32/check_onewire.py b/tests/quality_tests/check_esp32/check_onewire.py index 950933268..3bc01ec7d 100644 --- a/tests/quality_tests/check_esp32/check_onewire.py +++ b/tests/quality_tests/check_esp32/check_onewire.py @@ -1,7 +1,7 @@ -from typing_extensions import assert_type +import onewire # OneWire driver from machine import Pin -import onewire +from typing_extensions import assert_type ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12 ow.scan() # return a list of devices on the bus @@ -12,7 +12,7 @@ ow.write(b"123") # write bytes on the bus ow.select_rom(b"12345678") # select a specific device by its ROM code -assert_type(ow, onewire.OneWire) +# assert_type(ow, onewire.OneWire) # there was no onewire documatation before 1.19.1 # assert_type(ow.write(b"123"), None) diff --git a/tests/quality_tests/check_esp32/check_webrepl.py b/tests/quality_tests/check_esp32/check_webrepl.py index 5cf2b06ad..b18d8300a 100644 --- a/tests/quality_tests/check_esp32/check_webrepl.py +++ b/tests/quality_tests/check_esp32/check_webrepl.py @@ -1,16 +1,15 @@ -#type: ignore # currently the webrepl module is excluded from creatstubs -# https://github.com/Josverl/micropython-stubber/blob/91394e70a168cfea954f0137faf38d769ae372e8/src/stubber/update_module_list.py#L91 +# # https://github.com/Josverl/micropython-stubber/blob/91394e70a168cfea954f0137faf38d769ae372e8/src/stubber/update_module_list.py#L91 -import webrepl -# https://docs.micropython.org/en/latest/esp32/quickref.html#webrepl-web-browser-interactive-prompt -# -import webrepl_setup +# import webrepl +# # https://docs.micropython.org/en/latest/esp32/quickref.html#webrepl-web-browser-interactive-prompt +# # +# import webrepl_setup -# and following on-screen instructions. After reboot, it will be available for connection. If you disabled automatic start-up on boot, you may run configured daemon on demand using: +# # and following on-screen instructions. After reboot, it will be available for connection. If you disabled automatic start-up on boot, you may run configured daemon on demand using: -webrepl.start() +# webrepl.start() -# or, start with a specific password -webrepl.start(password="mypass") +# # or, start with a specific password +# webrepl.start(password="mypass") diff --git a/tests/quality_tests/feat_bluetooth/check_examples/ble_uart_repl.py b/tests/quality_tests/feat_bluetooth/check_examples/ble_uart_repl.py index ba70cb24c..767ebe1f3 100644 --- a/tests/quality_tests/feat_bluetooth/check_examples/ble_uart_repl.py +++ b/tests/quality_tests/feat_bluetooth/check_examples/ble_uart_repl.py @@ -43,7 +43,7 @@ def __init__(self, uart): def _on_rx(self): # Needed for ESP32. if hasattr(os, "dupterm_notify"): - os.dupterm_notify(None) # type: ignore + os.dupterm_notify(None) # stubs-ignore: linter=="pyright" def read(self, sz=None): return self._uart.read(sz) diff --git a/tests/quality_tests/check_esp32/check_aioespnow.py b/tests/quality_tests/feat_espnow/check_aioespnow.py similarity index 96% rename from tests/quality_tests/check_esp32/check_aioespnow.py rename to tests/quality_tests/feat_espnow/check_aioespnow.py index 8f96000d7..583326fb8 100644 --- a/tests/quality_tests/check_esp32/check_aioespnow.py +++ b/tests/quality_tests/feat_espnow/check_aioespnow.py @@ -5,7 +5,7 @@ import asyncio -import aioespnow # type: ignore +import aioespnow # stubs-ignore: version<"1.22.0" import network # A WLAN interface must be active to send()/recv() diff --git a/tests/quality_tests/feat_micropython/check_functions.py b/tests/quality_tests/feat_micropython/check_functions.py index e59a2ec84..ed98d7791 100644 --- a/tests/quality_tests/feat_micropython/check_functions.py +++ b/tests/quality_tests/feat_micropython/check_functions.py @@ -1,4 +1,4 @@ -from socket import * # type: ignore +from socket import * # socket.socket # Create STREAM TCP socket diff --git a/tests/quality_tests/feat_micropython/check_machine/check_reset.py b/tests/quality_tests/feat_micropython/check_machine/check_reset.py index 76cbc9878..d20585229 100644 --- a/tests/quality_tests/feat_micropython/check_machine/check_reset.py +++ b/tests/quality_tests/feat_micropython/check_machine/check_reset.py @@ -4,6 +4,6 @@ # put the device to deep sleep for 10 seconds -machine.reset() # type: ignore +machine.reset() # detect that reset never returns assert False, "reset never returns" diff --git a/tests/quality_tests/feat_networking/check_examples/http_client.py b/tests/quality_tests/feat_networking/check_examples/http_client.py index 661c286b7..63799527d 100644 --- a/tests/quality_tests/feat_networking/check_examples/http_client.py +++ b/tests/quality_tests/feat_networking/check_examples/http_client.py @@ -15,8 +15,8 @@ def main(use_stream=False): # MicroPython socket objects support stream (aka file) interface # directly, but the line below is needed for CPython. s = s.makefile("rwb", 0) - s.write(b"GET / HTTP/1.0\r\n\r\n") - print(s.read()) + s.write(b"GET / HTTP/1.0\r\n\r\n") # stubs-ignore: linter == "mypy" + print(s.read()) # stubs-ignore: linter == "mypy" else: s.send(b"GET / HTTP/1.0\r\n\r\n") print(s.recv(4096)) diff --git a/tests/quality_tests/feat_networking/check_examples/http_client_ssl.py b/tests/quality_tests/feat_networking/check_examples/http_client_ssl.py index 29d4035dc..04f8154a0 100644 --- a/tests/quality_tests/feat_networking/check_examples/http_client_ssl.py +++ b/tests/quality_tests/feat_networking/check_examples/http_client_ssl.py @@ -23,8 +23,9 @@ def main(use_stream=True): else: # MicroPython SSLSocket objects implement only stream interface, not # socket interface - s.send(b"GET / HTTP/1.0\r\n\r\n") # type: ignore # not supported by design of MicroPython - print(s.recv(4096)) # type: ignore # not supported by design of MicroPython + + s.send(b"GET / HTTP/1.0\r\n\r\n") # stubs-ignore + print(s.recv(4096)) # stubs-ignore s.close() diff --git a/tests/quality_tests/feat_networking/check_examples/http_server_ssl.py b/tests/quality_tests/feat_networking/check_examples/http_server_ssl.py index 3427e9a1e..af1284487 100644 --- a/tests/quality_tests/feat_networking/check_examples/http_server_ssl.py +++ b/tests/quality_tests/feat_networking/check_examples/http_server_ssl.py @@ -74,10 +74,10 @@ def main(use_stream=True): # next request they issue will likely be more well-behaving and # will succeed. try: - req = client_s.readline() + req = client_s.readline() # type: ignore # stubs: ignore print(req) while True: - h = client_s.readline() + h = client_s.readline() # type: ignore # stubs: ignore if h == b"" or h == b"\r\n": break print(h) @@ -86,8 +86,8 @@ def main(use_stream=True): except Exception as e: print("Exception serving request:", e) else: - print(client_s.recv(4096)) # type: ignore # not supported by design of MicroPython - client_s.send(CONTENT % counter) # type: ignore # not supported by design of MicroPython + print(client_s.recv(4096)) # stubs-ignore + client_s.send(CONTENT % counter) # stubs-ignore client_s.close() counter += 1 print() diff --git a/tests/quality_tests/feat_networking/check_ssl.py b/tests/quality_tests/feat_networking/check_ssl.py index 68f86baa6..6f8b4a1f1 100644 --- a/tests/quality_tests/feat_networking/check_ssl.py +++ b/tests/quality_tests/feat_networking/check_ssl.py @@ -27,8 +27,8 @@ def create_ssl_context(cert, key, **kwargs): natively, this function will be deprecated. """ if hasattr(ssl, 'SSLContext'): - ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER, **kwargs) # type: ignore - ctx.load_cert_chain(cert, key) # type: ignore + ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER, **kwargs) + ctx.load_cert_chain(cert, key) # stubs: ignore return ctx if isinstance(cert, str): diff --git a/tests/quality_tests/feat_stdlib/check_io.py b/tests/quality_tests/feat_stdlib/check_io.py index c5992b11f..e403b3c8d 100644 --- a/tests/quality_tests/feat_stdlib/check_io.py +++ b/tests/quality_tests/feat_stdlib/check_io.py @@ -8,11 +8,11 @@ stream = open("file") -buf = io.BufferedWriter(stream, 8) # type: ignore # TODO stdlib.io "TextIOWrapper" is incompatible with "RawIOBase" +buf = io.BufferedWriter(stream, 8) print(buf.write(bytearray(16))) stream.close() - -with open("foo.bar", "wb") as f: +# TODO: fix ect of type "BufferedWriter" cannot be used with "with" because it does not implement __enter__ +with open("foo.bar", "wb") as f: # type: ignore f.write(b"deadbeef") diff --git a/tests/quality_tests/feat_stdlib/check_sys/check_implementation.py b/tests/quality_tests/feat_stdlib/check_sys/check_implementation.py index f9820932b..372e6f790 100644 --- a/tests/quality_tests/feat_stdlib/check_sys/check_implementation.py +++ b/tests/quality_tests/feat_stdlib/check_sys/check_implementation.py @@ -12,7 +12,8 @@ def is_tuple(imp: Tuple): # indirect check if sys implementation has a base class of a tuple # there must be a cleaner way to do this but I can't find it -is_tuple(impl) # type: ignore # TODO +is_tuple(impl) +assert_type(impl, Tuple) assert_type(impl, NamedTuple) # type: ignore # TODO sys.implementation is not a tuple @@ -30,22 +31,3 @@ def is_tuple(imp: Tuple): # if "mpy" in dir(sys.implementation) # else "" # ) - -# TODO - improve sys.implementation in stubs -_ = """ -file sys.pyi - -implementation: _mpy_implementation - -# from stdlib.sys import _version_info -class _mpy_implementation: - name: str - version: Tuple[int, int, int] - _machine: str - _mpy: int - # Define __getattr__, as the documentation states: - # > sys.implementation may contain additional attributes specific to the Python implementation. - # > These non-standard attributes must start with an underscore, and are not described here. - def __getattr__(self, name: str) -> Any: ... - -""" diff --git a/tests/quality_tests/feat_uasyncio/check_demo/aiorepl.py b/tests/quality_tests/feat_uasyncio/check_demo/aiorepl.py index 2fdba6af3..ba2355636 100644 --- a/tests/quality_tests/feat_uasyncio/check_demo/aiorepl.py +++ b/tests/quality_tests/feat_uasyncio/check_demo/aiorepl.py @@ -64,9 +64,10 @@ async def kbd_intr_task(exec_task, s): except asyncio.CancelledError: # stubs-ignore: port=="esp32" pass finally: - intr_task.cancel() + intr_task.cancel() # stubs: ignore try: - await intr_task + await intr_task # stubs: ignore + # "Task" is not awaitable  "Task" is incompatible with protocol "Awaitable[_T_co@Awaitable]"  "__await__" is not present except asyncio.CancelledError: # stubs-ignore: port=="esp32" pass else: @@ -95,7 +96,8 @@ async def task(g=None, prompt="--> "): g = __import__("__main__").__dict__ try: micropython.kbd_intr(-1) - s = asyncio.StreamReader(sys.stdin) # type: ignore # TODO: fix type stubs asyncio.StreamReader + s = asyncio.StreamReader(sys.stdin) # stubs-ignore + # TODO: fix type stubs asyncio.StreamReader # clear = True hist = [None] * _HISTORY_LIMIT hist_i = 0 # Index of most recent entry. @@ -123,7 +125,7 @@ async def task(g=None, prompt="--> "): sys.stdout.write("\n") if cmd: # Push current command. - hist[hist_i] = cmd # type: ignore + hist[hist_i] = cmd # stubs: ignore # Increase history length if possible, and rotate ring forward. hist_n = min(_HISTORY_LIMIT - 1, hist_n + 1) hist_i = (hist_i + 1) % _HISTORY_LIMIT @@ -164,9 +166,13 @@ async def task(g=None, prompt="--> "): # Stash the current command. hist[(hist_i - hist_b) % _HISTORY_LIMIT] = cmd # type: ignore # Clear current command. - b = "\x08" * len(cmd) # type: ignore + assert cmd # Added to avoid type check errors below + b = "\x08" * len(cmd) # stubs-ignore + # OK on v 1.20.0 + # "None" is incompatible with protocol "Sized" sys.stdout.write(b) - sys.stdout.write(" " * len(cmd)) # type: ignore + sys.stdout.write(" " * len(cmd)) + # "None" is incompatible with protocol "Sized" sys.stdout.write(b) # Go backwards or forwards in the history. if key == "[A": diff --git a/tests/quality_tests/feat_uasyncio/check_demo/auart_hd.py b/tests/quality_tests/feat_uasyncio/check_demo/auart_hd.py index 36c9093f9..58ef590e2 100644 --- a/tests/quality_tests/feat_uasyncio/check_demo/auart_hd.py +++ b/tests/quality_tests/feat_uasyncio/check_demo/auart_hd.py @@ -22,8 +22,8 @@ class Device(): def __init__(self, uart_no = 4): self.uart = UART(uart_no, 9600) - self.swriter = asyncio.StreamWriter(self.uart, {}) # type: ignore # TODO: fix type stubs asyncio.StreamWriter - self.sreader = asyncio.StreamReader(self.uart) # type: ignore # TODO: fix type stubs asyncio.StreamReader + self.swriter = asyncio.StreamWriter(self.uart, {}) # stubs-ignore: True + self.sreader = asyncio.StreamReader(self.uart) # stubs-ignore: True asyncio.create_task(self._run()) async def _run(self): @@ -45,8 +45,8 @@ class Master(): def __init__(self, uart_no = 2, timeout=4000): self.uart = UART(uart_no, 9600) self.timeout = timeout - self.swriter = asyncio.StreamWriter(self.uart, {}) # type: ignore - self.sreader = asyncio.StreamReader(self.uart) # type: ignore + self.swriter = asyncio.StreamWriter(self.uart, {}) # stubs: ignore + self.sreader = asyncio.StreamReader(self.uart) # stubs: ignore self.delay = Delay_ms() self.response = [] asyncio.create_task(self._recv()) diff --git a/tests/quality_tests/typecheck.py b/tests/quality_tests/typecheck.py index 9371a5f7b..c9bf1fff2 100644 --- a/tests/quality_tests/typecheck.py +++ b/tests/quality_tests/typecheck.py @@ -12,7 +12,6 @@ import pytest from mypy_gitlab_code_quality import generate_report as gitlab_report from packaging.version import Version - from typecheck_mypy import check_with_mypy log = logging.getLogger() @@ -56,6 +55,12 @@ def stub_ignore(line, version, port, board, linter, is_source=True) -> bool: """ if is_source: comment = line.rsplit("#")[-1].strip() + if comment == "stubs: ignore": + # new style stubs: ignore + return True + if comment == "stubs-ignore": + # old style + return True if not (comment.startswith("stubs-ignore") and ":" in comment): return False id, condition = comment.split(":") diff --git a/tests/quality_tests/typecheck_mypy.py b/tests/quality_tests/typecheck_mypy.py index c8361c689..4888d8c6a 100644 --- a/tests/quality_tests/typecheck_mypy.py +++ b/tests/quality_tests/typecheck_mypy.py @@ -76,7 +76,8 @@ def check_with_mypy(snip_path): """ raw_results = run_mypy(snip_path) results = raw_results.split("\n") - results = gitlab_to_pyright(gitlab_report(map(str.rstrip, results))) + gl_report = gitlab_report(map(str.rstrip, results)) + results = gitlab_to_pyright(gl_report) return results @@ -166,7 +167,9 @@ def gitlab_to_pyright(report): i["message"] = issue["description"] i["rule"] = issue["check_name"] # pyright uses 0-based lines - gitlab uses 1-based lines - i["range"]["start"]["line"] = int(issue["location"]["lines"]["begin"]) -1 + line_no = int(issue["location"]["lines"]["begin"]) -1 + i["range"]["start"]["line"] = line_no + i["range"]["end"]["line"] = line_no pyright_report["generalDiagnostics"].append(i) for sev in ["error", "warning", "information"]: