com2ann icon indicating copy to clipboard operation
com2ann copied to clipboard

Support tuple types comments

Open ilevkivskyi opened this issue 3 years ago • 2 comments

We should support translating type comments like this:

x, y = ...  # type: Tuple[int, int]

Note this may be not totally trivial in r.h.s. is a single expression (not a tuple). In this case we may need to add annotations before assignment, like this

x: int
y: int
x, y = v

ilevkivskyi avatar Mar 09 '22 10:03 ilevkivskyi

I'm interested in having a go at this. To that end I've had a quick look at what's involved and it turns out to be even more complicated than it first appears.

In addition to the expected forms:

a, b = ...  # type: str, int
c, d = ...  # type: (str, int)
x, y = ...  # type: Tuple[str, int]

There are also a number of other forms which seem to work but which are going to be a lot more complicated to unpack:

from typing import Any, NamedTuple

SomeAlias = Tuple[str, int]
class NT(NamedTuple):
    _x: str
    _y: int

src: Any = object()

(a, b) = src  # type: (str, int), (str, int)
(c, d) = src  # type: SomeAlias
(e, f) = src  # type: NT

(r, s), (t, u) = src  # type: (str, int), (str, int)

reveal_type(a)  # Revealed type: Tuple[str, int]
reveal_type(b)  # Revealed type: Tuple[str, int]

reveal_type(c)  # Revealed type: str
reveal_type(d)  # Revealed type: int

reveal_type(e)  # Revealed type: str
reveal_type(f)  # Revealed type: int

reveal_type(r)  # Revealed type: str
reveal_type(s)  # Revealed type: int
reveal_type(t)  # Revealed type: str
reveal_type(u)  # Revealed type: int

The complexity for some of these is that what makes a valid comment type doesn't always become a valid type. In fact I suspect these are already a bug (if the comments here were processed by com2ann)?

# These are all syntax errors, either straight up or from mypy

m = ...  # type: (str, int)
n = ...  # type: str, int

z: (str, int)

reveal_type(z)

My current thinking is that we want to construct a pair of trees of values in the left hand side and the type comment respectively and then walk both trees to marry up the parts. That would then allow for the construction of the preceding annotation declarations.

What I'm not sure about is how to handle the case where there's something that we cannot match up the trees (the named alias case feels the most likely). Do we want to just throw an error and fail the whole file? Or is there a way to reject this one statement and undo the changes that may have already happened? Or do we need to detect these cases upfront so they don't fail later?

PeterJCLaw avatar Sep 09 '22 18:09 PeterJCLaw

Sorry for long silence. Yeah, I think it would be great to support this. I don't think we need to cover all the cases, if we can't handle some annotation (if there is e.g. a type alias) we can print an error message, and skip it. The user can then look at the log, and fix remaining items manually. IIRC this is what we do in other cases where we can't handle a type comment.

ilevkivskyi avatar Dec 24 '22 12:12 ilevkivskyi