chore: enable strict mypy checks and fix pre-commit mypy hook

Add type annotations to all previously untyped functions and remove 9
suppressed error codes (call-arg, assignment, return-value, operator,
has-type, dict-item, misc, list-item, annotation-unchecked) by fixing
the underlying type issues.

Add [[tool.mypy.overrides]] with ignore_missing_imports for KiCAD-specific
modules (pcbnew, sexpdata, skip, cairosvg, kipy, PIL) so the pre-commit
mypy hook passes in its isolated venv. Add types-requests and pytest to
additional_dependencies in .pre-commit-config.yaml.

Also fixes several real bugs uncovered by stricter checks: incorrect static
calls to instance methods in swig_backend, wrong return type on get_size,
missing value param in BoardAPI.place_component, variable shadowing in
kicad_process.py, unqualified LibraryManager reference in kicad_interface,
and missing top-level Path import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Eugene Mikhantyev
2026-04-05 23:48:35 +01:00
parent 5a2b481db3
commit 9b1024a8f3
35 changed files with 4665 additions and 4610 deletions

View File

@@ -11,7 +11,7 @@ import os
import sqlite3
from datetime import datetime
from pathlib import Path
from typing import Dict, List, Optional
from typing import Any, Callable, Dict, List, Optional, Tuple
logger = logging.getLogger("kicad_interface")
@@ -38,10 +38,10 @@ class JLCPCBPartsManager:
db_path = str(data_dir / "jlcpcb_parts.db")
self.db_path = db_path
self.conn = None
self.conn: Optional[sqlite3.Connection] = None
self._init_database()
def _init_database(self):
def _init_database(self) -> None:
"""Initialize SQLite database with schema"""
self.conn = sqlite3.connect(self.db_path)
self.conn.row_factory = sqlite3.Row # Return rows as dicts
@@ -90,7 +90,9 @@ class JLCPCBPartsManager:
self.conn.commit()
logger.info(f"Initialized JLCPCB parts database at {self.db_path}")
def import_parts(self, parts: List[Dict], progress_callback=None):
def import_parts(
self, parts: List[Dict], progress_callback: Optional[Callable[..., Any]] = None
) -> None:
"""
Import parts into database from JLCPCB API response
@@ -167,7 +169,9 @@ class JLCPCBPartsManager:
else:
return "Extended" # Default to Extended
def import_jlcsearch_parts(self, parts: List[Dict], progress_callback=None):
def import_jlcsearch_parts(
self, parts: List[Dict], progress_callback: Optional[Callable[..., Any]] = None
) -> None:
"""
Import parts into database from JLCSearch API response
@@ -452,7 +456,7 @@ class JLCPCBPartsManager:
alternatives = [p for p in alternatives if p["lcsc"] != lcsc_number]
# Sort by: Basic first, then by price, then by stock
def sort_key(p):
def sort_key(p: Dict[str, Any]) -> Tuple[int, float, int]:
is_basic = 1 if p.get("library_type") == "Basic" else 0
try:
prices = json.loads(p.get("price_json", "[]"))
@@ -467,7 +471,7 @@ class JLCPCBPartsManager:
return alternatives[:limit]
def close(self):
def close(self) -> None:
"""Close database connection"""
if self.conn:
self.conn.close()