0

I am trying (as an exercise) to type Curio's source code, but I have stumbled on a problem with its variable length tuples in the yielding parts of the code.

Curio's traps yield to the kernel a tuple of a known length, but the traps yield different lengths of tuples than each other.

For example, the curio.traps._read_wait(fileobj) yields a 4-tuple of type Tuple[int, int, int, str] whereas curio.traps._spawn(coro) yields a 2 tuple of type Tuple[int, Coroutine].

The similarity between all their yield types is that the first item is always an int but the rest have type Any.

In the kernel, when it runs the coroutine to the next yield point, it expects an int as the first item and Anys after that. I was expecting Tuple[int, Any, ...] to maaybe work, but it gives an error saying that the ... was unexpected.

from typing import Tuple, Any

# Test code
vltuple: Tuple[int, Any, ...] = (1, 2)
vltuple = (1, 2, 3)
vltuple = (1, 'a', 'b')
vltuple = (1, [], 4.5)

Here are the exact error messages:

____.py:4: error: Unexpected '...'

____.py:4: error: Incompatible types in assignment (expression has type "Tuple[int]", variable has type "Tuple[int, Any, Any]")

GeeTransit
  • 1,458
  • 9
  • 22
  • 1
    According with [this answer](https://stackoverflow.com/questions/54747253/how-to-annotate-function-that-takes-a-tuple-of-variable-length-in-python) there can only be annotated _Arbitrary-length homogeneous tuples_ as you see in [PEP484](https://www.python.org/dev/peps/pep-0484/#id49) you cannot find any other reference to _Arbitrary-length_. It should be some hack but i recommend you to strip into 2 variables – Ivan Gonzalez Jun 23 '19 at 02:41
  • How would one do that? Sorry about this. I'm pretty inexperienced in typing things. EDIT: Ah, you mean by doing `key: int; args: tuple; key, *args = vltuple`. – GeeTransit Jun 23 '19 at 02:46
  • The first value of the tuple which will always be an int save it in other variable – Ivan Gonzalez Jun 23 '19 at 02:48
  • Thanks so much. By changing it to `key: int; args: list; key, *args = (1, "a", b"b")`, mypy doesn't complain. Have a good day :D – GeeTransit Jun 23 '19 at 02:51
  • Post the solution and mark it as answered. :) – Ivan Gonzalez Jun 23 '19 at 02:53

1 Answers1

1

As I commented:

According with this answer, there can only be annotated Arbitrary-length homogeneous tuples as you see in PEP484 you cannot find any other reference to Arbitrary-length. It should be some hack but i recommend you to strip into 2 variables

i.e.

Solution:

key: int
args: list

key, *args = (1, 2)
key, *args = (1, 2, 3)
key, *args = (1, 'a', 'b')
key, *args = (1, [], 4.5)

By using extended unpacking you type and assign a fixed amount of variables (in this case one, just key) and the extra elements are put into another variable that can be typed individually

Ivan Gonzalez
  • 446
  • 1
  • 5
  • 14