'Confusing type warning when constructing list with Union contents

Consider this example:

from typing import Union


def f(xs: list[Union[type, str]]):
    pass


f(([int] * 2) + [int, ' ', str])
f(([int] * 3) + [' ', str])
f(([int] * 3) + [' ', int])

I would consider the first two calls to f() to be equivalent. But PyCharm flags the second one with a warning: "Expected type 'list[Type[int]]' (matched generic type 'list[_T]'), got 'list[str | Type[str]]' instead"

As if to further confuse me, the third call does not have this issue.

Am I missing some type hint subtlety here, or is it PyCharm that's making a mistake? (in which case I'll go and file a bug report)

I got the sense that PyCharm is too trigger-happy to decide that, apparently, we're dealing with a list of types, which matches the required list[Union[type, str]], but then forgets that this is the actual requirement and then stumbles when the next list starts with a string (which is of course not a type). But if that were the case, it makes no sense that the third statement works...

Of course the code above is not trying to achieve anything, this is just the minimal example that I could come up with that displays behaviour I'm seeing in actual code, where it actually makes sense for me to pass a list of mixed strings and types.

It seems that the problem only occurs if there's a mismatch between the types in the two halves of the concatenation, because this is fine:

f(([str] * 3) + [' ', str])


Solution 1:[1]

The issue has been reported as https://youtrack.jetbrains.com/issue/PY-53036

I'll update and accept this answer if the outcome requires some change in settings, or I'll delete the question if the issue is simply fixed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Grismar