gpt4 book ai didi

django-rest-framework - 在运行时验证 Python TypedDict

转载 作者:行者123 更新时间:2023-12-03 23:39:27 24 4
gpt4 key购买 nike

我在 Python 3.8+ Django/Rest-Framework 环境中工作,在新代码中强制执行类型,但建立在许多未类型化的遗留代码和数据上。我们广泛使用 TypedDicts 来确保我们生成的数据以正确的数据类型传递到我们的 TypeScript 前端。
MyPy/PyCharm/等。在检查我们的新代码是否吐出符合要求的数据方面做得很好,但我们想测试我们许多 RestSerializers/ModelSerializers 的输出是否符合 TypeDict。如果我有一个序列化程序并输入 dict 如下:

class PersonSerializer(ModelSerializer):
class Meta:
model = Person
fields = ['first', 'last']

class PersonData(TypedDict):
first: str
last: str
email: str
然后运行如下代码:
person_dict: PersonData = PersonSerializer(Person.objects.first()).data
静态类型检查器无法弄清楚 person_dict缺少所需的 email关键,因为(由 PEP-589 设计)它只是一个普通的 dict .但我可以写一些类似的东西:
annotations = PersonData.__annotations__
for k in person_dict:
assert k in annotations # or something more complex.
assert isinstance(person_dict[k], annotations[k])
它会发现 email序列化器的数据中缺少。这在这种情况下很好,我没有任何由 from __future__ import annotations 引入的更改。 (不确定这是否会破坏它),并且我所有的类型注释都是裸类型。但如果 PersonData定义如下:
class PersonData(TypedDict):
email: Optional[str]
affiliations: Union[List[str], Dict[int, str]]
然后 isinstance不足以检查数据是否通过(因为“下标泛型不能与类和实例检查一起使用”)。
我想知道的是,是否已经存在一个可调用的函数/方法(在 mypy 或其他检查器中)允许我针对注释验证 TypedDict(甚至是单个变量,因为我可以自己迭代 dict)并查看如果它验证?
我不关心速度等,因为这样做的目的是检查我们所有的数据/方法/函数一次,然后在我们对当前数据验证感到高兴后删除检查。

最佳答案

有点小技巧,但您可以使用 mypy 命令行 -c 检查两种类型选项。只需将它包装在一个 python 函数中:

import subprocess

def is_assignable(type_to, type_from) -> bool:
"""
Returns true if `type_from` can be assigned to `type_to`,
e. g. type_to := type_from

Example:
>>> is_assignable(bool, str)
False
>>> from typing import *
>>> is_assignable(Union[List[str], Dict[int, str]], List[str])
True
"""
code = "\n".join((
f"import typing",
f"type_to: {type_to}",
f"type_from: {type_from}",
f"type_to = type_from",
))
return subprocess.call(("mypy", "-c", code)) == 0

关于django-rest-framework - 在运行时验证 Python TypedDict,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66665336/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com