程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

PyCharm typing warning inconsistency for abstract base classes

发布于2025-01-05 09:05     阅读(427)     评论(0)     点赞(8)     收藏(0)


In the following code, PyCharm is issuing a typing warning for Base.foo ("Expected to return 'int', got no return") but not for Base.bar, which has exactly the same typing hint and return type:

import abc

class Base(abc.ABC):
    @abc.abstractmethod
    def foo(self) -> int:
        print('fooing')
        pass

    @abc.abstractmethod
    def bar(self) -> int:
        pass

class Derived(Base):
    def foo(self) -> int:
        return 42

    def bar(self) -> int:
        return 42

In practice, neither Base.foo nor Base.bar can be called directly, so I'd expect no typing warnings at all there. If, on the other hand, one were to return super().foo() in Derived.foo, then a typing warning should indeed be issued, but the same should apply for Derived.bar so I still don't understand why the different behavior. Can someone explain, or is this a bug in PyCharm?


解决方案


Base.foo can be called, from an otherwise correct override of foo. Your type checker isn't tracing the execution of your code to ensure that Base.foo isn't called: you could have code like

class Derived2(Base):
    def foo(self) -> int:
        return 42 + super().foo()

which requires Base.foo to return an int.

Yes, Base.bar could also be called in the same way, but the empty body implies that there is no reason to do so. The type-checker special case that allows the empty abstract method to violate its typing is necessary because the ABC mechanism provides no way to separate the "declaration" of an abstract method from a definition. The only workaround to avoid the need for the special case would be to inject an annotated name directly into the private __abstractmethods__ attribute (which is essentially all the abstractmethod decorator does)

class Base(ABC):
    bar: Callable[[], int]

Base.__abstractmethods__.append("bar")

(The above is not tested, and it may not work even with additional tweaking. But I think we'd agree that this isn't something we'd want to write, hence the special handling by type checkers. In the end, Python-the-language has no support for base classes; it's provided entirely by a library module, and one designed long before type-checking was a thing to consider.)



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:https://www.pythonheidong.com/blog/article/2046778/b02f37379568a250e08e/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

8 0
收藏该文
已收藏

评论内容:(最多支持255个字符)