如何将字符串转为boto3的EncryptionAlgorithmSpecType字面量解决mypy报错
最优实现方案
可以直接利用Python Literal 类型内置的__args__属性获取所有合法取值,该属性和EncryptionAlgorithmSpecType的定义完全同步,运行时也可以直接访问,不需要手动二次枚举所有值,优化后的代码如下:
import boto3 from typing import cast from mypy_boto3_kms.literals import EncryptionAlgorithmSpecType def get_encryption_algorithm_literal(algorithm: str) -> EncryptionAlgorithmSpecType: valid_algorithms = EncryptionAlgorithmSpecType.__args__ if algorithm in valid_algorithms: # 已确认值合法,用cast告知mypy类型匹配 return cast(EncryptionAlgorithmSpecType, algorithm) raise ValueError(f"Unexpected algorithm '{algorithm}'. It must be one of {valid_algorithms}") def main(binary_enc_data: bytes, key_id: str, algorithm: str): kms = boto3.client('kms') kms_result = kms.decrypt( CiphertextBlob=binary_enc_data, KeyId=key_id, EncryptionAlgorithm=get_encryption_algorithm_literal(algorithm) )
如果不想显式使用cast,可以搭配类型守卫实现自动类型推导,mypy可直接识别类型合法性:
import boto3 from typing import TypeGuard from mypy_boto3_kms.literals import EncryptionAlgorithmSpecType def is_valid_enc_algorithm(alg: str) -> TypeGuard[EncryptionAlgorithmSpecType]: return alg in EncryptionAlgorithmSpecType.__args__ def get_encryption_algorithm_literal(algorithm: str) -> EncryptionAlgorithmSpecType: valid_algorithms = EncryptionAlgorithmSpecType.__args__ if is_valid_enc_algorithm(algorithm): return algorithm raise ValueError(f"Unexpected algorithm '{algorithm}'. It must be one of {valid_algorithms}")
注:
TypeGuard在Python 3.10及以上版本内置在typing模块中,更低版本需要从typing_extensions导入。
该方案完全复用了EncryptionAlgorithmSpecType的定义,后续如果boto3-stubs更新了该Literal的合法取值,代码不需要做任何修改即可同步适配,同时也保留了运行时的参数校验能力,不需要禁用mypy的类型检查。
内容的提问来源于stack exchange,提问作者eNca
相关产品推荐
相关产品推荐

