Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion mypy/checkexpr.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,10 @@ def visit_call_expr_inner(self, e: CallExpr, allow_none_return: bool = False) ->
and not node.node.no_args
and not (
isinstance(union_target := get_proper_type(node.node.target), UnionType)
and union_target.uses_pep604_syntax
and (
union_target.uses_pep604_syntax
or self.chk.options.python_version >= (3, 10)
)
)
):
self.msg.type_arguments_not_allowed(e)
Expand Down
27 changes: 27 additions & 0 deletions test-data/unit/check-unions.test
Original file line number Diff line number Diff line change
Expand Up @@ -1345,3 +1345,30 @@ x: Union[C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11]
y: Union[C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, None]
x = y # E: Incompatible types in assignment (expression has type "Union[C1, C2, C3, C4, C5, <6 more items>, None]", variable has type "Union[C1, C2, C3, C4, C5, <6 more items>]") \
# N: Item in the first union not in the second: "None"

[case testTypeAliasWithOldUnionIsInstance]
# flags: --python-version 3.10
from typing import Union
SimpleAlias = Union[int, str]

def foo(x: Union[int, str, tuple]):
# TODO: fix the typeshed stub for isinstance
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this fixable in typeshed? I don't think the correct type is expressible.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah the correct type isn't expressible, but if we change typeshed to include _SpecialForm here https://github.com/python/typeshed/blob/b6e21d05aec7ff1444ffc109c7d31d2f5bb28dbd/stdlib/builtins.pyi#L1537 or attempt to type more of the union runtime impl or just give up and make it use object, I think that will make the remaining error here go away

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was tried in python/typeshed#7508 and the consensus seemed to be that it wasn't worth it?

I wouldn't mind the stubs reflecting the runtime a bit more closely w.r.t. the various special forms though; it would mean less special casing in ty too, which would be nice

if isinstance(x, SimpleAlias): # E: Argument 2 to "isinstance" has incompatible type "<typing special form>"; expected "type"
reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str, builtins.tuple[Any, ...]]"
else:
reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str, builtins.tuple[Any, ...]]"
[builtins fixtures/tuple.pyi]


[case testTypeAliasWithOldUnionIsInstancePython39]
# flags: --python-version 3.9
from typing import Union
SimpleAlias = Union[int, str]

def foo(x: Union[int, str, tuple]):
if isinstance(x, SimpleAlias): # E: Parameterized generics cannot be used with class or instance checks \
# E: Argument 2 to "isinstance" has incompatible type "<typing special form>"; expected "type"
reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str, builtins.tuple[Any, ...]]"
else:
reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str, builtins.tuple[Any, ...]]"
[builtins fixtures/tuple.pyi]
Loading