Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 323
Soto Avatar asked Jul 23 '20 14:07

Soto


2 Answers

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.

like image 155
ssfdust Avatar answered Oct 23 '22 18:10

ssfdust


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.

like image 44
Joscha Götzer Avatar answered Oct 23 '22 19:10

Joscha Götzer