OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Python type annotation for return values of the same length than *args but different type

  • Thread starter Thread starter mgab
  • Start date Start date
M

mgab

Guest
Python supports defining functions that take a variable-length sequence of arguments with *args. The type annotation in those cases is expected to describe the type of the individual elements in the sequence. But how can one describe the return type of the function if its length is supposed to depend on the length of args and the type of the elements is arbitrary?

Let's consider how we could annotate the output type in the following dubiously useful function:

Code:
def add_one_and_to_str(*args):
    return tuple(str(i+1) for i in args)

Attempt 1: Sequence


One option might be to use Sequence. For example, one can do

Code:
from typing import Sequence

def add_one_and_to_str(*args: int) -> Sequence[str]:
    return tuple(str(i+1) for i in args)

This kind of works, but it is loosing information: we know that return type will not be just any sequence of strings but specifically a tuple, and precisely of the same length than the number of arguments provided.

Attempt 2: TypeVarTuple


As an alternative, Python 3.11 introduces TypeVarTuple, which conceptually, can be thought of as a tuple of type variables (T1, T2, ...).

So you can use it like

Code:
from typing import Sequence, TypeVarTuple

Ts = TypeVarTuple('Ts')

def make_tuple(*args: *Ts) -> Tuple[*Ts]:
    return args

This correctly propagates the information about the length of the tuple. However, you cannot restrict the input types because type bounds are still not supported for TypeVarTuple (so you would accept Any). But more importantly this seems to be useful in this case only to use the exact same types in the outputs than in the input.

Thus, it doesn't seem to be useful in the case discussed her.

Open question​


How could the first function be correctly annotated specifying that the output will be a tuple of strings with the same number of elements than integers were provided as function arguments? Any idea?

Thanks!
<p>Python supports defining functions that take a variable-length sequence of arguments with <code>*args</code>. The type annotation in those cases is expected to describe the type of the individual elements in the sequence. But how can one describe the return type of the function if its length is supposed to depend on the length of <code>args</code> and the type of the elements is arbitrary?</p>
<p>Let's consider how we could annotate the output type in the following dubiously useful function:</p>
<pre class="lang-py prettyprint-override"><code>def add_one_and_to_str(*args):
return tuple(str(i+1) for i in args)
</code></pre>
<h4>Attempt 1: <code>Sequence</code></h4>
<p>One option might be to use <code>Sequence</code>. For example, one can do</p>
<pre class="lang-py prettyprint-override"><code>from typing import Sequence

def add_one_and_to_str(*args: int) -> Sequence[str]:
return tuple(str(i+1) for i in args)
</code></pre>
<p>This kind of works, but it is loosing information: we know that return type will not be just any sequence of strings but specifically a tuple, and precisely of the same length than the number of arguments provided.</p>
<h4>Attempt 2: <code>TypeVarTuple</code></h4>
<p>As an alternative, Python 3.11 introduces <a href="https://docs.python.org/3/library/typing.html#typing.TypeVarTuple" rel="noreferrer">TypeVarTuple</a>, which conceptually, can be thought of as a tuple of type variables (T1, T2, ...).</p>
<p>So you can use it like</p>
<pre class="lang-py prettyprint-override"><code>from typing import Sequence, TypeVarTuple

Ts = TypeVarTuple('Ts')

def make_tuple(*args: *Ts) -> Tuple[*Ts]:
return args
</code></pre>
<p>This correctly propagates the information about the length of the tuple. However, you cannot restrict the input types because <a href="https://peps.python.org/pep-0646/#variance-type-constraints-and-type-bounds-not-yet-supported" rel="noreferrer">type bounds are still not supported</a> for <code>TypeVarTuple</code> (so you would accept <code>Any</code>). But more importantly this seems to be useful in this case only to use the exact same types in the outputs than in the input.</p>
<p>Thus, it doesn't seem to be useful in the case discussed her.</p>
<h4>Open question</h4>
<p>How could the first function be correctly annotated specifying that the output will be a tuple of strings with the same number of elements than integers were provided as function arguments? Any idea?</p>
<p>Thanks!</p>
 

Latest posts

U
Replies
0
Views
1
user2774120
U
P
Replies
0
Views
1
Pramod Karandikar
P
Top