【问题标题】:Inheriting from a generic abstract class with a concrete type parameter is not enforced in PyCharm在 PyCharm 中不强制从具有具体类型参数的通用抽象类继承
【发布时间】:2020-11-13 07:33:28
【问题描述】:

背景:我正在使用 PyCharm 2019.1 和 Python 3.7

问题:我想创建一个泛型抽象类,这样当我从它继承并将泛型类型设置为具体类型时,我希望继承的方法能够识别具体类型并且如果类型不匹配,则显示警告。

带有子类的通用 ABC

from abc import ABC, abstractmethod
from typing import TypeVar, Generic

T = TypeVar("T")


class FooGenericAbstract(ABC, Generic[T]):

    @abstractmethod
    def func(self) -> T:
        pass


class Foo(FooGenericAbstract[dict]):  # I am specifying T as type dict

    def func(self) -> dict:  # I would like the return type to show a warning, if the type is incorrect
        pass

错误类型没有警告

我预计这里会出错,因为返回类型 list 与具体类型参数 dict 不匹配。

class Foo(FooGenericAbstract[dict]):  # I am specifying T as type dict

    def func(self) -> list:  # Should be a warning here!
        pass

【问题讨论】:

    标签: python generics inheritance abstract-class


    【解决方案1】:
    from abc import ABC, abstractmethod
    from typing import Dict, Generic, List, TypeVar
    
    T = TypeVar("T")
    
    
    class FooGenericAbstract(ABC, Generic[T]):
    
        @abstractmethod
        def func(self) -> T:
            pass
    
    
    class Foo(FooGenericAbstract[Dict[str, int]]): 
    
        def func(self) -> Dict[str, str]:
            pass
    

    使用 coc.nvim 和 python 3.8,mypy 0.770 会按预期发出警告。

    我想也许你应该使用类型提示而不是内置类型,因为 mypy 直到现在都无法识别内置类型。

    【讨论】:

      【解决方案2】:

      一般而言,PyCharm 对类型提示的支持非常弱,因此始终建议您依赖 the Mypy plugin available in the JetBrains marketplace

      您的示例是显式注释默默地覆盖基类指定的类型的情况之一,即使使用typing 模块中的大写ListDict 类型也是如此。使用 Mypy 插件会引发错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-08
        • 2017-02-23
        • 2011-12-28
        • 2021-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-27
        相关资源
        最近更新 更多