fix(ci): address remaining pyright errors (#1368)

* fix(ci): address remaining pyright errors

* fix: implement review feedback
This commit is contained in:
Travis Abendshien
2026-05-13 15:28:41 -04:00
committed by GitHub
parent a7b6636a0b
commit 3846b65758
6 changed files with 51 additions and 32 deletions

View File

@@ -102,6 +102,7 @@ include = ["src/tagstudio", "tests"]
reportAny = false
reportIgnoreCommentWithoutRule = false
reportImplicitStringConcatenation = false
reportImportCycles = false
reportMissingTypeArgument = false
reportMissingTypeStubs = false
# reportOptionalMemberAccess = false
@@ -110,6 +111,7 @@ reportUnknownArgumentType = false
reportUnknownLambdaType = false
reportUnknownMemberType = false
reportUnusedCallResult = false
reportUninitializedInstanceVariable = false
[tool.ruff]
exclude = ["home_ui.py", "resources.py", "resources_rc.py"]

View File

@@ -4,7 +4,7 @@
import io
from pathlib import Path
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, override
import cv2
import rawpy
@@ -12,6 +12,10 @@ import structlog
from PIL import Image, UnidentifiedImageError
from PIL.Image import DecompressionBombError
from PySide6.QtCore import QSize
from rawpy import (
LibRawFileUnsupportedError, # pyright: ignore[reportPrivateImportUsage]
LibRawIOError, # pyright: ignore[reportPrivateImportUsage]
)
from tagstudio.core.library.alchemy.library import Library
from tagstudio.core.media_types import MediaCategories
@@ -50,8 +54,8 @@ class PreviewThumb(PreviewThumbView):
stats.width = image.width
stats.height = image.height
except (
rawpy.LibRawIOError,
rawpy.LibRawFileUnsupportedError,
LibRawIOError,
LibRawFileUnsupportedError,
FileNotFoundError,
):
pass
@@ -144,18 +148,22 @@ class PreviewThumb(PreviewThumbView):
self._display_image(filepath)
return self.__get_image_stats(filepath)
@override
def _open_file_action_callback(self):
open_file(
self.__current_file, windows_start_command=self.__driver.settings.windows_start_command
)
@override
def _open_explorer_action_callback(self):
open_file(self.__current_file, file_manager=True)
@override
def _delete_action_callback(self):
if bool(self.__current_file):
self.__driver.delete_files_callback(self.__current_file)
@override
def _button_wrapper_callback(self):
open_file(
self.__current_file, windows_start_command=self.__driver.settings.windows_start_command

View File

@@ -7,7 +7,7 @@ from PIL import Image, ImageDraw, ImageFont
def wrap_line(
text: str,
font: ImageFont.ImageFont,
font: ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont,
width: int = 256,
draw: ImageDraw.ImageDraw | None = None,
) -> int:
@@ -31,7 +31,7 @@ def wrap_line(
def wrap_full_text(
text: str,
font: ImageFont.ImageFont,
font: ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont,
width: int = 256,
draw: ImageDraw.ImageDraw | None = None,
) -> str:

View File

@@ -43,7 +43,7 @@ from PIL import (
UnidentifiedImageError,
)
from PIL.Image import DecompressionBombError
from pillow_heif import register_heif_opener
from pillow_heif import register_heif_opener # pyright: ignore[reportUnknownVariableType]
from PySide6.QtCore import (
QBuffer,
QFile,
@@ -58,6 +58,10 @@ from PySide6.QtCore import (
from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPixmap
from PySide6.QtPdf import QPdfDocument, QPdfDocumentRenderOptions
from PySide6.QtSvg import QSvgRenderer
from rawpy import (
LibRawFileUnsupportedError, # pyright: ignore[reportPrivateImportUsage]
LibRawIOError, # pyright: ignore[reportPrivateImportUsage]
)
from tagstudio.core.constants import (
FONT_SAMPLE_SIZES,
@@ -75,9 +79,11 @@ from tagstudio.qt.helpers.gradients import four_corner_gradient
from tagstudio.qt.helpers.image_effects import replace_transparent_pixels
from tagstudio.qt.helpers.text_wrapper import wrap_full_text
from tagstudio.qt.models.palette import UI_COLORS, ColorType, UiColor, get_ui_color
from tagstudio.qt.previews.vendored.blender_renderer import blend_thumb
from tagstudio.qt.previews.vendored.blender_renderer import (
blend_thumb, # pyright: ignore[reportUnknownVariableType]
)
from tagstudio.qt.previews.vendored.pydub.audio_segment import (
_AudioSegment as AudioSegment,
_AudioSegment as AudioSegment, # pyright: ignore[reportPrivateUsage]
)
from tagstudio.qt.resource_manager import ResourceManager
@@ -118,7 +124,7 @@ class _TarFile:
def __init__(self, filepath: Path, mode: Literal["r"]) -> None:
self.tar: tarfile.TarFile
self.filepath = filepath
self.mode = mode
self.mode: Literal["r"] = mode
def namelist(self) -> list[str]:
return self.tar.getnames()
@@ -127,10 +133,10 @@ class _TarFile:
return unwrap(self.tar.extractfile(name)).read()
def __enter__(self) -> "_TarFile":
self.tar = tarfile.open(self.filepath, self.mode).__enter__()
self.tar = tarfile.open(name=self.filepath, mode=self.mode).__enter__()
return self
def __exit__(self, *args) -> None:
def __exit__(self, *args) -> None: # pyright: ignore[reportUnknownParameterType, reportMissingParameterType]
self.tar.__exit__(*args)
@@ -293,7 +299,7 @@ class ThumbRenderer(QObject):
im: Image.Image = Image.new(
mode="L",
size=tuple([d * smooth_factor for d in size]), # type: ignore
size=tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
color="black",
)
draw = ImageDraw.Draw(im)
@@ -324,7 +330,7 @@ class ThumbRenderer(QObject):
# Highlight
im_hl: Image.Image = Image.new(
mode="RGBA",
size=tuple([d * smooth_factor for d in size]), # type: ignore
size=tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
color="#00000000",
)
draw = ImageDraw.Draw(im_hl)
@@ -343,7 +349,7 @@ class ThumbRenderer(QObject):
# Shadow
im_sh: Image.Image = Image.new(
mode="RGBA",
size=tuple([d * smooth_factor for d in size]), # type: ignore
size=tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
color="#00000000",
)
draw = ImageDraw.Draw(im_sh)
@@ -388,7 +394,7 @@ class ThumbRenderer(QObject):
# Create larger blank image based on smooth_factor
im: Image.Image = Image.new(
"RGBA",
size=tuple([d * smooth_factor for d in size]), # type: ignore
size=tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
color="#FF000000",
)
@@ -396,13 +402,13 @@ class ThumbRenderer(QObject):
bg: Image.Image
bg = Image.new(
"RGB",
size=tuple([d * smooth_factor for d in size]), # type: ignore
size=tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
color="#000000FF",
)
# Use a background image if provided
if bg_image:
bg_im = Image.Image.resize(bg_image, size=tuple([d * smooth_factor for d in size])) # type: ignore
bg_im = Image.Image.resize(bg_image, size=tuple([d * smooth_factor for d in size])) # type: ignore # pyright: ignore[reportArgumentType]
bg_im = ImageEnhance.Brightness(bg_im).enhance(0.3) # Reduce the brightness
bg.paste(bg_im)
@@ -411,7 +417,7 @@ class ThumbRenderer(QObject):
bg,
(0, 0),
mask=self._get_mask(
tuple([d * smooth_factor for d in size]), # type: ignore
tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
(pixel_ratio * smooth_factor),
),
)
@@ -495,19 +501,19 @@ class ThumbRenderer(QObject):
# Create larger blank image based on smooth_factor
im: Image.Image = Image.new(
"RGBA",
size=tuple([d * smooth_factor for d in size]), # type: ignore
size=tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
color="#00000000",
)
bg: Image.Image
# Use a background image if provided
if bg_image:
bg = Image.Image.resize(bg_image, size=tuple([d * smooth_factor for d in size])) # type: ignore
bg = Image.Image.resize(bg_image, size=tuple([d * smooth_factor for d in size])) # type: ignore # pyright: ignore[reportArgumentType]
# Create solid background color
else:
bg = Image.new(
"RGB",
size=tuple([d * smooth_factor for d in size]), # type: ignore
size=tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
color="#000000",
)
# Apply color overlay
@@ -521,7 +527,7 @@ class ThumbRenderer(QObject):
bg,
(0, 0),
mask=self._get_mask(
tuple([d * smooth_factor for d in size]), # type: ignore
tuple([d * smooth_factor for d in size]), # type: ignore # pyright: ignore[reportArgumentType]
(pixel_ratio * smooth_factor),
),
)
@@ -662,17 +668,17 @@ class ThumbRenderer(QObject):
artwork = None
if ext in [".mp3"]:
id3_tags: id3.ID3 = id3.ID3(filepath)
id3_covers: list = id3_tags.getall("APIC")
id3_covers: list = id3_tags.getall("APIC") # pyright: ignore[reportUnknownVariableType]
if id3_covers:
artwork = Image.open(BytesIO(id3_covers[0].data))
elif ext in [".flac"]:
flac_tags: flac.FLAC = flac.FLAC(filepath)
flac_covers: list = flac_tags.pictures
flac_covers: list = flac_tags.pictures # pyright: ignore[reportUnknownVariableType]
if flac_covers:
artwork = Image.open(BytesIO(flac_covers[0].data))
elif ext in [".mp4", ".m4a", ".aac"]:
mp4_tags: mp4.MP4 = mp4.MP4(filepath)
mp4_covers: list | None = mp4_tags.get("covr") # pyright: ignore[reportAssignmentType]
mp4_covers: list | None = mp4_tags.get("covr") # pyright: ignore[reportUnknownVariableType]
if mp4_covers:
artwork = Image.open(BytesIO(mp4_covers[0]))
if artwork:
@@ -1088,7 +1094,7 @@ class ThumbRenderer(QObject):
font = ImageFont.truetype(filepath, size=font_size)
text_wrapped: str = wrap_full_text(
FONT_SAMPLE_TEXT,
font=font, # pyright: ignore[reportArgumentType]
font=font,
width=size,
draw=draw,
)
@@ -1120,8 +1126,8 @@ class ThumbRenderer(QObject):
)
except (
DecompressionBombError,
rawpy.LibRawIOError,
rawpy.LibRawFileUnsupportedError,
LibRawIOError,
LibRawFileUnsupportedError,
) as e:
logger.error("Couldn't render thumbnail", filepath=filepath, error=type(e).__name__)
return im
@@ -1137,6 +1143,7 @@ class ThumbRenderer(QObject):
try:
# Load the EXR data to an array and rotate the color space from BGRA -> RGBA
raw_array = cv2.imread(str(filepath), cv2.IMREAD_UNCHANGED)
assert raw_array is not None
raw_array[..., :3] = raw_array[..., 2::-1]
# Correct the gamma of the raw array
@@ -1209,7 +1216,7 @@ class ThumbRenderer(QObject):
# Write the image to a buffer as png
buffer: QBuffer = QBuffer()
buffer.open(QBuffer.OpenModeFlag.ReadWrite)
q_image.save(buffer, "PNG") # type: ignore[call-overload]
q_image.save(device=buffer, format="PNG") # type: ignore # pyright: ignore[reportArgumentType]
# Load the image from the buffer
im = Image.new("RGB", (size, size), color="#1e1e1e")
@@ -1258,7 +1265,7 @@ class ThumbRenderer(QObject):
return im
@staticmethod
def _model_stl_thumb(filepath: Path, size: int) -> Image.Image | None:
def _model_stl_thumb(filepath: Path, size: int) -> Image.Image | None: # pyright: ignore[reportUnusedParameter]
"""Render a thumbnail for an STL file.
Args:
@@ -1614,6 +1621,7 @@ class ThumbRenderer(QObject):
def fetch_cached_image(file_name: Path):
image: Image.Image | None = None
assert self.driver.cache_manager is not None
cached_path = self.driver.cache_manager.get_file_path(file_name)
if cached_path and cached_path.is_file():
@@ -1876,6 +1884,7 @@ class ThumbRenderer(QObject):
image = self._resize_image(image, (adj_size, adj_size))
if save_to_file and savable_media_type and image:
assert self.driver.cache_manager is not None
self.driver.cache_manager.save_image(image, save_to_file, mode="RGBA")
except (

View File

@@ -5,7 +5,7 @@
from PySide6.QtCore import QObject, QRunnable, Signal
class CustomRunnable(QRunnable, QObject):
class CustomRunnable(QRunnable, QObject): # pyright: ignore[reportUnsafeMultipleInheritance]
done = Signal()
def __init__(self, function) -> None:

View File

@@ -29,7 +29,7 @@ def test_tag_widget_actions_replaced_correctly(qtbot: QtBot, qt_driver: QtDriver
# Set the widget
tags = library.tags
panel.set_tag_widget(tags[0], 0)
tag_widget: TagWidget = panel.scroll_layout.itemAt(0).widget()
tag_widget: TagWidget = panel.scroll_layout.itemAt(0).widget() # pyright: ignore[reportAssignmentType]
should_replace_actions = {
tag_widget: ["on_edit()", "on_remove()"],