From 3612e45df6cdc542b6af1e7b4ab0cd41740a48ba Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Mon, 2 May 2022 11:31:05 -0700 Subject: [PATCH] Add casts for package metadata In the latest mypy (0.942), importlib.metadata.metadata now returns a Protocol named PackageMetadata that doesn't implement the get method. The actual object remains a Message class, however, so the get method works correctly. Only mypy checking fails. Pending https://github.com/python/typeshed/issues/7767, which may reveal that it is intentional that get not be supported, cast the return value to Message so that the existing functions work. This seems better than adding try/catch blocks for every piece of metadata of interest given that the omission of get appears to be unintentional. --- src/safir/metadata.py | 4 ++-- tests/metadata_test.py | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/safir/metadata.py b/src/safir/metadata.py index 50848f6..a23ce88 100644 --- a/src/safir/metadata.py +++ b/src/safir/metadata.py @@ -5,7 +5,7 @@ from email.message import Message from importlib.metadata import metadata -from typing import Optional +from typing import Optional, cast from pydantic import BaseModel, Field @@ -66,7 +66,7 @@ def get_metadata(*, package_name: str, application_name: str) -> Metadata: project_urls, Source code Used as the ``respository_url``. """ - pkg_metadata: Message = metadata(package_name) + pkg_metadata: Message = cast(Message, metadata(package_name)) return Metadata( name=application_name, version=pkg_metadata.get("Version", "0.0.0"), diff --git a/tests/metadata_test.py b/tests/metadata_test.py index 8bf2bbb..7ef6361 100644 --- a/tests/metadata_test.py +++ b/tests/metadata_test.py @@ -3,20 +3,18 @@ from __future__ import annotations +from email.message import Message from importlib.metadata import metadata -from typing import TYPE_CHECKING +from typing import cast import pytest from safir.metadata import get_metadata, get_project_url -if TYPE_CHECKING: - from email.message import Message - @pytest.fixture(scope="session") def safir_metadata() -> Message: - return metadata("safir") + return cast(Message, metadata("safir")) def test_get_project_url(safir_metadata: Message) -> None: