Skip to content

Commit 352e0e9

Browse files
committed
Fix mypy type checking errors: add type annotations and handle None cases
1 parent 31ac57c commit 352e0e9

4 files changed

Lines changed: 48 additions & 33 deletions

File tree

bookmark_checker/core/dedupe.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
"""Deduplication logic with fuzzy title matching."""
22

33
from collections import defaultdict
4-
from typing import Any
4+
from typing import TYPE_CHECKING, Any
55

6-
try:
7-
from rapidfuzz import fuzz
8-
except ImportError:
9-
fuzz = None
6+
if TYPE_CHECKING:
7+
from rapidfuzz import fuzz as fuzz_module
8+
else:
9+
try:
10+
from rapidfuzz import fuzz as fuzz_module
11+
except ImportError:
12+
fuzz_module = None
13+
14+
fuzz = fuzz_module
1015

1116
from bookmark_checker.core.models import Bookmark, BookmarkCollection
1217
from bookmark_checker.core.utils import domain_from_url, normalize_whitespace

bookmark_checker/core/models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Data models for bookmarks."""
22

3+
from collections.abc import Iterator
34
from dataclasses import dataclass, field
45
from datetime import datetime
56
from typing import Any
@@ -53,6 +54,6 @@ def __len__(self) -> int:
5354
"""Return the number of bookmarks."""
5455
return len(self.bookmarks)
5556

56-
def __iter__(self):
57+
def __iter__(self) -> Iterator[Bookmark]:
5758
"""Iterate over bookmarks."""
5859
return iter(self.bookmarks)

bookmark_checker/core/parsers.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def parse_netscape_html(path: str) -> BookmarkCollection:
6060

6161
def get_folder_path_for_element(element: Any) -> str:
6262
"""Get folder path by finding all parent DLs and their associated H3 folders."""
63-
path_parts = []
63+
path_parts: list[str] = []
6464
current_dl = element.find_parent("dl")
6565

6666
# Walk up the tree through all parent DLs
@@ -133,7 +133,8 @@ def get_folder_path_for_element(element: Any) -> str:
133133
all_links = soup.find_all("a", href=True)
134134

135135
for link in all_links:
136-
url = link.get("href", "").strip()
136+
href_attr = link.get("href", "")
137+
url = str(href_attr).strip() if href_attr else ""
137138
if not url or url.startswith("data:"):
138139
continue
139140

@@ -144,7 +145,7 @@ def get_folder_path_for_element(element: Any) -> str:
144145
add_date = link.get("add_date")
145146
if add_date:
146147
try:
147-
timestamp = int(add_date)
148+
timestamp = int(str(add_date))
148149
added = datetime.fromtimestamp(timestamp)
149150
except (ValueError, OSError):
150151
pass

bookmark_checker/ui/main_window.py

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import sys
44
from pathlib import Path
5+
from typing import Any
56

67
from PyQt6.QtCore import Qt
78
from PyQt6.QtGui import QColor, QDragEnterEvent, QDropEvent, QPalette
@@ -37,8 +38,10 @@ def __init__(self) -> None:
3738
self.setMinimumSize(1000, 640)
3839

3940
# Data
40-
self.current_collection = None
41-
self.current_report: list[dict] = []
41+
from bookmark_checker.core.models import BookmarkCollection
42+
43+
self.current_collection: BookmarkCollection | None = None
44+
self.current_report: list[dict[str, Any]] = []
4245

4346
# Setup UI
4447
self._setup_ui()
@@ -102,17 +105,13 @@ def _setup_ui(self) -> None:
102105
self.table.setHorizontalHeaderLabels(
103106
["Title", "URL (canonical)", "Folder", "Source", "Count"]
104107
)
105-
self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
106-
self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
107-
self.table.horizontalHeader().setSectionResizeMode(
108-
2, QHeaderView.ResizeMode.ResizeToContents
109-
)
110-
self.table.horizontalHeader().setSectionResizeMode(
111-
3, QHeaderView.ResizeMode.ResizeToContents
112-
)
113-
self.table.horizontalHeader().setSectionResizeMode(
114-
4, QHeaderView.ResizeMode.ResizeToContents
115-
)
108+
header = self.table.horizontalHeader()
109+
if header:
110+
header.setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
111+
header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
112+
header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
113+
header.setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
114+
header.setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents)
116115
self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
117116
self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
118117
layout.addWidget(self.table)
@@ -186,15 +185,22 @@ def _setup_style(self) -> None:
186185
"""
187186
)
188187

