如何让mypy兼容__getitem__返回None、__setitem__拒接None的MutableMapping
解决方案
修复__contains__的类型错误
MutableMapping继承的Container和Mapping抽象类要求__contains__的参数类型为object(遵循里氏替换原则,子类方法的参数类型不能比父类更严格)。你需要修改参数类型,并在内部过滤非字符串的键:
def __contains__(self, key: object) -> bool: if not isinstance(key, str): return False return self._record.get(key) is not None
这样既符合父类的类型要求,又保证只有字符串键会被检查,非字符串键直接返回False,避免了和__getitem__的参数冲突。
修复__getitem__的类型错误
Mapping[str, int]的契约要求__getitem__必须返回int,当键不存在时抛出KeyError,而你的实现返回None违反了这个契约,这是mypy报错的核心原因。
如果必须保留“无对应键时返回None”的逻辑,同时不想移除MutableMapping继承,有两种可行方案:
方案1:遵循Mapping契约,新增get方法实现需求
调整__getitem__使其符合契约(键不存在时抛KeyError),同时新增一个get方法来实现“返回None”的逻辑:
def __getitem__(self, key: str) -> int: # 遵循Mapping契约,键不存在时抛出KeyError try: return self._record[key] except KeyError: # 替换为你的实际复杂逻辑后,抛出KeyError raise KeyError(key) def get(self, key: str) -> int | None: # 实现你需要的“无键返回None”逻辑 return self._record.get(key)
这种方案完全符合MutableMapping的类型规范,mypy会通过检查,同时满足你的业务需求。
方案2:调整泛型类型并限制__setitem__的参数
如果你坚持让__getitem__返回int | None,可以将泛型改为MutableMapping[str, int | None],然后通过重载和运行时检查限制__setitem__只能接受int类型:
from typing import overload, Iterator from collections.abc import MutableMapping class FooMap(MutableMapping[str, int | None]): _record: dict[str, int] def __init__(self) -> None: self._record = {} def __contains__(self, key: object) -> bool: if not isinstance(key, str): return False return self._record.get(key) is not None def __getitem__(self, key: str) -> int | None: return self._record.get(key) @overload def __setitem__(self, key: str, value: int) -> None: ... def __setitem__(self, key: str, value: int | None) -> None: if value is None: raise ValueError("Cannot set None as value") self._record[key] = value def __delitem__(self, key: str) -> None: raise TypeError('Keys cannot be deleted') def __len__(self) -> int: return len(self._record) def __iter__(self) -> Iterator[str]: return iter(self._record)
这种方案下,mypy会认为__setitem__支持int | None,但实际运行时会拒绝None值,同时__getitem__的返回类型也符合泛型定义。不过这种方式存在一定的类型“欺骗”,不如方案1规范。
内容的提问来源于stack exchange,提问作者InSync
相关产品推荐
相关产品推荐

