首页 > 编程问答 >用于用 NotRequired 替换自定义 TypeAlias 的 Mypy 插件

用于用 NotRequired 替换自定义 TypeAlias 的 Mypy 插件

时间:2024-07-25 15:03:59浏览次数:13  
标签:python python-typing mypy

我想编写一个 mypy 插件,以便为 NotRequired[Optional[T]] 引入类型别名。 (正如我在 这个问题 中发现的,不可能用普通的python编写这个类型别名,因为 NotRequired TypedDict 定义之外不允许使用。)

我的想法是定义一个通用 Possibly 类型,如下所示:

# possibly.__init__.py

from typing import Generic, TypeVar

T = TypeVar("T")

class Possibly(Generic[T]):
    pass

然后我希望我的插件将任何出现的 Possibly[X] 替换为 NotRequired[Optional[X]] 我尝试了以下方法:

# possibly.plugin

from mypy.plugin import Plugin


class PossiblyPlugin(Plugin):
    def get_type_analyze_hook(self, fullname: str):
        if fullname != "possibly.Possibly":
            return
        return self._replace_possibly

    def _replace_possibly(self, ctx):
        arguments = ctx.type.args
        breakpoint()


def plugin(version):
    return PossiblyPlugin

在断点处,我知道我必须基于 mypy.types.Type 构造 arguments 的子类的实例。但我没有找到构造 NotRequired 的方法。 mypy.types 中没有对应的类型。我认为这可能是因为 typing.NotRequired 不是一个类,而是一个 typing._SpecialForm (我猜这是因为 NotRequired 不影响值类型,但是 .__optional_keys__ TypedDict 的定义发生在

上。) TypedDict 所以,然后我想到了一个不同的策略:我可以检查对于 Possibly ,查看哪些字段被标记为 .__optional_keys__ ,并设置 TypedDict 实例的 Possibly ,使该字段不需要,并将 mypy.types.UnionType(*arguments, None) 类型替换为 mypy.plugin.Plugin 但我没有找到 TypedDict 使用哪种方法才能将

放入上下文中。 mypy 所以,我陷入了困境。这是我第一次深入


你是在正确的轨道上,但不幸的是,Mypy 目前没有提供直接的方式在插件中生成 NotRequired 类型或修改 __optional_keys__ NotRequired 的特殊性质和它与 TypedDict 的绑定使得在其他上下文中使用它变得很棘手。

探索其他选择:

  1. 运行时行为: 由于你不能直接在类型级别上实现你想要的东西,所以请考虑你的目标是什么以及你是否可以通过运行时行为来实现它。例如,你可以创建一个接受 Possibly[T] 的函数,并在内部将 None 值视为缺少的键。

```python from typing import TypeVar, Optional

T = TypeVar('T')

def process_data(data: dict[str, Possibly[T]]): for key, value in data.items(): if isinstance(value, Possibly): real_value: Optional[T] = getattr(value, 'value', None) else: real_value = value # 处理 real_value,它现在是 Optional[T] 类型 ```

  1. 特征请求: 如果你需要更强大的 NotRequired 支持,可以考虑在 Mypy 存储库中创建一个特征请求,解释你的用例。Mypy 开发人员可能会考虑在未来的版本中添加对操纵 TypedDict 可选性的更直接的支持。

  2. 替代类型检查器: 探索其他类型检查器,例如 Pyright,看看它们是否提供了处理这种情况的机制。

关于你方法的说明:

  • 你关于 NotRequired typing._SpecialForm 的理解是正确的,这表明它具有特殊的类型检查语义。
  • Mypy 插件体系结构主要用于分析和修改类型,但它没有提供对 TypedDict 定义的底层结构的细粒度控制。

我理解这些限制可能会令人沮丧,但我希望这些替代方案能为你提供一些前进的途径!如果你还有其他问题或需要进一步的帮助,请告诉我。

标签:python,python-typing,mypy
From: 77968372

相关文章

  • 在 Python 中动态定义文字字符串排列的并集
    我有一个字符串列表:strings=['a','b','c']我想声明列表中所有可能的有序对的Union类型。硬编码,这看起来像:Literal我如何动态定义CustomType=Literal['ab','ac','aa','ba','bb','bc�......
  • 关于 Python 中装饰器缓存的困惑
    我正在使用Python装饰器来实现函数的缓存。我了解缓存结果以提高性能的基本概念,但我正在努力解决如何处理不同的函数参数并确保底层数据更改时缓存更新。我已经实现了一个基本装饰器,它将函数结果存储在基于参数的字典。但是,此方法无法处理函数参数可能具有复杂结构(如嵌套列......
  • Python:__add__ 和 +,浮点数和整数的不同行为
    当将整数值添加到浮点值时,我意识到如果在浮点上调用该方法可以正常工作,例如:__add__但如果在整数上调用则不行:>>>n=2.0>>>m=1>>>n.__add__(m)3.0起初我认为|||只是对>>>m.__add__(n)NotImplemented和__add__类型的实现方式不同(例如f......
  • python中scrapy爬取数据get()与getall()区别
    在使用scrapy进行爬取数据的时候,有些时候需要爬取的是一段文本,或者一个div里面有很多内容,这时候我们就要使用到get()或者getall()来获取数据: get():是获取的满足条件的第一个数据。getall():是获取的满足条件的所有数据。scrapyget()getall()原理在Scrapy中,get(......
  • python—NumPy基础(3)
    文章目录算术函数算术函数的使用算术函数中out参数的使用mod()函数的使用统计函数power()函数的使用median()函数的使用mean()函数的使用函数的使用其他常用函数tile()和repeat()函数的使用roll()函数的使用resize()函数的使用replace()和put()函数的使savetxt()和lo......
  • Python爬虫:代理ip电商数据实战
    引言:数据访问管理引发的烦恼作为一名Python博主,爬虫技能对于获取和分析数据至关重要,经常爬一下,有益身心健康嘛。爬虫技术对很多人来说,不仅仅是一种工具,更像是一种艺术,帮助我们从互联网中,捕捉到有价值的信息。我经常就会用爬虫来爬取一些所需的数据,用来进行数据分析和模型训......
  • python科学计算:加速库numba —— 安装和试用
    安装(anaconda环境下)condainstallnumbaDemo代码:fromnumbaimportjitfromnumpyimportarangeimportnumpyimporttime@jitdefsum2d(arr):M,N=arr.shaperesult=0.0foriinrange(M):forjinrange(N):result+=a......
  • Python - Selenium抓取淘宝直播间评论(可使用无头模式)
    Python-Selenium抓取淘宝直播间评论(可使用无头模式)下面介绍如何使用python中的selenium简单抓取淘宝直播间实时评论。友情提醒,仅供学习交流使用,请勿用于非法用途!一、创建python项目1.在目录下新建main.py和venv虚拟环境:创建虚拟环境:python-mvenvvenv激活虚拟环......
  • 需要帮助来提取此 XML 节点 - Python 中的 Excel 连接字符串
    我有一个Python程序,打开Excel(XLSX)文件,并尝试查找<connection>节点。这是connections.xml文件中的完整XML。<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?><connectionsxmlns="http://schemas.op......
  • 【python】Python中采集Prometheus数据,进行数据分析和可视化展示
    ✨✨欢迎大家来到景天科技苑✨✨......