Satisfy the type checker

`PYRIGHT_PYTHON_FORCE_VERSION=1.1.327 pyright` now gives 0 errors

(before this commit it was 16 errors)
This commit is contained in:
Isaiah Odhner 2023-09-16 22:06:09 -04:00
parent a6b5cb31be
commit 0791b1c080
11 changed files with 42 additions and 17 deletions

View File

@ -349,10 +349,8 @@ cspell-cli lint .
# Type checking
# I use the "Python" and "Pylance" VS Code extensions, and the Pyright CLI:
pyright
# It should give 0 errors at this version of Pyright:
PYRIGHT_PYTHON_FORCE_VERSION=1.1.317 pyright
# It gives 508 errors with the next version (the current latest) for some reason:
PYRIGHT_PYTHON_FORCE_VERSION=1.1.318 pyright
# I'm targeting zero errors at this version of Pyright:
PYRIGHT_PYTHON_FORCE_VERSION=1.1.327 pyright
# I also tried mypy and fixed some errors it reported, but I'm not targeting zero errors with mypy.
mypy src --no-namespace-packages --check-untyped-defs

View File

@ -1114,6 +1114,7 @@ class Selection:
offset = target_region.offset - self.region.offset
if self.mask:
def sample(x: int, y: int) -> bool:
assert self.mask is not None
try:
return self.mask[y + offset.y][x + offset.x]
except IndexError:

View File

@ -12,7 +12,7 @@ replacements: list[tuple[object, str, object, object]] = []
def replace(obj: object, attr: str, ascii_only_value: object) -> None:
"""Replace an attribute with a value for --ascii-only mode."""
if isinstance(obj, dict):
replacements.append((obj, attr, ascii_only_value, obj[attr]))
replacements.append((obj, attr, ascii_only_value, obj[attr])) # type: ignore
else:
replacements.append((obj, attr, ascii_only_value, getattr(obj, attr)))

View File

@ -102,7 +102,7 @@ class EnhancedDirectoryTree(DirectoryTree):
# self.call_later(clear_flag) # too early!
self.call_after_refresh(clear_flag) # finally reliable
def _expand_matching_child(self, node: TreeNode[DirEntry], remaining_parts: tuple[str], callback: Callable[[], None]) -> None:
def _expand_matching_child(self, node: TreeNode[DirEntry], remaining_parts: tuple[str, ...], callback: Callable[[], None]) -> None:
"""Hooks into DirectoryTree's add method, and expands the child node matching the next path part, recursively.
Once the last part of the path is reached, it scrolls to and selects the node.

View File

@ -1468,7 +1468,9 @@ class Inspector(Container):
# TODO: Highlight the metrics of the hovered widget: padding, border, margin.
if "inspector_highlight" not in self.app.styles.layers:
self.app.styles.layers += ("inspector_highlight",)
# tuple[str] vs tuple[str, ...] in NameListProperty.__set__ vs NameListProperty.__get__
self.app.styles.layers += ("inspector_highlight",) # type: ignore
if dom_node not in self._highlight_boxes:
self._highlight_boxes[dom_node] = {}

View File

@ -46,8 +46,8 @@ def load_language(language_code: str):
except Exception as e:
print(f"Could not load language '{language_code}': {e}")
untranslated: set[str] = set()
if TRACK_UNTRANSLATED:
untranslated: set[str] = set()
try:
with open(untranslated_file, "r", encoding="utf-8") as f:
untranslated = set(f.read().splitlines())

View File

@ -9,7 +9,7 @@ import re
import shlex
import sys
from random import random
from typing import Any, Callable, Coroutine, Iterator, Optional
from typing import Any, Callable, Iterator, Optional
from uuid import uuid4
from PIL import Image, UnidentifiedImageError
@ -983,7 +983,7 @@ class PaintApp(App[None]):
# An error message will be shown when attempting to encode.
callback(False)
async def confirm_information_loss_async(self, format_id: str | None) -> Coroutine[None, None, bool]:
async def confirm_information_loss_async(self, format_id: str | None) -> bool:
"""Confirms discarding information when saving as a particular format. Awaitable variant, which uses the callback variant."""
future = asyncio.get_running_loop().create_future()
self.confirm_information_loss(format_id, lambda result: future.set_result(result))

View File

@ -60,14 +60,14 @@ def my_fs(fs: FakeFilesystem) -> Generator[FakeFilesystem, None, None]:
# Don't fail trying to load the default font "standard", we don't need it!
# `pkg_resources` doesn't seem to work with pyfakefs (or I don't know what directories I need to add)
from pyfiglet import FigletFont
from pyfiglet import FigletFont # type: ignore
def preloadFont(self: FigletFont, font: str):
dumb_font = FIGletFontWriter(commentLines=["Stupid font for testing"])
for ordinal in dumb_font.charOrder:
dumb_font.figChars[ordinal] = "fallback font for testing"
return dumb_font.createFigFileData()
orig_preloadFont = FigletFont.preloadFont
FigletFont.preloadFont = preloadFont
orig_preloadFont = FigletFont.preloadFont # type: ignore
FigletFont.preloadFont = preloadFont # type: ignore
# Add an extra file to show how a file looks in the EnhancedDirectoryTree widget.
fs.create_file("/pyfakefs_added_file.txt", contents="pyfakefs ate ur FS")

View File

@ -8,10 +8,35 @@ from typing import Any
from textual.errors import NoWidget
from textual.events import MouseDown, MouseMove, MouseUp
from textual.geometry import Offset
from textual.pilot import Pilot, _get_mouse_message_arguments
from textual.pilot import Pilot
from textual.widget import Widget
def _get_mouse_message_arguments(
target: Widget,
offset: Offset = Offset(),
button: int = 0,
shift: bool = False,
meta: bool = False,
control: bool = False,
) -> dict[str, Any]:
"""Get the arguments to pass into mouse messages for the click and hover methods."""
click_x, click_y = target.region.offset + offset
message_arguments = {
"x": click_x,
"y": click_y,
"delta_x": 0,
"delta_y": 0,
"button": button,
"shift": shift,
"meta": meta,
"ctrl": control,
"screen_x": click_x,
"screen_y": click_y,
}
return message_arguments
async def click_widget(pilot: Pilot[Any], widget: Widget, shift: bool = False, meta: bool = False, control: bool = False) -> None:
"""Click on widget, by reference."""
widget.add_class("pilot-click-target")

View File

@ -118,7 +118,7 @@ class PilotRecorder():
# - Every event seems to be received twice, once with _forwarded set and once without.
# I don't claim to understand the forwarding scheme, but ignoring either
# the forwarded or the un-forwarded events seems workable.
if not event._forwarded:
if not event._forwarded: # pyright: ignore[reportPrivateUsage]
recorder.handle_event(event)
await original_on_event(self, event)
self.app_on_event = on_event
@ -188,7 +188,7 @@ class PilotRecorder():
"""Replay the recorded steps, in the current app instance."""
if not self.steps:
return
await pilot._wait_for_screen(timeout=5.0)
await pilot._wait_for_screen(timeout=5.0) # pyright: ignore[reportPrivateUsage]
self.replaying = True
replay_code = self.get_replay_code()
# Fix import

View File

@ -6,7 +6,6 @@ Run with `pytest tests/test_snapshots.py`, or `pytest` to run all tests.
from pathlib import Path, PurePath
from typing import TYPE_CHECKING, Awaitable, Callable, Iterable, Protocol
import pytest
from pyfakefs.fake_filesystem import FakeFilesystem
from textual.geometry import Offset
from textual.pilot import Pilot