baxx
baxx

Reputation: 4745

Typehint a list of tuples with nested tuples in python

I'm trying to type hint the following:

from typing import *

x = [('a',), (('b',), ('c', 'd'))]

f( k : list[ tuple[str] | tuple[str, tuple[str]]]):
    print(k)

and am unsure how to type-hint for this list.

Upvotes: 2

Views: 4448

Answers (1)

KonstantinosKokos
KonstantinosKokos

Reputation: 3473

Given your example, the correct annotation for a recursive data type would require a forward reference and look like:

Tstr = tuple[str, ...] | tuple['Tstr', 'Tstr'] 

meaning that an Tstr is either a variadic tuple of str or a nested tuple containing a Tstr on each coordinate.

Example inhabitants would be

('b',)                           # B1: base case with 1 element -- tuple[str] 
('c', 'd')                       # B2: base case with 2 elements -- tuple[str, str]
(('b',), ('c', 'd'))             # inductive case of tuple[B1, B2]
(('c', 'd'), ('b',))             # inductive case of tuple[B2, B1]
((('b',), ('c', 'd')), ('b',))   # inductive case of tuple[tuple[B2, B1], B1]
...

etc.

list[Tstr] is then a perfectly fine type hint (if its purpose is just hinting), but it won't pass type checking by mypy (see this issue).

If you want any of the available python type checkers to not complain, you need to settle for a simplified version i.e. set an upper boundary to the induction and explicitly specify allowed variants (e.g. Tstr = tuple[str, ...] | tuple[tuple[str, ...], tuple[str, ...]]).

Upvotes: 1

Related Questions