In the code below, print_pos accepts one argument which can be of
three different types.
from typing import List, Tuple, Union
pos_t = Tuple[int, int]
anchor_t = Tuple[str, str]
anchor_pos_t = Tuple[anchor_t, pos_t]
def print_pos(
pos: Union[
pos_t,
anchor_pos_t,
List[Union[pos_t, anchor_pos_t]]
]
) -> None:
if isinstance(pos, tuple) and isinstance(pos[0], int):
print('xy =', pos)
elif isinstance(pos, tuple) and isinstance(pos[0], tuple):
print('anchor =', pos[0])
print('xy =', pos[1])
elif isinstance(pos, list):
print('[')
for p in pos:
print_pos(p)
print(']')
else:
raise ValueError('invalid pos')
print_pos((0, 100))
print_pos((('right', 'bottom'), (0, 100)))
print_pos([
(0, 100),
(('right', 'bottom'), (0, 100))
])
Right now, I use isinstance to check for the different possibilities
for the type of pos but I find the code rather clumsy. Is there a
more convenient/elegant way to do that? In particular is there a mean
to reuse types I defined (pos_t, anchor_t, anchor_pos_t) in my type check?