pythonpycharminspection

PyCharm inspection doesn't show warnings for my own class in type annotaitions


Here is my code. It works. Pay attention to lines A and B.

from dataclasses import dataclass, field, InitVar
import datetime
from typing import List, Optional

@dataclass
class Book:
    author: str = 'no data'
    title: str = 'no data'

@dataclass
class Library:
    name: str = 'no data'
    books: List[Book] = field(default_factory=list)  # line A - books attribute type annotation
    gen_time: InitVar[bool] = True
    creation_timestamp: Optional[str] = None

    def __post_init__(self, gen_time):
        if gen_time:
            self.creation_timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

def main():

    b_1 = Book('J. Mouse', 'Beautiful mice')
    b_2 = Book('M. Catling', 'Magic kittens')
    b_3 = Book('A. Dogg', 'Tasty Dogs')
    print(b_1, b_2, b_3)

    bb_1 = Library('My library', gen_time=False)
    bb_1.books.extend([bb_1, b_2, b_3, 1])  # line B - add books and not books to newly created empty library
    print(bb_1)


if __name__ == '__main__':
    main()

Line A says that books attrbute should be a list containing Book objects. In line B I add Book, Library, and int into books. PyCharm doesn't tell me if this is a problem.

However, if I modify line A slightly books: List[str] = field(default_factory=list) (Book <-> str) then PyCharm gives the following very useful warning:

Expected type 'Iterable[str]' (matched generic type 'Iterable[_T]'), got 'List[Union[Library, Book, int]]' instead

So, why does PyCharm inspection behaves differently in these two cases? How can I see the warning with the original code?

P.S. Win10 / Python 3.7 / PyCharm Community Edition 2019.2 without any modifications/addons.


Solution

  • Inferred type of [bb_1, b_2, b_3, 1] is List[Union[Library, Book, int]], and it matches expected type in the following way:

    1. Container types are the same, List in both cases
    2. Actual value type Union[Library, Book, int] contains expected Book type -- here type checker is satisfied and says nothing.

    It's a bug in PyCharm type system.