I've encountered a problem with argument highlighting while unpacking a class into a function: Python can't figure out amount of arguments I want to provide while unpacking a class
Let's say we have a function:
def somefunc(attr1, attr2, a,b,c,d,e,f):
pass
I want to unpack an object and expect vs code to know the object unpacks to 2 arguments. It works just fine with tuples (VS Code knows the size of tuple and highlights the next argument):
data1 = ("Hello", "World")
somefunc(*data1,1,2,3,4,5,6)
but I want to unpack classes as well:
class foo:
attr1: str
attr2: str
def __init__(self, attr1, attr2):
self.attr1 = attr1
self.attr2 = attr2
def empty():
return foo(None,None)
def __iter__(self):
return iter((self.attr1, self.attr2))
When I try to write some code with this implementation:
data2 = foo("Hello", "World")
somefunc(*data2,1,2,3,4,5,6)
it doesn't work:
What can I do to fix this? Is it a code highlighter problem, or it can be fixed with some type annotations and tricks?
I am using "pylance, python, python debugger" extensions from Microsoft for my Python code
In general, with static analysis stuff like this, you need to put yourself in the shoes of the static analysis tooling and the implementors of that tooling. julaine's comment hits the nail on the head of how to think:
I guess the trouble is knowing how many elements
__iter__
is going to return, and while it is obvious in your case, it is generally impossible to tell, even with type annotations. Since the most common reason to implement__iter__
is to program a collection-like-class, it might be that no part of vscode considered your special case important enough to implement. But I am just speculating on that last part.
That being said, it does seem that Pylance takes length information into account from this section of the release notes, but from testing with an implmentation of __len__
that returns 2
, I don't think Pylance supports that either.
I think that wording in the release notes is about well-known iterable types like lists and tuples.
You can get what you want from Pylance if you switch to this:
from typing import Tuple
class foo(Tuple[str,str]):
, which I think is thanks to a change made in Pylance 1.1.63, but extending Tuple is not a trivial type change.
Hopefully I'm not missing something, but I'm not a regular Python dev, so I likely am.
If you want something different, you may want/need to raise a feature-request issue ticket.
Fun fact: you can see analogous discussion/info in this answer to Declaring length of tuples in Python typing, which is about mypy (which is not relevant here, since Pylance uses Pyright).