Pycharm 静态类型检查器失败
Posted
技术标签:
【中文标题】Pycharm 静态类型检查器失败【英文标题】:Pycharm static type checker fails 【发布时间】:2021-02-28 04:33:57 【问题描述】:也许有人可以在这里帮助我。 我一直在为这个pycharm集成的静态类型检查器苦苦挣扎。
一些规格:
Python 3.7.7 Windows 10 专业版 x64我尝试了以下 PyCharm 版本。
专业2020.1.3 社区 2020.2.3我试图说明问题。您可以将其复制并粘贴到您的 PyCharm 中以验证问题。
class SpecificCLS:
pass
class CLS:
def __init__(self):
self.integer: int = 0
self.specific_cls: SpecificCLS = SpecificCLS()
def set_im_int(self, value: int):
self.integer = value
def get_im_int(self) -> int:
return self.integer
def get_specific_cls(self) -> SpecificCLS:
return self.specific_cls
def set_specific_cls(self, value: SpecificCLS):
self.specific_cls = value
cls = CLS()
# Example for assigning a class into an integer
cls.integer = SpecificCLS() # PyCharm does NOT show any error/warning that a class is assigned into an variable that is declared as an "int"
cls.set_im_int(SpecificCLS()) # PyCharm recognise an error (underlined red): Expected type 'int', got 'SpecificCLS' instead
# Example for assigning an integer into a class
cls.specific_cls = 1 # PyCharm does NOT show any error/warning that a class is assigned into an variable that is declared as an "int"
cls.set_specific_cls(1) # PyCharm recognise an error (underlined red): Expected type 'SpecificCLS', got 'int' instead
PyCharm Screenshot
如果您查看这一行,您会注意到没有显示错误。
cls.integer = SpecificCLS() # PyCharm does NOT show any error/warning that a class is assigned into an variable that is declared as an "int"
如果我们使用 setter 方法来赋值,pycharm 会正确识别错误的赋值。
cls.set_im_int(SpecificCLS()) # PyCharm recognise an error (underlined red): Expected type 'int', got 'SpecificCLS' instead
那么谁能告诉我为什么 setter 的类型检查工作得很好,但其他分配却不行?
到目前为止,我一直使用 getter/setter 来验证我是否会为彼此分配正确的类型。因此我用'__'标记了私有字段,这样没有人可以直接更改状态。 由于我已经从 python 3.5.x 更新到 3.7.x,我认为我可以删除这个样板代码。我想要那种静态类型检查功能,但我不想强迫我一直使用 getter/setter。
感谢您的帮助。
最好的问候
2020 年 11 月 18 日更新:12:00 很抱歉这个误导性的例子。我试图编辑剪辑并希望问题现在很清楚。我还尝试更详细地解释我在 pycharm 的执行/性能中看到的问题。我还添加了更新的屏幕截图。
【问题讨论】:
这能回答你的问题吗? Mypy doesn't throw an error when mixing booleans with integers 【参考方案1】:Pycharm 和 mypy 都是正确的,因为 bool 派生自 int,并且通过表明您想要一个 int,您接受任何类型派生自 int 的变量。
您可以通过 issubclass(bool, int)
验证 bool 是从 int 派生的
【讨论】:
感谢您的快速回复。我根据您的说明更新了我的问题。【参考方案2】:在@Sylvaus 的帮助下,我找出了问题所在并找到了解决方案。
PyCharm 无法识别出违反 PEP-526 的行为,但 mypy 正确识别! 通过
安装Mypy插件文件 -> 设置 -> 插件
如果你运行 mypy,它会告诉你现在有错误。但是需要一些时间才能触发 pycharms 分析器并显示 mypy 的结果。
我将尝试将分析器绑定到代码格式快捷方式。如果我能做到,我会更新这篇文章。
编辑: 感谢user2235698,这是来自jetbrains https://youtrack.jetbrains.com/issue/PY-36889的issue
【讨论】:
这不是真的,PyCharm 自 2016 年以来 (youtrack.jetbrains.com/issue/PY-20744) 就支持 PEP 526,请在类级别上注释您的属性,所有预期的警告都会引发。 @user2235698 为什么它无法识别上例中的违规行为?为什么我应该使用类变量而不是实例变量? 不会是类变量,例如:class MyClass: integer: int
,会是类级别的注解
嗯。我试过了,但 PyCharm 类型检查器仍然没有警告。 Mypy 确实向我显示了警告。
对不起,你是对的:youtrack.jetbrains.com/issue/PY-36889以上是关于Pycharm 静态类型检查器失败的主要内容,如果未能解决你的问题,请参考以下文章