chore: clear typehinting errors

This commit is contained in:
aclist committed 2026-11-12 07:10:27 +09:00
1 parent 3e7b49203a
commit f7d95d5407
11 files changed
+99 -61

No files matched your search

+2 -1
View File
@@ -1,6 +1,7 @@
import pytest import pytest
from _pytest.monkeypatch import MonkeyPatch from _pytest.monkeypatch import MonkeyPatch
from collections.abc import Iterator
from pathlib import Path from pathlib import Path
from dzgui.api.steam import get_app_allows_downloads, get_last_updated from dzgui.api.steam import get_app_allows_downloads, get_last_updated
@@ -36,7 +37,7 @@ def steam_path() -> Path:
@pytest.fixture(scope="module", autouse=True) @pytest.fixture(scope="module", autouse=True)
def patch_api() -> None: def patch_api() -> Iterator[None]:
mp = MonkeyPatch() mp = MonkeyPatch()
mp.setattr("dzgui.api.steam.get_app_path", mock_path) mp.setattr("dzgui.api.steam.get_app_path", mock_path)
yield yield
+7 -1
View File
@@ -1,6 +1,7 @@
import pytest import pytest
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from dzgui.api.steam import find_user_id from dzgui.api.steam import find_user_id
from dzgui.const.constants import DEFAULT_STEAM_PATH from dzgui.const.constants import DEFAULT_STEAM_PATH
@@ -8,6 +9,9 @@ from tests.fixtures import fixture_path
pytestmark = pytest.mark.apitest pytestmark = pytest.mark.apitest
if TYPE_CHECKING:
from _pytest.monkeypatch import MonkeyPatch
@pytest.mark.parametrize( @pytest.mark.parametrize(
"fixture, expect", "fixture, expect",
@@ -19,12 +23,14 @@ pytestmark = pytest.mark.apitest
("api/loginusers_beta_client_multiple_2.vdf", 0), ("api/loginusers_beta_client_multiple_2.vdf", 0),
], ],
) )
def test_loginusers(monkeypatch, fixture: str, expect: int) -> None: def test_loginusers(monkeypatch: "MonkeyPatch", fixture: str, expect: int) -> None:
def mock_loginusers(path: Path) -> Path: def mock_loginusers(path: Path) -> Path:
return fixture_path(fixture) return fixture_path(fixture)
monkeypatch.setattr("dzgui.api.steam.find_loginusers", mock_loginusers) monkeypatch.setattr("dzgui.api.steam.find_loginusers", mock_loginusers)
uid = find_user_id(Path("")) uid = find_user_id(Path(""))
if uid is None:
raise ValueError()
assert int(uid) == expect assert int(uid) == expect
+15 -6
View File
@@ -11,27 +11,33 @@ import dzgui.config.query
from tests.fixtures import fixture_path from tests.fixtures import fixture_path
if TYPE_CHECKING: if TYPE_CHECKING:
from dzgui.const.enums import Preferences from _pytest.monkeypatch import MonkeyPatch
from dzgui.const.enum import Preferences
pytestmark = pytest.mark.mods pytestmark = pytest.mark.mods
@pytest.fixture @pytest.fixture
def versions() -> str: def versions() -> "Path":
return fixture_path("dzg.versions") return fixture_path("dzg.versions")
@pytest.fixture @pytest.fixture
def tmp() -> str: def tmp() -> str:
with tempfile.NamedTemporaryFile(delete=False) as f: with tempfile.NamedTemporaryFile(delete=False) as f:
tmp = f.name tmp = f.name
return tmp return tmp
def mock_local_ids(path: Path) -> list[int]: def mock_local_ids(path: Path) -> list[int]:
return [3410710885, 3739934289] return [3410710885, 3739934289]
def mock_lookup(path: Path, prefs: "Preferences") -> str: def mock_lookup(path: Path, prefs: "Preferences") -> str:
return "" return ""
def test_signatures(monkeypatch, tmp: str, versions: str) -> None:
def test_signatures(monkeypatch: "MonkeyPatch", tmp: str, versions: str) -> None:
ids = [1559212036, 1654462998] ids = [1559212036, 1654462998]
shutil.copyfile(versions, tmp) shutil.copyfile(versions, tmp)
path = Path(tmp) path = Path(tmp)
@@ -41,12 +47,15 @@ def test_signatures(monkeypatch, tmp: str, versions: str) -> None:
lines = f.readlines() lines = f.readlines()
assert ids not in lines assert ids not in lines
def test_signatures_with_no_ids(monkeypatch, tmp: str, versions: str) -> None:
def test_signatures_with_no_ids(
monkeypatch: "MonkeyPatch", tmp: str, versions: str
) -> None:
shutil.copyfile(versions, tmp) shutil.copyfile(versions, tmp)
path = Path(tmp) path = Path(tmp)
monkeypatch.setattr("dzgui.api.mods.get_local_mod_ids", mock_local_ids) monkeypatch.setattr("dzgui.api.mods.get_local_mod_ids", mock_local_ids)
monkeypatch.setattr("dzgui.api.mods.lookup", mock_lookup) monkeypatch.setattr("dzgui.api.mods.lookup", mock_lookup)
dzgui.api.mods.remove_stale_signatures(path, path) dzgui.api.mods.remove_stale_signatures(path, path)
with open(tmp, "r") as f: with open(tmp, "r") as f:
lines = f.readlines() lines = [line.rstrip() for line in f.readlines()]
assert lines == ["3410710885,1752864732\n", "3739934289,1780855136\n"] assert lines == ["3410710885,1752864732", "3739934289,1780855136"]
+3
View File
@@ -4,10 +4,13 @@ from pathlib import Path
from dzgui.api.mods import tokenize from dzgui.api.mods import tokenize
from tests.fixtures import fixture_path from tests.fixtures import fixture_path
@pytest.mark.mods @pytest.mark.mods
@pytest.mark.parametrize("i", range(1, 7)) @pytest.mark.parametrize("i", range(1, 7))
def test_modmeta(i: int) -> None: def test_modmeta(i: int) -> None:
fixture = fixture_path(f"cpp/mod{i}") fixture = fixture_path(f"cpp/mod{i}")
path = Path(fixture) path = Path(fixture)
meta = tokenize(path) meta = tokenize(path)
if meta is None:
raise ValueError
assert meta["name"] == "ModName" assert meta["name"] == "ModName"
+2 -2
View File
@@ -23,11 +23,11 @@ if TYPE_CHECKING:
def test_dayz_patch_pending( def test_dayz_patch_pending(
monkeypatch: "MonkeyPatch", file_list: list[str], expect: bool monkeypatch: "MonkeyPatch", file_list: list[str], expect: bool
) -> None: ) -> None:
def mock_get_pending_downloads(steam_path: Path, appid: int) -> None: def mock_get_pending_downloads(steam_path: Path, appid: int) -> list[Path]:
files = [Path(file) for file in file_list] files = [Path(file) for file in file_list]
return files return files
monkeypatch.setattr( monkeypatch.setattr(
"dzgui.api.steam.get_pending_downloads", mock_get_pending_downloads "dzgui.api.steam.get_pending_downloads", mock_get_pending_downloads
) )
assert is_dayz_downloading(Path("/tmp"), Path("/tmp")) == expect assert is_dayz_downloading(Path("/tmp"), 221100) == expect
+9 -3
View File
@@ -1,6 +1,7 @@
import pytest import pytest
from pathlib import Path
from pathlib import Path
from typing import TYPE_CHECKING
import dzgui.api.pefile as PeFile import dzgui.api.pefile as PeFile
from dzgui.api.steam import ( from dzgui.api.steam import (
@@ -16,6 +17,9 @@ from dzgui.const.constants import APPID_DAYZ
from tests.fixtures import fixture_path from tests.fixtures import fixture_path
if TYPE_CHECKING:
from _pytest.monkeypatch import MonkeyPatch
pytestmark = pytest.mark.apitest pytestmark = pytest.mark.apitest
@@ -53,7 +57,9 @@ def test_invalid_pefile_path() -> None:
("malformed.vdf", VDFLoadError), ("malformed.vdf", VDFLoadError),
], ],
) )
def test_not_in_library(monkeypatch, fixture, exception): def test_not_in_library(
monkeypatch: "MonkeyPatch", fixture: str, exception: type[Exception]
) -> None:
import dzgui.api.steam as steam import dzgui.api.steam as steam
monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", fixture) monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", fixture)
@@ -71,7 +77,7 @@ def second_drive() -> str:
return "in_library_on_second_drive.vdf" return "in_library_on_second_drive.vdf"
def test_on_second_drive(monkeypatch, second_drive: str) -> None: def test_on_second_drive(monkeypatch: "MonkeyPatch", second_drive: str) -> None:
import dzgui.api.steam as steam import dzgui.api.steam as steam
monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", second_drive) monkeypatch.setattr(steam, "LIBRARYFOLDERS_PATH", second_drive)
+3 -1
View File
@@ -1,6 +1,8 @@
import pytest import pytest
import unittest import unittest
from unittest.mock import patch from unittest.mock import patch
from typing import Any
from dzgui.const.constants import ( from dzgui.const.constants import (
FLATPAK_APPID, FLATPAK_APPID,
@@ -15,7 +17,7 @@ pytestmark = pytest.mark.flatpak
class TestSteamDetection(unittest.TestCase): class TestSteamDetection(unittest.TestCase):
def test_flatpak_detection_with_multiple_running_apps(self) -> None: def test_flatpak_detection_with_multiple_running_apps(self) -> None:
def flatpak_output(args, *, text: str) -> str: def flatpak_output(args: Any, *, text: str) -> str:
# Default 'flatpak ps' includes instance, PID, app and runtime columns. # Default 'flatpak ps' includes instance, PID, app and runtime columns.
if args == ["flatpak", "ps", "--columns=application"]: if args == ["flatpak", "ps", "--columns=application"]:
return f"com.spotify.Client\n{FLATPAK_APPID}\n{FLATPAK_APPID}\n" return f"com.spotify.Client\n{FLATPAK_APPID}\n{FLATPAK_APPID}\n"
+3 -3
View File
@@ -1,6 +1,6 @@
import pytest import pytest
from typing import TYPE_CHECKING from typing import Any, TYPE_CHECKING
from dzgui.api import probe from dzgui.api import probe
from dzgui.config.query import get_config from dzgui.config.query import get_config
@@ -13,7 +13,7 @@ pytestmark = pytest.mark.webtest
@pytest.fixture @pytest.fixture
def config() -> dict[str, "Path"]: def config() -> Any:
paths = get_xdg_paths() paths = get_xdg_paths()
xdg = parse_filepaths(paths) xdg = parse_filepaths(paths)
return get_config(xdg.config) return get_config(xdg.config)
@@ -23,6 +23,6 @@ def test_ipdb() -> None:
assert probe.test_ipdb() assert probe.test_ipdb()
def test_steam(config: dict[str, "Path"]) -> None: def test_steam(config: Any) -> None:
key = config["steam_api"] key = config["steam_api"]
assert probe.test_steam_api(key) assert probe.test_steam_api(key)
+2
View File
@@ -27,6 +27,8 @@ def test_time_accel(details, key, expect) -> None:
def test_gametime(details: Details | None) -> None: def test_gametime(details: Details | None) -> None:
time_reg = r"^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]$)" time_reg = r"^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]$)"
if details is None:
raise ValueError
match = re.match(time_reg, details.gametime) match = re.match(time_reg, details.gametime)
assert match is not None assert match is not None
+17 -7
View File
@@ -1,7 +1,8 @@
import pytest import pytest
from hypothesis import given, strategies as st
from datetime import datetime, timedelta from datetime import datetime, timedelta
from hypothesis import given, strategies as st
from typing import Any
from dzgui.views.dialogs.calc import ( from dzgui.views.dialogs.calc import (
LocalClock, LocalClock,
@@ -17,12 +18,12 @@ class DummyEmitter:
def __init__(self) -> None: def __init__(self) -> None:
pass pass
def connect(self, _, __) -> None: def connect(self, _: Any, __: Any) -> None:
pass pass
@pytest.fixture(params=[("05:00", 10.0), ("15:30", 5.0)]) @pytest.fixture(params=[("05:00", 10.0), ("15:30", 5.0)])
def accel_server_clock(request) -> None: def accel_server_clock(request) -> tuple[str, ServerClock]:
clock_time, expect = request.param clock_time, expect = request.param
cur_time = Time(clock_time, 5.0, 2.0) cur_time = Time(clock_time, 5.0, 2.0)
emitter = DummyEmitter() emitter = DummyEmitter()
@@ -31,13 +32,18 @@ def accel_server_clock(request) -> None:
return expect, server_clock return expect, server_clock
def test_accel_factor(accel_server_clock) -> None: def test_accel_factor(accel_server_clock: tuple[str, ServerClock]) -> None:
"""Static test checking times at known boundaries""" """Static test checking times at known boundaries"""
expect, clock = accel_server_clock expect, clock = accel_server_clock
assert clock.get_accel_factor(clock.cur_time) == expect assert clock.get_accel_factor(clock.cur_time) == expect
def reference_calc(start, end, day_factor, night_factor): def reference_calc(
start: datetime,
end: datetime,
day_factor: float,
night_factor: float,
) -> timedelta:
""" """
Reference implementation to test validity of UI-side calculator Reference implementation to test validity of UI-side calculator
Aggregates total seconds and applies accel factors after Aggregates total seconds and applies accel factors after
@@ -80,7 +86,7 @@ night_accel = st.floats(
@st.composite @st.composite
def time_ranges(draw): def time_ranges(draw: st.DrawFn) -> tuple[datetime, datetime]:
start_time = draw(st.times()) start_time = draw(st.times())
deltas = st.timedeltas(min_value=timedelta(0), max_value=timedelta(days=1)) deltas = st.timedeltas(min_value=timedelta(0), max_value=timedelta(days=1))
duration = draw(deltas) duration = draw(deltas)
@@ -91,7 +97,11 @@ def time_ranges(draw):
@given(span=time_ranges(), day_factor=day_accel, night_factor=night_accel) @given(span=time_ranges(), day_factor=day_accel, night_factor=night_accel)
def test_time_aggregation(span, day_factor, night_factor) -> None: def test_time_aggregation(
span: tuple[datetime, datetime],
day_factor: float,
night_factor: float,
) -> None:
start, end = span start, end = span
strtime = start.strftime("%H:%M") strtime = start.strftime("%H:%M")
+36 -37
View File
@@ -1,10 +1,11 @@
import pytest import pytest
import tempfile import tempfile
from typing import TYPE_CHECKING
from pathlib import Path
from _pytest.monkeypatch import MonkeyPatch from _pytest.monkeypatch import MonkeyPatch
from collections.abc import Iterator
from pathlib import Path
from typing import Any, cast, TYPE_CHECKING
from dzgui.api.shortcuts import Shortcuts from dzgui.api.shortcuts import Shortcuts
from tests.fixtures import fixture_path from tests.fixtures import fixture_path
@@ -15,12 +16,12 @@ if TYPE_CHECKING:
pytestmark = pytest.mark.apitest pytestmark = pytest.mark.apitest
def mock_find_shortcuts(self, steam_path: Path) -> Path: def mock_find_shortcuts(self: Shortcuts, steam_path: Path) -> Path:
return Path(fixture_path("api/no_shortcuts.vdf")) return Path(fixture_path("api/no_shortcuts.vdf"))
@pytest.fixture(scope="module", autouse=True) @pytest.fixture(scope="module", autouse=True)
def patch_api() -> None: def patch_api() -> Iterator[None]:
mp = MonkeyPatch() mp = MonkeyPatch()
mp.setattr("dzgui.api.shortcuts.Shortcuts.find_shortcuts_path", mock_find_shortcuts) mp.setattr("dzgui.api.shortcuts.Shortcuts.find_shortcuts_path", mock_find_shortcuts)
yield yield
@@ -33,64 +34,62 @@ def test_no_shortcuts(monkeypatch: "MonkeyPatch") -> None:
@pytest.fixture @pytest.fixture
def dummy_app() -> dict[str, str]: def dummy_app() -> dict[str, Any]:
d = { d = {
"AppName": "TEST APP", "AppName": "TEST APP",
"StartDir": "TEST_DIR", "StartDir": Path("TEST_DIR"),
"Exe": "TEST_DIR/TEST_EXE.EXE", "Exe": Path("TEST_DIR/TEST_EXE.EXE"),
"icon": "IMAGES_DIR/TEST_IMAGE.PNG", "icon": Path("IMAGES_DIR/TEST_IMAGE.PNG"),
} }
return d return d
def test_wrap_exe(dummy_app: dict[str, str]) -> None: @pytest.fixture
def shortcuts(dummy_app: dict[str, Any]) -> Shortcuts:
s = Shortcuts(Path("")) s = Shortcuts(Path(""))
s.add_shortcut(*dummy_app.values()) args = cast(tuple[str, Path, Path, Path], dummy_app.values())
assert s.shortcuts["shortcuts"]["0"]["Exe"][0] == '"' s.add_shortcut(*args)
assert s.shortcuts["shortcuts"]["0"]["Exe"][-1] == '"' return s
def test_add_shortcut(dummy_app: dict[str, str]) -> None: def test_wrap_exe(shortcuts: Shortcuts) -> None:
s = Shortcuts(Path("")) assert shortcuts.shortcuts["shortcuts"]["0"]["Exe"][0] == '"'
s.add_shortcut(*dummy_app.values()) assert shortcuts.shortcuts["shortcuts"]["0"]["Exe"][-1] == '"'
new = s.shortcuts["shortcuts"]
def test_add_shortcut(shortcuts: Shortcuts, dummy_app: dict[str, Any]) -> None:
new = shortcuts.shortcuts["shortcuts"]
ind = str(len(new) - 1) ind = str(len(new) - 1)
for k, v in dummy_app.items(): for k, v in dummy_app.items():
if k == "Exe": if k == "Exe":
v = f'"{v}"' v = f'"{v}"'
assert new[ind][k] == v assert new[ind][k] == str(v)
def test_save_shortcut(dummy_app: dict[str, str]) -> None: def test_save_shortcut(shortcuts: Shortcuts) -> None:
s = Shortcuts(Path(""))
s.add_shortcut(*dummy_app.values())
with tempfile.NamedTemporaryFile() as f: with tempfile.NamedTemporaryFile() as f:
tmp = Path(f.name) tmp = Path(f.name)
s.shortcuts_path = tmp shortcuts.shortcuts_path = tmp
s.save_shortcuts() shortcuts.save_shortcuts()
s._load_shortcuts(tmp) shortcuts._load_shortcuts(tmp)
assert len(s.shortcuts["shortcuts"]) == 1 assert len(shortcuts.shortcuts["shortcuts"]) == 1
def test_shortcut_crc(dummy_app: dict[str, str]) -> None: def test_shortcut_crc(shortcuts: Shortcuts) -> None:
s = Shortcuts(Path("")) for key in shortcuts.shortcuts["shortcuts"].keys():
s.add_shortcut(*dummy_app.values()) entry = shortcuts.shortcuts["shortcuts"][key]
for key in s.shortcuts["shortcuts"].keys():
entry = s.shortcuts["shortcuts"][key]
name = entry["AppName"] name = entry["AppName"]
exe = entry["Exe"] exe = entry["Exe"]
uid = name + exe uid = name + exe
bpid = s.gen_bpid(uid) bpid = shortcuts.gen_bpid(uid)
assert entry["appid"] & 0xFFFFFFFF == bpid assert entry["appid"] & 0xFFFFFFFF == bpid
def test_reverse_crc(dummy_app: dict[str, str]) -> None: def test_reverse_crc(shortcuts: Shortcuts) -> None:
s = Shortcuts(Path("")) for key in shortcuts.shortcuts["shortcuts"].keys():
s.add_shortcut(*dummy_app.values()) entry = shortcuts.shortcuts["shortcuts"][key]
for key in s.shortcuts["shortcuts"].keys():
entry = s.shortcuts["shortcuts"][key]
name = entry["AppName"] name = entry["AppName"]
exe = entry["Exe"] exe = entry["Exe"]
uid = name + exe uid = name + exe
bpid = s.gen_bpid(uid) bpid = shortcuts.gen_bpid(uid)
assert s.find_appname_by_unsigned_id(bpid) == name assert shortcuts.find_appname_by_unsigned_id(bpid) == name