Skip to content

Unpacking iterable into arguments fails in call to static method or class method #1076

@aatle

Description

@aatle

Unpacking an iterable to be used as arguments compiles into incorrect code under certain circumstances.
Conditions:

  • A call uses unpacking of an iterable for arguments: eggs(*stuff)
  • The call is to a staticmethod or classmethod of a class
  • The method is accessed via the class: Cls.method(), instead of through an instance: Cls().method()

The compilation of the module succeeds, but upon execution of it, it's clear that the compiled code has different behavior.

Results:
It seems that the compiled code neglects to unpack the iterable, instead passing the entire iterable as a single argument to the method. This results in a TypeError at runtime as the method expected items of the iterable, not the iterable itself.

Example code:

class Foo:
  def instance(self, a: int, b: int) -> None:
    pass

  @staticmethod
  def static(a: int, b: int) -> None:
    pass

  @classmethod
  def cls(cls, a: int, b: int) -> None:
    pass


Foo().instance(1, 2)
Foo().static(1, 2)
Foo().cls(1, 2)
Foo.static(1, 2)
Foo.cls(1, 2)

things: list[int] = [1, 2]
Foo().instance(*things)
Foo().static(*things)
Foo().cls(*things)
Foo.static(*things)  # TypeError: int object expected; got list
Foo.cls(*things)  # TypeError: int object expected; got list

keys: tuple[int, int] = 1, 2
Foo().instance(*keys)
Foo().static(*keys)
Foo().cls(*keys)
Foo.static(*keys)  # TypeError: int object expected; got tuple[int, int]
Foo.cls(*keys)  # TypeError: int object expected; got tuple[int, int]
$ python -c "import test"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
    import test
  File "test.py", line 24, in <module>
    Foo.static(*things)
TypeError: int object expected; got list

(Expected: no error upon running)

Environment:
Mypy version used: 1.13.0 (compiled)
Mypy command-line flags: none
Mypy configuration options from mypy.ini (and other config files): none
Python version used: 3.13.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions