Skip to content

Commit e6ce8bb

Browse files
committed
Add custom repr
1 parent 153dc42 commit e6ce8bb

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

tail_recursive/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from dataclasses import dataclass
44
from functools import wraps
5+
from itertools import chain
56
from typing import Any, Callable, Dict, Tuple
67

78

@@ -42,10 +43,24 @@ def factorial(n, accumulator=1):
4243
func: Callable[..., Any]
4344
args: Tuple[Any, ...]
4445
kwargs: Dict[str, Any]
46+
has_been_tail_called: bool
4547

4648
def __init__(self, func: Callable[..., Any]):
4749
"""Assigns the ``func`` attribute to the decorated function."""
4850
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
4964

5065
def __call__(self, *args, **kwargs) -> Any:
5166
@wraps(self.func)
@@ -82,4 +97,5 @@ def f():
8297
"""
8398
self.args = args
8499
self.kwargs = kwargs
100+
self.has_been_tail_called = True
85101
return self

tests.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@
44
from tail_recursive import tail_recursive
55

66

7+
def test__repr__():
8+
9+
def func():
10+
pass
11+
12+
decorated_func = tail_recursive(func)
13+
14+
# Without tail calls.
15+
assert repr(decorated_func) == f"tail_recursive(func={repr(func)})"
16+
17+
# With tail calls.
18+
# Without arguments.
19+
assert repr(
20+
decorated_func.tail_call()
21+
) == f"tail_recursive(func={repr(func)}).tail_call()"
22+
23+
# With arguments.
24+
assert repr(decorated_func.tail_call(
25+
"first_arg", 2, [],
26+
first_kwarg="1", second_kwarg=2, third_kwarg={},
27+
)) == f"tail_recursive(func=" + repr(func) + ").tail_call('first_arg', 2, [], first_kwarg='1', second_kwarg=2, third_kwarg={})"
28+
29+
730
def test_factorial_fails_when_max_recursion_depth_is_reached():
831

932
@tail_recursive

0 commit comments

Comments
 (0)