From 3619fd87560187b54671922423e49ededdea5dda Mon Sep 17 00:00:00 2001 From: Wouter Vanden Hove Date: Sun, 30 Aug 2026 16:27:42 +0200 Subject: [PATCH] fix(about): make about.py metadata lookup type-checker-proof Dependabot #103 (bump `ty` 0.0.19 -> 0.0.29) turns the Linting job red on every Python version. `ty` rejects two constructs in `about.py` that older `ty` accepted and that `# type: ignore[...]` does not silence: - `msg.json` -> `unresolved-attribute` (typeshed resolves `importlib.metadata.metadata()` as `email.message.Message`). - `version: str = pkginfo.get("version", "unknown")` -> `invalid-assignment` (the value is `str | list[str]`). Materialise the distribution metadata into a plain `dict[str, str]` via `{key: msg[key] for key in msg}` - only `__iter__` (over keys) and `__getitem__` are guaranteed on `PackageMetadata` across 3.9-3.14, unlike `.json` / `.get` - then read `Author-email` / `License(-Expression)` / `Version` off the dict. Fallback branches keep their `# pragma: no cover`. Verified against `ty` 0.0.75 locally (plus ruff, pylint 10/10, mypy on 3.10/3.11/3.14, pre-commit, pytest+coverage 100%). Merging unblocks #103, which then only carries the lockfile bump. --- src/autoadd_bindir/about.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/autoadd_bindir/about.py b/src/autoadd_bindir/about.py index 5f0483d..b487eac 100644 --- a/src/autoadd_bindir/about.py +++ b/src/autoadd_bindir/about.py @@ -13,18 +13,21 @@ try: - msg = importlib.metadata.metadata(PACKAGE) - pkginfo: dict[str, str | list[str]] = msg.json # type: ignore[attr-defined] + _msg = importlib.metadata.metadata(PACKAGE) + # Materialise a plain ``dict`` so downstream ``.get(...)`` calls are typed + # unambiguously on every supported Python: ``PackageMetadata`` only guarantees + # ``__iter__`` (over keys) and ``__getitem__`` across versions. + pkginfo: dict[str, str] = {key: _msg[key] for key in _msg} except ValueError: # pragma: no cover - # A distribution name is required. __package__ is None + # A distribution name is required. __package__ is None. pkginfo = {} except importlib.metadata.PackageNotFoundError: # pragma: no cover # fallback if this package is not properly installed pkginfo = {} -authors: str | list[str] = pkginfo.get("author_email", "unknown") +authors: str = pkginfo.get("Author-email", "unknown") -license_: str | list[str] = pkginfo.get("license_expression") or pkginfo.get("license", "unknown") or "unknown" +license_: str = pkginfo.get("License-Expression") or pkginfo.get("License", "unknown") or "unknown" -version: str = pkginfo.get("version", "unknown") # type: ignore[assignment] +version: str = pkginfo.get("Version", "unknown")