Python 3元类如何进行类型提示?

4

今天在我升级了使用的 mypy 版本后,我的某些代码里出现了一个类型警告。关于这个问题似乎没有太多的文献资料,所以希望这里能有人帮助我解决!

我定义了一个如下的元类...

 from __future__ import annotations


 class MyMetaClass(type):                                                                                                                                

     def __new__(mcs,                                                                  
                 name: str,                                                            
                 bases: Tuple[type, ...],                                              
                 namespace: Dict[str, Any],                                                                                     
                 ) -> MyMetaClass:                                             

         # Custom code... doesnt matter
         # ...
         # ...

         return type.__new__(mcs, name, bases, namespace)

今天,mypy开始输出以下错误...
error: Incompatible return value type (got "type", expected "MyMetaClass")

我尝试了以下几种 return 语句的写法,但都没有成功...

return super().__new__(mcs, name, bases, namespace)
return super(MyMetaClass, mcs).__new__(mcs, name, bases, namespace)

有什么建议可以避免这个警告吗?最终我选择了一个强制类型转换的方法...但是感觉肯定有更好的办法。

return cast(MyMetaClass, super().__new__(mcs, name, bases, namespace))

只是为了明确一下,你的类的源文件是否以from __future__ import annotations开头,以便首先允许你推迟注释评估? - ShadowRanger
我强烈怀疑这实际上是当值是cls的实例时,你能注释返回类型吗?的重复问题。虽然不是100%确定,但你可以尝试那里的解决方案吗? - ShadowRanger
@ShadowRanger是的,它可以!我将在上面的片段中包含它。关于您提出的另一个建议,如果我使用T = TypeVar('T', bound='MyMetaClass'),仍然会出现错误,现在是不兼容的返回值类型(得到"类型",期望"T") - wakey
1个回答

0
问题是你没有注释mcs参数,所以无法知道super().__new__会返回什么类型。

1
嗨尼尔,很高兴再次回顾这个问题。在我的 python 3.11.1 版本中,mypy不再对上述代码片段报错。我猜测自2019年9月以来,任何潜在的问题都已经得到修复。 - wakey
1
@wakey哦,那很有道理,他们可能隐式地将第一个参数类型为type[Self]或其他什么。无论如何,谢谢你的问题。我不得不查一下这个,这是我找到的第一个结果。 - Neil G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接