189-
def dragEnterEvent(self, event: QDragEnterEvent) -> None:
188+
def dragEnterEvent(self, event: QDragEnterEvent | None) -> None:
190189
"""Handle drag enter event."""
191-
if event.mimeData().hasUrls():
190+
if event is None:
191+
return
192+
mime_data = event.mimeData()
193+
if mime_data and mime_data.hasUrls():
192194
event.acceptProposedAction()
193195

194-
def dropEvent(self, event: QDropEvent) -> None:
196+
def dropEvent(self, event: QDropEvent | None) -> None:
195197
"""Handle drop event."""
196-
files = [url.toLocalFile() for url in event.mimeData().urls()]
197-
self._process_files(files)
198+
if event is None:
199+
return
200+
mime_data = event.mimeData()
201+
if mime_data:
202+
files = [url.toLocalFile() for url in mime_data.urls()]
203+
self._process_files(files)
198204

199205
def _import_files(self) -> None:
200206
"""Open file dialog to import bookmark files."""
@@ -214,8 +220,9 @@ def _process_files(self, files: list[str]) -> None:
214220
self.progress_bar.setRange(0, 0) # Indeterminate
215221

216222
try:
217-
self.current_collection = parse_many(files)
218-
if len(self.current_collection.bookmarks) == 0:
223+
collection = parse_many(files)
224+
self.current_collection = collection
225+
if len(collection.bookmarks) == 0:
219226
QMessageBox.warning(
220227
self,
221228
"No Bookmarks Found",
@@ -225,7 +232,7 @@ def _process_files(self, files: list[str]) -> None:
225232
self.btn_merge.setEnabled(False)
226233
else:
227234
self.status_label.setText(
228-
f"Loaded {len(self.current_collection.bookmarks)} "
235+
f"Loaded {len(collection.bookmarks)} "
229236
f"bookmarks from {len(files)} file(s)"
230237
)
231238
self.btn_merge.setEnabled(True)
@@ -286,7 +293,7 @@ def _populate_table_from_collection(self) -> None:
286293
self.table.setItem(row, 3, QTableWidgetItem(bookmark.source_file))
287294
self.table.setItem(row, 4, QTableWidgetItem("1")) # Count is 1 for raw bookmarks
288295

289-
def _populate_table(self, report: list[dict]) -> None:
296+
def _populate_table(self, report: list[dict[str, Any]]) -> None:
290297
"""Populate table with dedupe report."""
291298
self.table.setRowCount(len(report))
292299

@@ -301,7 +308,8 @@ def _populate_table(self, report: list[dict]) -> None:
301308

302309
def _export_merged(self) -> None:
303310
"""Export merged bookmarks."""
304-
if not self.current_collection or not self.current_report:
311+
collection = self.current_collection
312+
if not collection or not self.current_report:
305313
return
306314

307315
output_path, _ = QFileDialog.getSaveFileName(
@@ -322,7 +330,7 @@ def _export_merged(self) -> None:
322330
# Re-merge to get merged collection
323331
similarity = self.similarity_slider.value()
324332
merged, _ = merge_collections(
325-
self.current_collection, similarity_threshold=similarity, enable_fuzzy=True
333+
collection, similarity_threshold=similarity, enable_fuzzy=True
326334
)
327335

328336
# Export HTML

0 commit comments

Comments
 (0)