PyCharm对重写的__floordiv__类型推断异常及类型标注疑问
问题解析
代码示例
class A(int): def __floordiv__(self, *args, **kwargs) -> "A": return A(super().__floordiv__(*args, **kwargs)) def __mod__(self, *args, **kwargs): return A(super().__mod__(*args, **kwargs)) # 无论是否重写此方法结果都相同 def __new__(cls, *args, **kwargs): return super().__new__(cls, *args, **kwargs) a = A(3) b = a // 2
疑问解答
1. 为何b的类型被识别为Union[A, int]?
PyCharm的类型推断引擎在此处存在逻辑偏差。尽管你明确让__floordiv__返回A实例,但引擎仍会参考父类int的__floordiv__签名(父类返回int),再加上你用*args, **kwargs覆盖所有签名的写法,导致引擎无法精准判定返回类型,最终给出Union[A, int]的模糊推断结果。
另外可以确定的是,//只会调用__floordiv__方法,不存在调用其他魔法方法的情况,问题核心在于PyCharm的类型推断逻辑。
2. 为什么__floordiv__必须加-> "A"标注?未加标注的__mod__返回类型被识别为int?
Python类型推断默认会继承父类方法的返回类型。int的__mod__返回类型为int,如果不给重写的__mod__添加返回类型标注,PyCharm会直接沿用父类的返回类型,因此显示为int。而__floordiv__添加-> "A"标注后,引擎会优先参考你指定的返回类型,但受限于前面提到的推断偏差,还是出现了Union的情况。
3. 这是PyCharm的Bug吗?如何反馈?
这属于PyCharm类型推断的缺陷,属于Bug范畴。你可以通过PyCharm内置渠道提交反馈:打开PyCharm,点击顶部菜单栏的Help -> Submit Feedback,按照指引填写问题详情、代码示例和版本信息即可。
内容的提问来源于stack exchange,提问作者M. Zoller




