Soto
Soto

Reputation: 679

Inheriting from a generic abstract class with a concrete type parameter is not enforced in PyCharm

Background: I am using PyCharm 2019.1 and Python 3.7

Question: I would like to create a generic abstract class, such that when I inherit from it and set the generic type to a concrete type, I want the inherited methods to recognize the concrete type and show a warning if the types do not match.

Generic ABC with Subclass

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

No warning for incorrect type

I would expect an error here, since the return type list does not match the concrete type parameter dict.

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

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

Upvotes: 14

Views: 14992

Answers (2)

Joscha Götzer
Joscha Götzer

Reputation: 664

PyCharm has very weak support for type hints in general, so always be advised to rely on the Mypy plugin available in the JetBrains marketplace.

Your example is one of those cases where explicit annotations silently override the types specified by the base class, even when using the uppercase List and Dict types from the typing module. It raises an error as expected using the Mypy plugin.

Upvotes: 2

ssfdust
ssfdust

Reputation: 156

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

With coc.nvim and python 3.8, mypy 0.770 warns as expected.

I guess maybe you should use type hints instead of built-in types, since mypy cannot recognize the built-in types until now.

Upvotes: 11

Related Questions