|
| 1 | +"""Example of code generation approach to variadics. |
| 2 | +
|
| 3 | +See https://github.com/python/typing/issues/193#issuecomment-236383893 |
| 4 | +""" |
| 5 | + |
| 6 | +LIMIT = 5 |
| 7 | +BOUND = 'object' |
| 8 | + |
| 9 | +def prelude(limit: int, bound: str) -> None: |
| 10 | + print('from typing import Callable, Iterable, Iterator, Tuple, TypeVar, overload') |
| 11 | + print('Ts = TypeVar(\'Ts\', bound={bound})'.format(bound=bound)) |
| 12 | + print('R = TypeVar(\'R\')') |
| 13 | + for i in range(LIMIT): |
| 14 | + print('T{i} = TypeVar(\'T{i}\', bound={bound})'.format(i=i+1, bound=bound)) |
| 15 | + |
| 16 | +def expand_template(template: str, |
| 17 | + arg_template: str = 'arg{i}: {Ts}', |
| 18 | + lower: int = 0, |
| 19 | + limit: int = LIMIT) -> None: |
| 20 | + print() |
| 21 | + for i in range(lower, limit): |
| 22 | + tvs = ', '.join('T{i}'.format(i=j+1) for j in range(i)) |
| 23 | + args = ', '.join(arg_template.format(i=j+1, Ts='T{}'.format(j+1)) |
| 24 | + for j in range(i)) |
| 25 | + print('@overload') |
| 26 | + s = template.format(Ts=tvs, argsTs=args) |
| 27 | + s = s.replace('Tuple[]', 'Tuple[()]') |
| 28 | + print(s) |
| 29 | + args_l = [arg_template.format(i=j+1, Ts='Ts') for j in range(limit)] |
| 30 | + args_l.append('*' + (arg_template.format(i='s', Ts='Ts'))) |
| 31 | + args = ', '.join(args_l) |
| 32 | + s = template.format(Ts='Ts, ...', argsTs=args) |
| 33 | + s = s.replace('Callable[[Ts, ...]', 'Callable[...') |
| 34 | + print('@overload') |
| 35 | + print(s) |
| 36 | + |
| 37 | +def main(): |
| 38 | + prelude(LIMIT, BOUND) |
| 39 | + |
| 40 | + # map() |
| 41 | + expand_template('def map(func: Callable[[{Ts}], R], {argsTs}) -> R: ...', |
| 42 | + lower=1) |
| 43 | + # zip() |
| 44 | + expand_template('def zip({argsTs}) -> Tuple[{Ts}]: ...') |
| 45 | + |
| 46 | + # Naomi's examples |
| 47 | + expand_template('def my_zip({argsTs}) -> Iterator[Tuple[{Ts}]]: ...', |
| 48 | + 'arg{i}: Iterable[{Ts}]') |
| 49 | + expand_template('def make_check({argsTs}) -> Callable[[{Ts}], bool]: ...') |
| 50 | + expand_template('def my_map(f: Callable[[{Ts}], R], {argsTs}) -> Iterator[R]: ...', |
| 51 | + 'arg{i}: Iterable[{Ts}]') |
| 52 | + |
| 53 | + |
| 54 | +main() |
0 commit comments