|
2 | 2 |
|
3 | 3 | from dataclasses import dataclass |
4 | 4 | from functools import wraps |
| 5 | +from itertools import chain |
5 | 6 | from typing import Any, Callable, Dict, Tuple |
6 | 7 |
|
7 | 8 |
|
@@ -42,10 +43,24 @@ def factorial(n, accumulator=1): |
42 | 43 | func: Callable[..., Any] |
43 | 44 | args: Tuple[Any, ...] |
44 | 45 | kwargs: Dict[str, Any] |
| 46 | + has_been_tail_called: bool |
45 | 47 |
|
46 | 48 | def __init__(self, func: Callable[..., Any]): |
47 | 49 | """Assigns the ``func`` attribute to the decorated function.""" |
48 | 50 | self.func = func # type: ignore |
| 51 | + self.has_been_tail_called = False |
| 52 | + |
| 53 | + def __repr__(self) -> str: |
| 54 | + class_string: str = type(self).__qualname__ |
| 55 | + func_string: str = repr(self.func) |
| 56 | + object_string: str = f"{class_string}(func={func_string})" |
| 57 | + if self.has_been_tail_called: |
| 58 | + args_string = ', '.join(chain( |
| 59 | + (repr(arg) for arg in self.args), |
| 60 | + (f"{name}={repr(val)}" for name, val in self.kwargs.items()) |
| 61 | + )) |
| 62 | + return f"{object_string}.tail_call({args_string})" |
| 63 | + return object_string |
49 | 64 |
|
50 | 65 | def __call__(self, *args, **kwargs) -> Any: |
51 | 66 | @wraps(self.func) |
@@ -82,4 +97,5 @@ def f(): |
82 | 97 | """ |
83 | 98 | self.args = args |
84 | 99 | self.kwargs = kwargs |
| 100 | + self.has_been_tail_called = True |
85 | 101 | return self |
0 commit comments