ty icon indicating copy to clipboard operation
ty copied to clipboard

Emit error when unpacking a not-iterable argument in a call

Open phistep opened this issue 1 week ago • 3 comments

Summary

from typing import Generic, TypeAlias, TypeVar


def foo(a: str, b: int, c: int, d: str): ...


VType: TypeAlias = int | tuple[int, int]
V = TypeVar("V", bound=VType)


class Foo(Generic[V]):
    v: V

    def __init__(self, v: V):
        self.v = v


D = dict(
    a=Foo(v=1),
    b=Foo(v=(2, 2)),
)
foo("foo", *D["b"], d="bar")

reports

error[parameter-already-assigned]: Multiple values provided for parameter `d` of function `foo`
  --> src/vhsh/test.py:22:21
   |
20 |     b=Foo(v=(2, 2)),
21 | )
22 | foo("foo", *D["b"], d="bar")
   |                     ^^^^^^^
   |
info: rule `parameter-already-assigned` is enabled by default

Found 1 diagnostic

when actually d is only passed once and D["b"] is unpacked into b and c.

This is similar to #2250 and #1985 but produces an error message and not only misleading inlays.

Image
foo("foo", D["b"][0], D["b"][1], d="bar")

gives the expected[^1] errors

error[non-subscriptable]: Cannot subscript object of type `Foo[int]` with no `__getitem__` method
  --> src/vhsh/test.py:22:12
   |
20 |     b=Foo(v=(2, 2)),
21 | )
22 | foo("foo", D["b"][0], D["b"][1], d="bar")
   |            ^^^^^^^^^
   |
info: rule `non-subscriptable` is enabled by default

error[non-subscriptable]: Cannot subscript object of type `Foo[tuple[int, int]]` with no `__getitem__` method
  --> src/vhsh/test.py:22:12
   |
20 |     b=Foo(v=(2, 2)),
21 | )
22 | foo("foo", D["b"][0], D["b"][1], d="bar")
   |            ^^^^^^^^^
   |
info: rule `non-subscriptable` is enabled by default

error[non-subscriptable]: Cannot subscript object of type `Foo[int]` with no `__getitem__` method
  --> src/vhsh/test.py:22:23
   |
20 |     b=Foo(v=(2, 2)),
21 | )
22 | foo("foo", D["b"][0], D["b"][1], d="bar")
   |                       ^^^^^^^^^
   |
info: rule `non-subscriptable` is enabled by default

error[non-subscriptable]: Cannot subscript object of type `Foo[tuple[int, int]]` with no `__getitem__` method
  --> src/vhsh/test.py:22:23
   |
20 |     b=Foo(v=(2, 2)),
21 | )
22 | foo("foo", D["b"][0], D["b"][1], d="bar")
   |                       ^^^^^^^^^
   |
info: rule `non-subscriptable` is enabled by default

Found 4 diagnostics
Image

[^1]: sadly unsatisfactory due to impossible type inference w/o TypedDict.

Version

ty 0.0.7 (cf82a04b5 2025-12-24)

phistep avatar Dec 28 '25 23:12 phistep