From 62580c855b48afff0550df3931ddb77a06184252 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 30 May 2025 10:01:15 +0530 Subject: [PATCH] Make mypy 1.16 happy --- benchmark.py | 2 +- kittens/query_terminal/main.py | 2 +- kittens/ssh/utils.py | 2 +- kittens/transfer/utils.py | 6 +++--- kittens/tui/images.py | 16 ++++++++-------- kitty/clipboard.py | 6 +++--- kitty/fast_data_types.pyi | 2 +- kitty/file_transmission.py | 19 ++++++++++--------- kitty/window.py | 2 +- pyproject.toml | 1 + 10 files changed, 30 insertions(+), 28 deletions(-) diff --git a/benchmark.py b/benchmark.py index 26116b83e..ba277190a 100755 --- a/benchmark.py +++ b/benchmark.py @@ -50,7 +50,7 @@ def run_parsing_benchmark(cell_width: int = 10, cell_height: int = 20, scrollbac screen = Screen(None, rows, columns, scrollback, cell_width, cell_height, 0, ToChild()) - def parse_bytes(data: bytes) -> None: + def parse_bytes(data: bytes|memoryview) -> None: data = memoryview(data) while data: dest = screen.test_create_write_buffer() diff --git a/kittens/query_terminal/main.py b/kittens/query_terminal/main.py index a9e6c39f5..7e550f5c1 100644 --- a/kittens/query_terminal/main.py +++ b/kittens/query_terminal/main.py @@ -30,7 +30,7 @@ class Query: def query_code(self) -> str: return f"\x1bP+q{self.encoded_query_name}\x1b\\" - def decode_response(self, res: bytes) -> str: + def decode_response(self, res: bytes | memoryview) -> str: return unhexlify(res).decode('utf-8') def more_needed(self, buffer: bytes) -> bool: diff --git a/kittens/ssh/utils.py b/kittens/ssh/utils.py index 20f78c9ef..3dc5b958b 100644 --- a/kittens/ssh/utils.py +++ b/kittens/ssh/utils.py @@ -115,7 +115,7 @@ def read_data_from_shared_memory(shm_name: str) -> Any: return json.loads(shm.read_data_with_size()) -def get_ssh_data(msgb: memoryview, request_id: str) -> Iterator[bytes]: +def get_ssh_data(msgb: memoryview, request_id: str) -> Iterator[bytes|memoryview]: from base64 import standard_b64decode yield b'\nKITTY_DATA_START\n' # to discard leading data try: diff --git a/kittens/transfer/utils.py b/kittens/transfer/utils.py index f3735d0c9..62b74b4aa 100644 --- a/kittens/transfer/utils.py +++ b/kittens/transfer/utils.py @@ -40,8 +40,8 @@ def set_paths(cwd: str = '', home: str = '') -> Generator[None, None, None]: class IdentityCompressor: - def compress(self, data: bytes) -> bytes: - return data + def compress(self, data: bytes | memoryview) -> bytes: + return bytes(data) def flush(self) -> bytes: return b'' @@ -53,7 +53,7 @@ class ZlibCompressor: import zlib self.c = zlib.compressobj() - def compress(self, data: bytes) -> bytes: + def compress(self, data: bytes | memoryview) -> bytes: return self.c.compress(data) def flush(self) -> bytes: diff --git a/kittens/tui/images.py b/kittens/tui/images.py index 55f677727..007e63d3e 100644 --- a/kittens/tui/images.py +++ b/kittens/tui/images.py @@ -14,7 +14,7 @@ from typing import Any, ClassVar, DefaultDict, Deque, Generic, Optional, TypeVar from kitty.conf.utils import positive_float, positive_int from kitty.fast_data_types import create_canvas -from kitty.typing_compat import GRT_C, CompletedProcess, GRT_a, GRT_d, GRT_f, GRT_m, GRT_o, GRT_t, HandlerType +from kitty.typing_compat import CompletedProcess, GRT_f, GRT_o, HandlerType from kitty.utils import ScreenSize, fit_image, which from .operations import cursor @@ -344,10 +344,10 @@ class Alias(Generic[T]): class GraphicsCommand: - a = action = Alias(cast(GRT_a, 't')) + a = action = Alias('t') q = quiet = Alias(0) f = format = Alias(32) - t = transmission_type = Alias(cast(GRT_t, 'd')) + t = transmission_type = Alias('d') s = data_width = animation_state = Alias(0) v = data_height = loop_count = Alias(0) S = data_size = Alias(0) @@ -356,7 +356,7 @@ class GraphicsCommand: I = image_number = Alias(0) # noqa p = placement_id = Alias(0) o = compression = Alias(cast(Optional[GRT_o], None)) - m = more = Alias(cast(GRT_m, 0)) + m = more = Alias(0) x = left_edge = Alias(0) y = top_edge = Alias(0) w = width = Alias(0) @@ -366,8 +366,8 @@ class GraphicsCommand: c = columns = other_frame_number = dest_frame = Alias(0) r = rows = frame_number = source_frame = Alias(0) z = z_index = gap = Alias(0) - C = cursor_movement = compose_mode = Alias(cast(GRT_C, 0)) - d = delete_action = Alias(cast(GRT_d, 'a')) + C = cursor_movement = compose_mode = Alias(0) + d = delete_action = Alias('a') def __init__(self) -> None: self._actual_values: dict[str, Any] = {} @@ -380,12 +380,12 @@ class GraphicsCommand: ans._actual_values = self._actual_values.copy() return ans - def serialize(self, payload: bytes | str = b'') -> bytes: + def serialize(self, payload: bytes | memoryview | str = b'') -> bytes: items = [] for k, val in self._actual_values.items(): items.append(f'{k}={val}') - ans: list[bytes] = [] + ans: list[bytes|memoryview] = [] w = ans.append w(b'\033_G') w(','.join(items).encode('ascii')) diff --git a/kitty/clipboard.py b/kitty/clipboard.py index d0b54b341..39290f765 100644 --- a/kitty/clipboard.py +++ b/kitty/clipboard.py @@ -212,7 +212,7 @@ class ReadRequest(NamedTuple): id: str = '' protocol_type: ProtocolType = ProtocolType.osc_52 - def encode_response(self, status: str = 'DATA', mime: str = '', payload: bytes = b'') -> bytes: + def encode_response(self, status: str = 'DATA', mime: str = '', payload: bytes | memoryview = b'') -> bytes: ans = f'{self.protocol_type.value};type=read:status={status}' if status == 'OK' and self.is_primary_selection: ans += ':loc=primary' @@ -276,7 +276,7 @@ class WriteRequest: x = {mime: self.tempfile.create_chunker(pos.start, pos.size) for mime, pos in self.mime_map.items()} cp.set_mime(x) - def add_base64_data(self, data: str | bytes, mime: str = 'text/plain') -> None: + def add_base64_data(self, data: str | bytes | memoryview, mime: str = 'text/plain') -> None: if isinstance(data, str): data = data.encode('ascii') if self.currently_writing_mime and self.currently_writing_mime != mime: @@ -295,7 +295,7 @@ class WriteRequest: self.mime_map[self.currently_writing_mime] = MimePos(start, self.tempfile.tell() - start) self.currently_writing_mime = '' - def write_base64_data(self, b: bytes) -> None: + def write_base64_data(self, b: bytes | memoryview) -> None: if not self.max_size_exceeded: try: decoded = self.decoder.decode(b) diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index a165d21ef..7fc45699b 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1418,7 +1418,7 @@ class ChildMonitor: def resize_pty(self, window_id: int, rows: int, cols: int, x_pixels: int, y_pixels: int) -> None: pass - def needs_write(self, child_id: int, data: bytes) -> bool: + def needs_write(self, child_id: int, data: bytes | memoryview) -> bool: pass def set_iutf8_winid(self, win_id: int, on: bool) -> bool: diff --git a/kitty/file_transmission.py b/kitty/file_transmission.py index 7e3c42ff8..2131063d8 100644 --- a/kitty/file_transmission.py +++ b/kitty/file_transmission.py @@ -244,8 +244,8 @@ def name_to_serialized_map() -> dict[str, str]: @run_once -def serialized_to_field_map() -> dict[bytes, 'Field[Any]']: - ans: dict[bytes, 'Field[Any]'] = {} +def serialized_to_field_map() -> dict[bytes | memoryview, 'Field[Any]']: + ans: dict[bytes | memoryview, 'Field[Any]'] = {} for k in fields(FileTransmissionCommand): ans[k.metadata.get('sname', k.name).encode('ascii')] = k return ans @@ -268,7 +268,7 @@ class FileTransmissionCommand: name: str = field(default='', metadata={'base64': True, 'sname': 'n'}) status: str = field(default='', metadata={'base64': True, 'sname': 'st'}) parent: str = field(default='', metadata={'sname': 'pr'}) - data: bytes = field(default=b'', repr=False, metadata={'sname': 'd'}) + data: bytes | memoryview = field(default=b'', repr=False, metadata={'sname': 'd'}) def __repr__(self) -> str: ans = [] @@ -313,7 +313,7 @@ class FileTransmissionCommand: yield '=' if inspect.isclass(k.type) and issubclass(k.type, Enum): yield val.name - elif k.type is bytes: + elif k.type == bytes | memoryview: yield base64_encode(val) elif k.type is str: if k.metadata.get('base64'): @@ -340,7 +340,7 @@ class FileTransmissionCommand: return if inspect.isclass(field.type) and issubclass(field.type, Enum): setattr(ans, field.name, field.type[str(val, "utf-8")]) - elif field.type is bytes: + elif field.type == bytes | memoryview: setattr(ans, field.name, base64_decode(val)) elif field.type is int: setattr(ans, field.name, int(val)) @@ -360,8 +360,8 @@ class FileTransmissionCommand: class IdentityDecompressor: - def __call__(self, data: bytes, is_last: bool = False) -> bytes: - return data + def __call__(self, data: bytes | memoryview, is_last: bool = False) -> bytes: + return bytes(data) class ZlibDecompressor: @@ -370,7 +370,7 @@ class ZlibDecompressor: import zlib self.d = zlib.decompressobj(wbits=0) - def __call__(self, data: bytes, is_last: bool = False) -> bytes: + def __call__(self, data: bytes | memoryview, is_last: bool = False) -> bytes: ans = self.d.decompress(data) if is_last: ans += self.d.flush() @@ -510,7 +510,7 @@ class DestFile: self.existing_stat = None self.needs_unlink = False - def write_data(self, all_files: dict[str, 'DestFile'], data: bytes, is_last: bool) -> None: + def write_data(self, all_files: dict[str, 'DestFile'], data: bytes | memoryview, is_last: bool) -> None: if self.ftype is FileType.directory: raise TransmissionError(code=ErrorCode.EISDIR, file_id=self.file_id, msg='Cannot write data to a directory entry') if self.closed: @@ -687,6 +687,7 @@ class SourceFile: self.differ = None def next_chunk(self, sz: int = 1024 * 1024) -> tuple[bytes, int]: + data: bytes | memoryview = b'' if self.target: self.transmitted = True data = self.target diff --git a/kitty/window.py b/kitty/window.py index 16540e2c5..e3a63ba0f 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -1032,7 +1032,7 @@ class Window: text = ''.join(strings) get_boss().display_scrollback(self, text, title='Dump of lines', report_cursor=False) - def write_to_child(self, data: str | bytes) -> None: + def write_to_child(self, data: str | bytes | memoryview) -> None: if data: if isinstance(data, str): data = data.encode('utf-8') diff --git a/pyproject.toml b/pyproject.toml index a8b4b257a..0e91974d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ disallow_untyped_decorators = true disallow_untyped_calls = true disallow_incomplete_defs = true strict = true +strict_bytes = true no_implicit_reexport = true [tool.pylsp-mypy]