diff --git a/app/service/offsite_document_recognition_adapter.py b/app/service/offsite_document_recognition_adapter.py index 0b4970f..4b3b9e2 100644 --- a/app/service/offsite_document_recognition_adapter.py +++ b/app/service/offsite_document_recognition_adapter.py @@ -785,7 +785,8 @@ def _confidence_map(value: Mapping[str, object]) -> dict[str, Decimal]: def _document_type(value: object) -> DocumentType: if value in ("summary", "subscription", "redemption", "other"): - return cast(DocumentType, value) + # 不需要 cast:上面的 `in (...)` 已经把类型收窄到那个字面量联合了。 + return value return "other" diff --git a/app/service/offsite_fund_service.py b/app/service/offsite_fund_service.py index 09daee3..4e37973 100644 --- a/app/service/offsite_fund_service.py +++ b/app/service/offsite_fund_service.py @@ -7,7 +7,7 @@ from datetime import UTC, date, datetime from decimal import Decimal from email import policy from email.header import decode_header, make_header -from email.message import Message +from email.message import EmailMessage from email.parser import BytesParser from email.utils import parsedate_to_datetime from pathlib import Path @@ -1190,7 +1190,10 @@ class OffsiteFundService: @staticmethod def _parse_eml(path: str) -> dict[str, object]: - empty = { + # 显式标注:字面量里只有一个 bool,mypy 会把它推断成 `dict[str, bool | None]`, + # 而 dict 是**不变型**,`dict[str, bool | None]` 不是 `dict[str, object]` 的子类型。 + # 运行时本来就是合法值,缺的只是这一个标注。 + empty: dict[str, object] = { "subject": None, "sent_at": None, "has_body": False, @@ -1227,8 +1230,11 @@ class OffsiteFundService: except (LookupError, UnicodeError, ValueError): return value + # 形参标注用 EmailMessage 而不是基类 Message:`get_content()` 只定义在 EmailMessage 上, + # 而调用方传的是 `BytesParser(policy=policy.default).parsebytes(...)` 的返回值 —— + # 它本来就是 EmailMessage。原先标注成基类,mypy 于是在下面报"没有该属性"。 @staticmethod - def _mail_body(message: Message) -> tuple[str | None, str | None]: + def _mail_body(message: EmailMessage) -> tuple[str | None, str | None]: text_body: str | None = None html_body: str | None = None parts = message.walk() if message.is_multipart() else (message,)