From f4c65480697d58a4184d564f7d62c90656e7f3a7 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Tue, 12 Aug 2025 15:39:58 -0700 Subject: [PATCH 1/2] Fix inference when unpacking union type --- mypy/argmap.py | 13 +++++++++++++ test-data/unit/check-functions.test | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/mypy/argmap.py b/mypy/argmap.py index 28fad1f093dd..3bb48fefa9d2 100644 --- a/mypy/argmap.py +++ b/mypy/argmap.py @@ -17,6 +17,7 @@ TypeOfAny, TypeVarTupleType, UnpackType, + UnionType, get_proper_type, ) @@ -211,6 +212,18 @@ def expand_actual_type( # Just return `Any`, other parts of code would raise # a different error for improper use. return AnyType(TypeOfAny.from_error) + elif isinstance(actual_type, UnionType): + item_types = [ + self.expand_actual_type( + item, + actual_kind=actual_kind, + formal_name=formal_name, + formal_kind=formal_kind, + allow_unpack=allow_unpack, + ) + for item in actual_type.items + ] + return UnionType.make_union(item_types) elif isinstance(actual_type, TupleType): # Get the next tuple item of a tuple *arg. if self.tuple_index >= len(actual_type.items): diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index 7fa34a398ea0..683d9c90ee22 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -3708,3 +3708,20 @@ foo(*args) # E: Argument 1 to "foo" has incompatible type "*list[object]"; expe kwargs: dict[str, object] foo(**kwargs) # E: Argument 1 to "foo" has incompatible type "**dict[str, object]"; expected "P" [builtins fixtures/dict.pyi] + +[case testUnpackUnionStarArgs] +from __future__ import annotations +from typing import TypeVar +T = TypeVar("T") + +def f(*args: T) -> T: ... + +def star_union_list(x: list[str | None] | list[str]): + reveal_type([*x]) # N: Revealed type is "builtins.list[Union[builtins.str, None]]" + reveal_type(f(*x)) # N: Revealed type is "Union[builtins.str, None]" + +def star_union_list_tuple(x: list[str | None] | tuple[int, int]): + reveal_type([*x]) # N: Revealed type is "builtins.list[Union[builtins.str, None, builtins.int]]" + reveal_type(f(*x)) # N: Revealed type is "Union[builtins.str, None, builtins.int]" + +[builtins fixtures/tuple.pyi] From 7fd1d1a1d46a665f742d3c0e2910983eff09768f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 22:48:04 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mypy/argmap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/argmap.py b/mypy/argmap.py index 3bb48fefa9d2..363d76cb7322 100644 --- a/mypy/argmap.py +++ b/mypy/argmap.py @@ -16,8 +16,8 @@ TypedDictType, TypeOfAny, TypeVarTupleType, - UnpackType, UnionType, + UnpackType, get_proper_type, )