-
Notifications
You must be signed in to change notification settings - Fork 48
Closed
python/mypy
#18228Description
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
Labels
No labels